diff options
-rw-r--r-- | include/usage.h | 3 | ||||
-rw-r--r-- | util-linux/mount.c | 73 |
2 files changed, 49 insertions, 27 deletions
diff --git a/include/usage.h b/include/usage.h index 0f6378e06..c6006aa65 100644 --- a/include/usage.h +++ b/include/usage.h | |||
@@ -2901,6 +2901,9 @@ | |||
2901 | "\n -f Dry run" \ | 2901 | "\n -f Dry run" \ |
2902 | ) \ | 2902 | ) \ |
2903 | ) \ | 2903 | ) \ |
2904 | IF_FEATURE_MOUNT_HELPERS( \ | ||
2905 | "\n -i Don't run mount helper" \ | ||
2906 | ) \ | ||
2904 | IF_FEATURE_MTAB_SUPPORT( \ | 2907 | IF_FEATURE_MTAB_SUPPORT( \ |
2905 | "\n -n Don't update /etc/mtab" \ | 2908 | "\n -n Don't update /etc/mtab" \ |
2906 | ) \ | 2909 | ) \ |
diff --git a/util-linux/mount.c b/util-linux/mount.c index ab249642b..72dabd840 100644 --- a/util-linux/mount.c +++ b/util-linux/mount.c | |||
@@ -79,15 +79,21 @@ enum { | |||
79 | }; | 79 | }; |
80 | 80 | ||
81 | #if ENABLE_FEATURE_MTAB_SUPPORT | 81 | #if ENABLE_FEATURE_MTAB_SUPPORT |
82 | #define useMtab (!(option_mask32 & OPT_n)) | 82 | #define USE_MTAB (!(option_mask32 & OPT_n)) |
83 | #else | 83 | #else |
84 | #define useMtab 0 | 84 | #define USE_MTAB 0 |
85 | #endif | 85 | #endif |
86 | 86 | ||
87 | #if ENABLE_FEATURE_MOUNT_FAKE | 87 | #if ENABLE_FEATURE_MOUNT_FAKE |
88 | #define fakeIt (option_mask32 & OPT_f) | 88 | #define FAKE_IT (option_mask32 & OPT_f) |
89 | #else | 89 | #else |
90 | #define fakeIt 0 | 90 | #define FAKE_IT 0 |
91 | #endif | ||
92 | |||
93 | #if ENABLE_FEATURE_MOUNT_HELPERS | ||
94 | #define HELPERS_ALLOWED (!(option_mask32 & OPT_i)) | ||
95 | #else | ||
96 | #define HELPERS_ALLOWED 0 | ||
91 | #endif | 97 | #endif |
92 | 98 | ||
93 | 99 | ||
@@ -360,7 +366,7 @@ static llist_t *get_block_backed_filesystems(void) | |||
360 | "/proc/filesystems", | 366 | "/proc/filesystems", |
361 | }; | 367 | }; |
362 | char *fs, *buf; | 368 | char *fs, *buf; |
363 | llist_t *list = 0; | 369 | llist_t *list = NULL; |
364 | int i; | 370 | int i; |
365 | FILE *f; | 371 | FILE *f; |
366 | 372 | ||
@@ -369,10 +375,11 @@ static llist_t *get_block_backed_filesystems(void) | |||
369 | if (!f) continue; | 375 | if (!f) continue; |
370 | 376 | ||
371 | while ((buf = xmalloc_fgetline(f)) != NULL) { | 377 | while ((buf = xmalloc_fgetline(f)) != NULL) { |
372 | if (!strncmp(buf, "nodev", 5) && isspace(buf[5])) | 378 | if (strncmp(buf, "nodev", 5) == 0 && isspace(buf[5])) |
373 | continue; | 379 | continue; |
374 | fs = skip_whitespace(buf); | 380 | fs = skip_whitespace(buf); |
375 | if (*fs=='#' || *fs=='*' || !*fs) continue; | 381 | if (*fs == '#' || *fs == '*' || !*fs) |
382 | continue; | ||
376 | 383 | ||
377 | llist_add_to_end(&list, xstrdup(fs)); | 384 | llist_add_to_end(&list, xstrdup(fs)); |
378 | free(buf); | 385 | free(buf); |
@@ -398,7 +405,7 @@ static int mount_it_now(struct mntent *mp, long vfsflags, char *filteropts) | |||
398 | { | 405 | { |
399 | int rc = 0; | 406 | int rc = 0; |
400 | 407 | ||
401 | if (fakeIt) { | 408 | if (FAKE_IT) { |
402 | if (verbose >= 2) | 409 | if (verbose >= 2) |
403 | bb_error_msg("would do mount('%s','%s','%s',0x%08lx,'%s')", | 410 | bb_error_msg("would do mount('%s','%s','%s',0x%08lx,'%s')", |
404 | mp->mnt_fsname, mp->mnt_dir, mp->mnt_type, | 411 | mp->mnt_fsname, mp->mnt_dir, mp->mnt_type, |
@@ -414,11 +421,15 @@ static int mount_it_now(struct mntent *mp, long vfsflags, char *filteropts) | |||
414 | 421 | ||
415 | // If mount failed, try | 422 | // If mount failed, try |
416 | // helper program mount.<mnt_type> | 423 | // helper program mount.<mnt_type> |
417 | if (ENABLE_FEATURE_MOUNT_HELPERS && rc) { | 424 | if (HELPERS_ALLOWED && rc) { |
418 | char *args[6]; | 425 | char *args[8]; |
419 | int errno_save = errno; | 426 | int errno_save = errno; |
420 | args[0] = xasprintf("mount.%s", mp->mnt_type); | 427 | args[0] = xasprintf("mount.%s", mp->mnt_type); |
421 | rc = 1; | 428 | rc = 1; |
429 | if (FAKE_IT) | ||
430 | args[rc++] = (char *)"-f"; | ||
431 | if (ENABLE_FEATURE_MTAB_SUPPORT && !USE_MTAB) | ||
432 | args[rc++] = (char *)"-n"; | ||
422 | args[rc++] = mp->mnt_fsname; | 433 | args[rc++] = mp->mnt_fsname; |
423 | args[rc++] = mp->mnt_dir; | 434 | args[rc++] = mp->mnt_dir; |
424 | if (filteropts) { | 435 | if (filteropts) { |
@@ -449,7 +460,7 @@ static int mount_it_now(struct mntent *mp, long vfsflags, char *filteropts) | |||
449 | // If the mount was successful, and we're maintaining an old-style | 460 | // If the mount was successful, and we're maintaining an old-style |
450 | // mtab file by hand, add the new entry to it now. | 461 | // mtab file by hand, add the new entry to it now. |
451 | mtab: | 462 | mtab: |
452 | if (useMtab && !rc && !(vfsflags & MS_REMOUNT)) { | 463 | if (USE_MTAB && !rc && !(vfsflags & MS_REMOUNT)) { |
453 | char *fsname; | 464 | char *fsname; |
454 | FILE *mountTable = setmntent(bb_path_mtab_file, "a+"); | 465 | FILE *mountTable = setmntent(bb_path_mtab_file, "a+"); |
455 | const char *option_str = mount_option_str; | 466 | const char *option_str = mount_option_str; |
@@ -1570,8 +1581,8 @@ static int singlemount(struct mntent *mp, int ignore_busy) | |||
1570 | { | 1581 | { |
1571 | int rc = -1; | 1582 | int rc = -1; |
1572 | long vfsflags; | 1583 | long vfsflags; |
1573 | char *loopFile = 0, *filteropts = 0; | 1584 | char *loopFile = NULL, *filteropts = NULL; |
1574 | llist_t *fl = 0; | 1585 | llist_t *fl = NULL; |
1575 | struct stat st; | 1586 | struct stat st; |
1576 | 1587 | ||
1577 | vfsflags = parse_mount_options(mp->mnt_opts, &filteropts); | 1588 | vfsflags = parse_mount_options(mp->mnt_opts, &filteropts); |
@@ -1581,21 +1592,28 @@ static int singlemount(struct mntent *mp, int ignore_busy) | |||
1581 | mp->mnt_type = NULL; | 1592 | mp->mnt_type = NULL; |
1582 | 1593 | ||
1583 | // Might this be a virtual filesystem? | 1594 | // Might this be a virtual filesystem? |
1584 | if (ENABLE_FEATURE_MOUNT_HELPERS | 1595 | if (ENABLE_FEATURE_MOUNT_HELPERS && strchr(mp->mnt_fsname, '#')) { |
1585 | && (strchr(mp->mnt_fsname, '#')) | 1596 | char *args[35]; |
1586 | ) { | 1597 | char *s; |
1587 | char *s, *p, *args[35]; | 1598 | int n; |
1588 | int n = 0; | 1599 | // fsname: "cmd#arg1#arg2..." |
1589 | // FIXME: does it allow execution of arbitrary commands?! | 1600 | // WARNING: allows execution of arbitrary commands! |
1590 | // What args[0] can end up with? | 1601 | // Try "mount 'sh#-c#sh' bogus_dir". |
1591 | for (s = p = mp->mnt_fsname; *s && n < 35-3; ++s) { | 1602 | // It is safe ONLY because non-root |
1592 | if (s[0] == '#' && s[1] != '#') { | 1603 | // cannot use two-argument mount command |
1593 | *s = '\0'; | 1604 | // and using one-argument "mount 'sh#-c#sh'" doesn't work: |
1594 | args[n++] = p; | 1605 | // "mount: can't find sh#-c#sh in /etc/fstab" |
1595 | p = s + 1; | 1606 | // (if /etc/fstab has it, it's ok: root sets up /etc/fstab). |
1607 | |||
1608 | s = mp->mnt_fsname; | ||
1609 | n = 0; | ||
1610 | args[n++] = s; | ||
1611 | while (*s && n < 35 - 2) { | ||
1612 | if (*s++ == '#' && *s != '#') { | ||
1613 | s[-1] = '\0'; | ||
1614 | args[n++] = s; | ||
1596 | } | 1615 | } |
1597 | } | 1616 | } |
1598 | args[n++] = p; | ||
1599 | args[n++] = mp->mnt_dir; | 1617 | args[n++] = mp->mnt_dir; |
1600 | args[n] = NULL; | 1618 | args[n] = NULL; |
1601 | rc = wait4pid(xspawn(args)); | 1619 | rc = wait4pid(xspawn(args)); |
@@ -1704,7 +1722,8 @@ static int singlemount(struct mntent *mp, int ignore_busy) | |||
1704 | for (fl = fslist; fl; fl = fl->link) { | 1722 | for (fl = fslist; fl; fl = fl->link) { |
1705 | mp->mnt_type = fl->data; | 1723 | mp->mnt_type = fl->data; |
1706 | rc = mount_it_now(mp, vfsflags, filteropts); | 1724 | rc = mount_it_now(mp, vfsflags, filteropts); |
1707 | if (!rc) break; | 1725 | if (!rc) |
1726 | break; | ||
1708 | } | 1727 | } |
1709 | } | 1728 | } |
1710 | 1729 | ||