diff options
-rw-r--r-- | applets/applets.c | 10 | ||||
-rw-r--r-- | include/applets.h | 6 | ||||
-rw-r--r-- | util-linux/mount.c | 80 |
3 files changed, 68 insertions, 28 deletions
diff --git a/applets/applets.c b/applets/applets.c index 5d8b80881..00102daa3 100644 --- a/applets/applets.c +++ b/applets/applets.c | |||
@@ -316,10 +316,10 @@ static void parse_config_file(void) | |||
316 | #endif /* CONFIG_FEATURE_SUID_CONFIG */ | 316 | #endif /* CONFIG_FEATURE_SUID_CONFIG */ |
317 | 317 | ||
318 | #ifdef CONFIG_FEATURE_SUID | 318 | #ifdef CONFIG_FEATURE_SUID |
319 | static void check_suid (struct BB_applet *applet) | 319 | static void check_suid(struct BB_applet *applet) |
320 | { | 320 | { |
321 | uid_t ruid = getuid (); /* real [ug]id */ | 321 | uid_t ruid = getuid(); /* real [ug]id */ |
322 | uid_t rgid = getgid (); | 322 | uid_t rgid = getgid(); |
323 | 323 | ||
324 | #ifdef CONFIG_FEATURE_SUID_CONFIG | 324 | #ifdef CONFIG_FEATURE_SUID_CONFIG |
325 | if (suid_cfg_readable) { | 325 | if (suid_cfg_readable) { |
@@ -334,7 +334,7 @@ static void check_suid (struct BB_applet *applet) | |||
334 | 334 | ||
335 | if (sct->m_uid == ruid) /* same uid */ | 335 | if (sct->m_uid == ruid) /* same uid */ |
336 | m >>= 6; | 336 | m >>= 6; |
337 | else if ((sct->m_gid == rgid) || ingroup (ruid, sct->m_gid)) /* same group / in group */ | 337 | else if ((sct->m_gid == rgid) || ingroup(ruid, sct->m_gid)) /* same group / in group */ |
338 | m >>= 3; | 338 | m >>= 3; |
339 | 339 | ||
340 | if (!(m & S_IXOTH)) /* is x bit not set ? */ | 340 | if (!(m & S_IXOTH)) /* is x bit not set ? */ |
@@ -358,7 +358,7 @@ static void check_suid (struct BB_applet *applet) | |||
358 | 358 | ||
359 | if (!onetime) { | 359 | if (!onetime) { |
360 | onetime = 1; | 360 | onetime = 1; |
361 | fprintf (stderr, "Using fallback suid method\n"); | 361 | fprintf(stderr, "Using fallback suid method\n"); |
362 | } | 362 | } |
363 | #endif | 363 | #endif |
364 | } | 364 | } |
diff --git a/include/applets.h b/include/applets.h index 3b759de20..0c0209676 100644 --- a/include/applets.h +++ b/include/applets.h | |||
@@ -46,6 +46,10 @@ | |||
46 | # define _BB_DIR_USR_SBIN _BB_DIR_SBIN | 46 | # define _BB_DIR_USR_SBIN _BB_DIR_SBIN |
47 | #endif | 47 | #endif |
48 | 48 | ||
49 | // _BB_SUID_ALWAYS: will complain if busybox isn't suid | ||
50 | // and is run by non-root (applet_main() will not be called at all) | ||
51 | // _BB_SUID_NEVER: will drop suid prior to applet_main() | ||
52 | // _BB_SUID_MAYBE: neither of the above | ||
49 | 53 | ||
50 | USE_TEST(APPLET_NOUSAGE([, test, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) | 54 | USE_TEST(APPLET_NOUSAGE([, test, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) |
51 | USE_TEST(APPLET_NOUSAGE([[, test, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) | 55 | USE_TEST(APPLET_NOUSAGE([[, test, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) |
@@ -198,7 +202,7 @@ USE_MKSWAP(APPLET(mkswap, _BB_DIR_SBIN, _BB_SUID_NEVER)) | |||
198 | USE_MKTEMP(APPLET(mktemp, _BB_DIR_BIN, _BB_SUID_NEVER)) | 202 | USE_MKTEMP(APPLET(mktemp, _BB_DIR_BIN, _BB_SUID_NEVER)) |
199 | USE_MODPROBE(APPLET(modprobe, _BB_DIR_SBIN, _BB_SUID_NEVER)) | 203 | USE_MODPROBE(APPLET(modprobe, _BB_DIR_SBIN, _BB_SUID_NEVER)) |
200 | USE_MORE(APPLET(more, _BB_DIR_BIN, _BB_SUID_NEVER)) | 204 | USE_MORE(APPLET(more, _BB_DIR_BIN, _BB_SUID_NEVER)) |
201 | USE_MOUNT(APPLET(mount, _BB_DIR_BIN, _BB_SUID_NEVER)) | 205 | USE_MOUNT(APPLET(mount, _BB_DIR_BIN, USE_DESKTOP(_BB_SUID_MAYBE) SKIP_DESKTOP(_BB_SUID_NEVER))) |
202 | USE_MOUNTPOINT(APPLET(mountpoint, _BB_DIR_BIN, _BB_SUID_NEVER)) | 206 | USE_MOUNTPOINT(APPLET(mountpoint, _BB_DIR_BIN, _BB_SUID_NEVER)) |
203 | USE_MSH(APPLET_NOUSAGE(msh, msh, _BB_DIR_BIN, _BB_SUID_NEVER)) | 207 | USE_MSH(APPLET_NOUSAGE(msh, msh, _BB_DIR_BIN, _BB_SUID_NEVER)) |
204 | USE_MT(APPLET(mt, _BB_DIR_BIN, _BB_SUID_NEVER)) | 208 | USE_MT(APPLET(mt, _BB_DIR_BIN, _BB_SUID_NEVER)) |
diff --git a/util-linux/mount.c b/util-linux/mount.c index 9793b825a..5ced48fea 100644 --- a/util-linux/mount.c +++ b/util-linux/mount.c | |||
@@ -32,8 +32,19 @@ | |||
32 | 32 | ||
33 | 33 | ||
34 | // Not real flags, but we want to be able to check for this. | 34 | // Not real flags, but we want to be able to check for this. |
35 | #define MOUNT_NOAUTO (1<<29) | 35 | enum { |
36 | #define MOUNT_SWAP (1<<30) | 36 | MOUNT_USERS = (1<<28)*ENABLE_DESKTOP, |
37 | MOUNT_NOAUTO = (1<<29), | ||
38 | MOUNT_SWAP = (1<<30), | ||
39 | }; | ||
40 | // TODO: more "user" flag compatibility. | ||
41 | // "user" option (from mount manpage): | ||
42 | // Only the user that mounted a filesystem can unmount it again. | ||
43 | // If any user should be able to unmount, then use users instead of user | ||
44 | // in the fstab line. The owner option is similar to the user option, | ||
45 | // with the restriction that the user must be the owner of the special file. | ||
46 | // This may be useful e.g. for /dev/fd if a login script makes | ||
47 | // the console user owner of this device. | ||
37 | 48 | ||
38 | /* Standard mount options (from -o options or --options), with corresponding | 49 | /* Standard mount options (from -o options or --options), with corresponding |
39 | * flags */ | 50 | * flags */ |
@@ -51,8 +62,10 @@ struct { | |||
51 | USE_FEATURE_MOUNT_FSTAB( | 62 | USE_FEATURE_MOUNT_FSTAB( |
52 | {"defaults", 0}, | 63 | {"defaults", 0}, |
53 | {"quiet", 0}, | 64 | {"quiet", 0}, |
54 | {"noauto",MOUNT_NOAUTO}, | 65 | {"noauto", MOUNT_NOAUTO}, |
55 | {"swap",MOUNT_SWAP}, | 66 | {"swap", MOUNT_SWAP}, |
67 | USE_DESKTOP({"user", MOUNT_USERS},) | ||
68 | USE_DESKTOP({"users", MOUNT_USERS},) | ||
56 | ) | 69 | ) |
57 | 70 | ||
58 | USE_FEATURE_MOUNT_FLAGS( | 71 | USE_FEATURE_MOUNT_FLAGS( |
@@ -106,7 +119,8 @@ static void append_mount_options(char **oldopts, char *newopts) | |||
106 | if (p) len = p - newopts; | 119 | if (p) len = p - newopts; |
107 | p = *oldopts; | 120 | p = *oldopts; |
108 | while (1) { | 121 | while (1) { |
109 | if (!strncmp(p,newopts,len) && (p[len]==',' || p[len]==0)) | 122 | if (!strncmp(p, newopts, len) |
123 | && (p[len]==',' || p[len]==0)) | ||
110 | goto skip; | 124 | goto skip; |
111 | p = strchr(p,','); | 125 | p = strchr(p,','); |
112 | if(!p) break; | 126 | if(!p) break; |
@@ -1422,6 +1436,8 @@ report_error: | |||
1422 | // Parse options, if necessary parse fstab/mtab, and call singlemount for | 1436 | // Parse options, if necessary parse fstab/mtab, and call singlemount for |
1423 | // each directory to be mounted. | 1437 | // each directory to be mounted. |
1424 | 1438 | ||
1439 | const char must_be_root[] = "you must be root"; | ||
1440 | |||
1425 | int mount_main(int argc, char **argv) | 1441 | int mount_main(int argc, char **argv) |
1426 | { | 1442 | { |
1427 | enum { OPT_ALL = 0x10 }; | 1443 | enum { OPT_ALL = 0x10 }; |
@@ -1433,13 +1449,15 @@ int mount_main(int argc, char **argv) | |||
1433 | int i, j, rc = 0; | 1449 | int i, j, rc = 0; |
1434 | unsigned opt; | 1450 | unsigned opt; |
1435 | struct mntent mtpair[2], *mtcur = mtpair; | 1451 | struct mntent mtpair[2], *mtcur = mtpair; |
1452 | SKIP_DESKTOP(const int nonroot = 0;) | ||
1453 | USE_DESKTOP( int nonroot = (getuid() != 0);) | ||
1436 | 1454 | ||
1437 | /* parse long options, like --bind and --move. Note that -o option | 1455 | /* parse long options, like --bind and --move. Note that -o option |
1438 | * and --option are synonymous. Yes, this means --remount,rw works. */ | 1456 | * and --option are synonymous. Yes, this means --remount,rw works. */ |
1439 | 1457 | ||
1440 | for (i = j = 0; i < argc; i++) { | 1458 | for (i = j = 0; i < argc; i++) { |
1441 | if (argv[i][0] == '-' && argv[i][1] == '-') { | 1459 | if (argv[i][0] == '-' && argv[i][1] == '-') { |
1442 | append_mount_options(&cmdopts,argv[i]+2); | 1460 | append_mount_options(&cmdopts, argv[i]+2); |
1443 | } else argv[j++] = argv[i]; | 1461 | } else argv[j++] = argv[i]; |
1444 | } | 1462 | } |
1445 | argv[j] = 0; | 1463 | argv[j] = 0; |
@@ -1470,12 +1488,12 @@ int mount_main(int argc, char **argv) | |||
1470 | if (!(opt & OPT_ALL)) { | 1488 | if (!(opt & OPT_ALL)) { |
1471 | FILE *mountTable = setmntent(bb_path_mtab_file, "r"); | 1489 | FILE *mountTable = setmntent(bb_path_mtab_file, "r"); |
1472 | 1490 | ||
1473 | if (!mountTable) bb_error_msg_and_die("no %s",bb_path_mtab_file); | 1491 | if (!mountTable) bb_error_msg_and_die("no %s", bb_path_mtab_file); |
1474 | 1492 | ||
1475 | while (getmntent_r(mountTable,mtpair,bb_common_bufsiz1, | 1493 | while (getmntent_r(mountTable, mtpair, bb_common_bufsiz1, |
1476 | sizeof(bb_common_bufsiz1))) | 1494 | sizeof(bb_common_bufsiz1))) |
1477 | { | 1495 | { |
1478 | // Don't show rootfs. | 1496 | // Don't show rootfs. FIXME: why?? |
1479 | if (!strcmp(mtpair->mnt_fsname, "rootfs")) continue; | 1497 | if (!strcmp(mtpair->mnt_fsname, "rootfs")) continue; |
1480 | 1498 | ||
1481 | if (!fstype || !strcmp(mtpair->mnt_type, fstype)) | 1499 | if (!fstype || !strcmp(mtpair->mnt_type, fstype)) |
@@ -1493,6 +1511,8 @@ int mount_main(int argc, char **argv) | |||
1493 | // argument when we get it. | 1511 | // argument when we get it. |
1494 | 1512 | ||
1495 | if (argc == 2) { | 1513 | if (argc == 2) { |
1514 | if (nonroot) | ||
1515 | bb_error_msg_and_die(must_be_root); | ||
1496 | mtpair->mnt_fsname = argv[0]; | 1516 | mtpair->mnt_fsname = argv[0]; |
1497 | mtpair->mnt_dir = argv[1]; | 1517 | mtpair->mnt_dir = argv[1]; |
1498 | mtpair->mnt_type = fstype; | 1518 | mtpair->mnt_type = fstype; |
@@ -1502,11 +1522,13 @@ int mount_main(int argc, char **argv) | |||
1502 | } | 1522 | } |
1503 | 1523 | ||
1504 | i = parse_mount_options(cmdopts, 0); | 1524 | i = parse_mount_options(cmdopts, 0); |
1525 | if (nonroot && (i & ~MS_SILENT)) // Non-root users cannot specify flags | ||
1526 | bb_error_msg_and_die(must_be_root); | ||
1505 | 1527 | ||
1506 | // If we have a shared subtree flag, don't worry about fstab or mtab. | 1528 | // If we have a shared subtree flag, don't worry about fstab or mtab. |
1507 | 1529 | ||
1508 | if (ENABLE_FEATURE_MOUNT_FLAGS && | 1530 | if (ENABLE_FEATURE_MOUNT_FLAGS && |
1509 | (i & (MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE ))) | 1531 | (i & (MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE))) |
1510 | { | 1532 | { |
1511 | rc = mount("", argv[0], "", i, ""); | 1533 | rc = mount("", argv[0], "", i, ""); |
1512 | if (rc) bb_perror_msg_and_die("%s", argv[0]); | 1534 | if (rc) bb_perror_msg_and_die("%s", argv[0]); |
@@ -1515,10 +1537,11 @@ int mount_main(int argc, char **argv) | |||
1515 | 1537 | ||
1516 | // Open either fstab or mtab | 1538 | // Open either fstab or mtab |
1517 | 1539 | ||
1518 | if (i & MS_REMOUNT) | 1540 | fstabname = "/etc/fstab"; |
1541 | if (i & MS_REMOUNT) { | ||
1519 | fstabname = bb_path_mtab_file; | 1542 | fstabname = bb_path_mtab_file; |
1520 | else fstabname = "/etc/fstab"; | 1543 | } |
1521 | fstab = setmntent(fstabname,"r"); | 1544 | fstab = setmntent(fstabname, "r"); |
1522 | if (!fstab) | 1545 | if (!fstab) |
1523 | bb_perror_msg_and_die("cannot read %s", fstabname); | 1546 | bb_perror_msg_and_die("cannot read %s", fstabname); |
1524 | 1547 | ||
@@ -1544,11 +1567,17 @@ int mount_main(int argc, char **argv) | |||
1544 | bb_error_msg_and_die("can't find %s in %s", | 1567 | bb_error_msg_and_die("can't find %s in %s", |
1545 | argv[0], fstabname); | 1568 | argv[0], fstabname); |
1546 | 1569 | ||
1570 | mtcur = mtnext; | ||
1571 | if (nonroot) { | ||
1572 | // fstab must have "users" or "user" | ||
1573 | if (!(parse_mount_options(mtcur->mnt_opts, 0) & MOUNT_USERS)) | ||
1574 | bb_error_msg_and_die(must_be_root); | ||
1575 | } | ||
1576 | |||
1547 | // Mount the last thing we found. | 1577 | // Mount the last thing we found. |
1548 | 1578 | ||
1549 | mtcur = mtnext; | ||
1550 | mtcur->mnt_opts = xstrdup(mtcur->mnt_opts); | 1579 | mtcur->mnt_opts = xstrdup(mtcur->mnt_opts); |
1551 | append_mount_options(&(mtcur->mnt_opts),cmdopts); | 1580 | append_mount_options(&(mtcur->mnt_opts), cmdopts); |
1552 | rc = singlemount(mtcur, 0); | 1581 | rc = singlemount(mtcur, 0); |
1553 | free(mtcur->mnt_opts); | 1582 | free(mtcur->mnt_opts); |
1554 | } | 1583 | } |
@@ -1563,10 +1592,10 @@ int mount_main(int argc, char **argv) | |||
1563 | 1592 | ||
1564 | // Is this what we're looking for? | 1593 | // Is this what we're looking for? |
1565 | 1594 | ||
1566 | if (strcmp(argv[0],mtcur->mnt_fsname) && | 1595 | if (strcmp(argv[0], mtcur->mnt_fsname) && |
1567 | strcmp(storage_path,mtcur->mnt_fsname) && | 1596 | strcmp(storage_path, mtcur->mnt_fsname) && |
1568 | strcmp(argv[0],mtcur->mnt_dir) && | 1597 | strcmp(argv[0], mtcur->mnt_dir) && |
1569 | strcmp(storage_path,mtcur->mnt_dir)) continue; | 1598 | strcmp(storage_path, mtcur->mnt_dir)) continue; |
1570 | 1599 | ||
1571 | // Remember this entry. Something later may have overmounted | 1600 | // Remember this entry. Something later may have overmounted |
1572 | // it, and we want the _last_ match. | 1601 | // it, and we want the _last_ match. |
@@ -1576,15 +1605,22 @@ int mount_main(int argc, char **argv) | |||
1576 | // If we're mounting all. | 1605 | // If we're mounting all. |
1577 | 1606 | ||
1578 | } else { | 1607 | } else { |
1579 | |||
1580 | // Do we need to match a filesystem type? | 1608 | // Do we need to match a filesystem type? |
1581 | if (fstype && strcmp(mtcur->mnt_type,fstype)) continue; | 1609 | // TODO: support "-t type1,type2"; "-t notype1,type2" |
1610 | |||
1611 | if (fstype && strcmp(mtcur->mnt_type, fstype)) continue; | ||
1582 | 1612 | ||
1583 | // Skip noauto and swap anyway. | 1613 | // Skip noauto and swap anyway. |
1584 | 1614 | ||
1585 | if (parse_mount_options(mtcur->mnt_opts,0) | 1615 | if (parse_mount_options(mtcur->mnt_opts, 0) |
1586 | & (MOUNT_NOAUTO | MOUNT_SWAP)) continue; | 1616 | & (MOUNT_NOAUTO | MOUNT_SWAP)) continue; |
1587 | 1617 | ||
1618 | // No, mount -a won't mount anything, | ||
1619 | // even user mounts, for mere humans. | ||
1620 | |||
1621 | if (nonroot) | ||
1622 | bb_error_msg_and_die(must_be_root); | ||
1623 | |||
1588 | // Mount this thing. | 1624 | // Mount this thing. |
1589 | 1625 | ||
1590 | if (singlemount(mtcur, 1)) { | 1626 | if (singlemount(mtcur, 1)) { |