aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--applets/applets.c10
-rw-r--r--include/applets.h6
-rw-r--r--util-linux/mount.c80
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
319static void check_suid (struct BB_applet *applet) 319static 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
50USE_TEST(APPLET_NOUSAGE([, test, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) 54USE_TEST(APPLET_NOUSAGE([, test, _BB_DIR_USR_BIN, _BB_SUID_NEVER))
51USE_TEST(APPLET_NOUSAGE([[, test, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) 55USE_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))
198USE_MKTEMP(APPLET(mktemp, _BB_DIR_BIN, _BB_SUID_NEVER)) 202USE_MKTEMP(APPLET(mktemp, _BB_DIR_BIN, _BB_SUID_NEVER))
199USE_MODPROBE(APPLET(modprobe, _BB_DIR_SBIN, _BB_SUID_NEVER)) 203USE_MODPROBE(APPLET(modprobe, _BB_DIR_SBIN, _BB_SUID_NEVER))
200USE_MORE(APPLET(more, _BB_DIR_BIN, _BB_SUID_NEVER)) 204USE_MORE(APPLET(more, _BB_DIR_BIN, _BB_SUID_NEVER))
201USE_MOUNT(APPLET(mount, _BB_DIR_BIN, _BB_SUID_NEVER)) 205USE_MOUNT(APPLET(mount, _BB_DIR_BIN, USE_DESKTOP(_BB_SUID_MAYBE) SKIP_DESKTOP(_BB_SUID_NEVER)))
202USE_MOUNTPOINT(APPLET(mountpoint, _BB_DIR_BIN, _BB_SUID_NEVER)) 206USE_MOUNTPOINT(APPLET(mountpoint, _BB_DIR_BIN, _BB_SUID_NEVER))
203USE_MSH(APPLET_NOUSAGE(msh, msh, _BB_DIR_BIN, _BB_SUID_NEVER)) 207USE_MSH(APPLET_NOUSAGE(msh, msh, _BB_DIR_BIN, _BB_SUID_NEVER))
204USE_MT(APPLET(mt, _BB_DIR_BIN, _BB_SUID_NEVER)) 208USE_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) 35enum {
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
1439const char must_be_root[] = "you must be root";
1440
1425int mount_main(int argc, char **argv) 1441int 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)) {