diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2021-10-08 02:16:41 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2021-10-08 02:20:10 +0200 |
commit | cf4dc4a09d2a7516e00c276396da85e1088a0ddf (patch) | |
tree | 46d0b4717e89b20a470147be524472cad7ffeb4c | |
parent | c28313bb176639e1e4b11a63f6452baebf69f28e (diff) | |
download | busybox-w32-cf4dc4a09d2a7516e00c276396da85e1088a0ddf.tar.gz busybox-w32-cf4dc4a09d2a7516e00c276396da85e1088a0ddf.tar.bz2 busybox-w32-cf4dc4a09d2a7516e00c276396da85e1088a0ddf.zip |
mount: "mount -o rw ...." should not fall back to RO mount
The reported case was an attempt to remount,rw a CD-ROM:
mount -o remount,rw /mnt/sr0
which "succeeded" by falling back to RO:
mount("/dev/sr0", "/mnt/sr0", 0x412862, MS_REMOUNT|MS_SILENT|MS_RELATIME, "nojoliet,check=s,map=n,blocksize"...) = -1 EROFS (Read-only file system)
...
mount("/dev/sr0", "/mnt/sr0", 0x412862, MS_RDONLY|MS_REMOUNT|MS_SILENT|MS_RELATIME, "nojoliet,check=s,map=n,blocksize"...) = 0
Clearly, not what was intended!
function old new delta
parse_mount_options 241 267 +26
mount_main 1198 1211 +13
singlemount 1301 1313 +12
inetd_main 1919 1911 -8
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 3/1 up/down: 51/-8) Total: 43 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | util-linux/mount.c | 21 |
1 files changed, 13 insertions, 8 deletions
diff --git a/util-linux/mount.c b/util-linux/mount.c index 44afdbcff..4e65b6b46 100644 --- a/util-linux/mount.c +++ b/util-linux/mount.c | |||
@@ -589,7 +589,7 @@ static void append_mount_options(char **oldopts, const char *newopts) | |||
589 | 589 | ||
590 | // Use the mount_options list to parse options into flags. | 590 | // Use the mount_options list to parse options into flags. |
591 | // Also update list of unrecognized options if unrecognized != NULL | 591 | // Also update list of unrecognized options if unrecognized != NULL |
592 | static unsigned long parse_mount_options(char *options, char **unrecognized) | 592 | static unsigned long parse_mount_options(char *options, char **unrecognized, uint32_t *opt) |
593 | { | 593 | { |
594 | unsigned long flags = MS_SILENT; | 594 | unsigned long flags = MS_SILENT; |
595 | 595 | ||
@@ -617,6 +617,11 @@ static unsigned long parse_mount_options(char *options, char **unrecognized) | |||
617 | flags &= fl; | 617 | flags &= fl; |
618 | else | 618 | else |
619 | flags |= fl; | 619 | flags |= fl; |
620 | /* If we see "-o rw" on command line, it's the same as -w: | ||
621 | * "do not try to fall back to RO mounts" | ||
622 | */ | ||
623 | if (fl == ~MS_RDONLY && opt) | ||
624 | (*opt) |= OPT_w; | ||
620 | goto found; | 625 | goto found; |
621 | } | 626 | } |
622 | option_str += opt_len + 1; | 627 | option_str += opt_len + 1; |
@@ -1973,7 +1978,7 @@ static int singlemount(struct mntent *mp, int ignore_busy) | |||
1973 | 1978 | ||
1974 | errno = 0; | 1979 | errno = 0; |
1975 | 1980 | ||
1976 | vfsflags = parse_mount_options(mp->mnt_opts, &filteropts); | 1981 | vfsflags = parse_mount_options(mp->mnt_opts, &filteropts, NULL); |
1977 | 1982 | ||
1978 | // Treat fstype "auto" as unspecified | 1983 | // Treat fstype "auto" as unspecified |
1979 | if (mp->mnt_type && strcmp(mp->mnt_type, "auto") == 0) | 1984 | if (mp->mnt_type && strcmp(mp->mnt_type, "auto") == 0) |
@@ -2047,7 +2052,7 @@ static int singlemount(struct mntent *mp, int ignore_busy) | |||
2047 | len, share, | 2052 | len, share, |
2048 | share + len + 1 /* "dir1/dir2" */ | 2053 | share + len + 1 /* "dir1/dir2" */ |
2049 | ); | 2054 | ); |
2050 | parse_mount_options(unc, &filteropts); | 2055 | parse_mount_options(unc, &filteropts, NULL); |
2051 | if (ENABLE_FEATURE_CLEAN_UP) free(unc); | 2056 | if (ENABLE_FEATURE_CLEAN_UP) free(unc); |
2052 | } | 2057 | } |
2053 | 2058 | ||
@@ -2073,7 +2078,7 @@ static int singlemount(struct mntent *mp, int ignore_busy) | |||
2073 | // (instead of _numeric_ iface_id) with glibc. | 2078 | // (instead of _numeric_ iface_id) with glibc. |
2074 | // This probably should be fixed in glibc, not here. | 2079 | // This probably should be fixed in glibc, not here. |
2075 | // The workaround is to manually specify correct "ip=ADDR%n" option. | 2080 | // The workaround is to manually specify correct "ip=ADDR%n" option. |
2076 | parse_mount_options(ip, &filteropts); | 2081 | parse_mount_options(ip, &filteropts, NULL); |
2077 | if (ENABLE_FEATURE_CLEAN_UP) free(ip); | 2082 | if (ENABLE_FEATURE_CLEAN_UP) free(ip); |
2078 | } | 2083 | } |
2079 | 2084 | ||
@@ -2355,7 +2360,7 @@ int mount_main(int argc UNUSED_PARAM, char **argv) | |||
2355 | // Past this point, we are handling either "mount -a [opts]" | 2360 | // Past this point, we are handling either "mount -a [opts]" |
2356 | // or "mount [opts] single_param" | 2361 | // or "mount [opts] single_param" |
2357 | 2362 | ||
2358 | cmdopt_flags = parse_mount_options(cmdopts, NULL); | 2363 | cmdopt_flags = parse_mount_options(cmdopts, NULL, &option_mask32); |
2359 | if (nonroot && (cmdopt_flags & ~MS_SILENT)) // Non-root users cannot specify flags | 2364 | if (nonroot && (cmdopt_flags & ~MS_SILENT)) // Non-root users cannot specify flags |
2360 | bb_simple_error_msg_and_die(bb_msg_you_must_be_root); | 2365 | bb_simple_error_msg_and_die(bb_msg_you_must_be_root); |
2361 | 2366 | ||
@@ -2429,7 +2434,7 @@ int mount_main(int argc UNUSED_PARAM, char **argv) | |||
2429 | continue; | 2434 | continue; |
2430 | 2435 | ||
2431 | // Skip noauto and swap anyway | 2436 | // Skip noauto and swap anyway |
2432 | if ((parse_mount_options(mtcur->mnt_opts, NULL) & (MOUNT_NOAUTO | MOUNT_SWAP)) | 2437 | if ((parse_mount_options(mtcur->mnt_opts, NULL, NULL) & (MOUNT_NOAUTO | MOUNT_SWAP)) |
2433 | // swap is bogus "fstype", parse_mount_options can't check fstypes | 2438 | // swap is bogus "fstype", parse_mount_options can't check fstypes |
2434 | || strcasecmp(mtcur->mnt_type, "swap") == 0 | 2439 | || strcasecmp(mtcur->mnt_type, "swap") == 0 |
2435 | ) { | 2440 | ) { |
@@ -2490,7 +2495,7 @@ int mount_main(int argc UNUSED_PARAM, char **argv) | |||
2490 | // exit_group(32) = ? | 2495 | // exit_group(32) = ? |
2491 | #if 0 | 2496 | #if 0 |
2492 | // In case we want to simply skip swap partitions: | 2497 | // In case we want to simply skip swap partitions: |
2493 | l = parse_mount_options(mtcur->mnt_opts, NULL); | 2498 | l = parse_mount_options(mtcur->mnt_opts, NULL, NULL); |
2494 | if ((l & MOUNT_SWAP) | 2499 | if ((l & MOUNT_SWAP) |
2495 | // swap is bogus "fstype", parse_mount_options can't check fstypes | 2500 | // swap is bogus "fstype", parse_mount_options can't check fstypes |
2496 | || strcasecmp(mtcur->mnt_type, "swap") == 0 | 2501 | || strcasecmp(mtcur->mnt_type, "swap") == 0 |
@@ -2500,7 +2505,7 @@ int mount_main(int argc UNUSED_PARAM, char **argv) | |||
2500 | #endif | 2505 | #endif |
2501 | if (nonroot) { | 2506 | if (nonroot) { |
2502 | // fstab must have "users" or "user" | 2507 | // fstab must have "users" or "user" |
2503 | l = parse_mount_options(mtcur->mnt_opts, NULL); | 2508 | l = parse_mount_options(mtcur->mnt_opts, NULL, NULL); |
2504 | if (!(l & MOUNT_USERS)) | 2509 | if (!(l & MOUNT_USERS)) |
2505 | bb_simple_error_msg_and_die(bb_msg_you_must_be_root); | 2510 | bb_simple_error_msg_and_die(bb_msg_you_must_be_root); |
2506 | } | 2511 | } |