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)
#endif /* CONFIG_FEATURE_SUID_CONFIG */
#ifdef CONFIG_FEATURE_SUID
-static void check_suid (struct BB_applet *applet)
+static void check_suid(struct BB_applet *applet)
{
- uid_t ruid = getuid (); /* real [ug]id */
- uid_t rgid = getgid ();
+ uid_t ruid = getuid(); /* real [ug]id */
+ uid_t rgid = getgid();
#ifdef CONFIG_FEATURE_SUID_CONFIG
if (suid_cfg_readable) {
@@ -334,7 +334,7 @@ static void check_suid (struct BB_applet *applet)
if (sct->m_uid == ruid) /* same uid */
m >>= 6;
- else if ((sct->m_gid == rgid) || ingroup (ruid, sct->m_gid)) /* same group / in group */
+ else if ((sct->m_gid == rgid) || ingroup(ruid, sct->m_gid)) /* same group / in group */
m >>= 3;
if (!(m & S_IXOTH)) /* is x bit not set ? */
@@ -358,7 +358,7 @@ static void check_suid (struct BB_applet *applet)
if (!onetime) {
onetime = 1;
- fprintf (stderr, "Using fallback suid method\n");
+ fprintf(stderr, "Using fallback suid method\n");
}
#endif
}
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 @@
# define _BB_DIR_USR_SBIN _BB_DIR_SBIN
#endif
+// _BB_SUID_ALWAYS: will complain if busybox isn't suid
+// and is run by non-root (applet_main() will not be called at all)
+// _BB_SUID_NEVER: will drop suid prior to applet_main()
+// _BB_SUID_MAYBE: neither of the above
USE_TEST(APPLET_NOUSAGE([, test, _BB_DIR_USR_BIN, _BB_SUID_NEVER))
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))
USE_MKTEMP(APPLET(mktemp, _BB_DIR_BIN, _BB_SUID_NEVER))
USE_MODPROBE(APPLET(modprobe, _BB_DIR_SBIN, _BB_SUID_NEVER))
USE_MORE(APPLET(more, _BB_DIR_BIN, _BB_SUID_NEVER))
-USE_MOUNT(APPLET(mount, _BB_DIR_BIN, _BB_SUID_NEVER))
+USE_MOUNT(APPLET(mount, _BB_DIR_BIN, USE_DESKTOP(_BB_SUID_MAYBE) SKIP_DESKTOP(_BB_SUID_NEVER)))
USE_MOUNTPOINT(APPLET(mountpoint, _BB_DIR_BIN, _BB_SUID_NEVER))
USE_MSH(APPLET_NOUSAGE(msh, msh, _BB_DIR_BIN, _BB_SUID_NEVER))
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 @@
// Not real flags, but we want to be able to check for this.
-#define MOUNT_NOAUTO (1<<29)
-#define MOUNT_SWAP (1<<30)
+enum {
+ MOUNT_USERS = (1<<28)*ENABLE_DESKTOP,
+ MOUNT_NOAUTO = (1<<29),
+ MOUNT_SWAP = (1<<30),
+};
+// TODO: more "user" flag compatibility.
+// "user" option (from mount manpage):
+// Only the user that mounted a filesystem can unmount it again.
+// If any user should be able to unmount, then use users instead of user
+// in the fstab line. The owner option is similar to the user option,
+// with the restriction that the user must be the owner of the special file.
+// This may be useful e.g. for /dev/fd if a login script makes
+// the console user owner of this device.
/* Standard mount options (from -o options or --options), with corresponding
* flags */
@@ -51,8 +62,10 @@ struct {
USE_FEATURE_MOUNT_FSTAB(
{"defaults", 0},
{"quiet", 0},
- {"noauto",MOUNT_NOAUTO},
- {"swap",MOUNT_SWAP},
+ {"noauto", MOUNT_NOAUTO},
+ {"swap", MOUNT_SWAP},
+ USE_DESKTOP({"user", MOUNT_USERS},)
+ USE_DESKTOP({"users", MOUNT_USERS},)
)
USE_FEATURE_MOUNT_FLAGS(
@@ -106,7 +119,8 @@ static void append_mount_options(char **oldopts, char *newopts)
if (p) len = p - newopts;
p = *oldopts;
while (1) {
- if (!strncmp(p,newopts,len) && (p[len]==',' || p[len]==0))
+ if (!strncmp(p, newopts, len)
+ && (p[len]==',' || p[len]==0))
goto skip;
p = strchr(p,',');
if(!p) break;
@@ -1422,6 +1436,8 @@ report_error:
// Parse options, if necessary parse fstab/mtab, and call singlemount for
// each directory to be mounted.
+const char must_be_root[] = "you must be root";
+
int mount_main(int argc, char **argv)
{
enum { OPT_ALL = 0x10 };
@@ -1433,13 +1449,15 @@ int mount_main(int argc, char **argv)
int i, j, rc = 0;
unsigned opt;
struct mntent mtpair[2], *mtcur = mtpair;
+ SKIP_DESKTOP(const int nonroot = 0;)
+ USE_DESKTOP( int nonroot = (getuid() != 0);)
/* parse long options, like --bind and --move. Note that -o option
* and --option are synonymous. Yes, this means --remount,rw works. */
for (i = j = 0; i < argc; i++) {
if (argv[i][0] == '-' && argv[i][1] == '-') {
- append_mount_options(&cmdopts,argv[i]+2);
+ append_mount_options(&cmdopts, argv[i]+2);
} else argv[j++] = argv[i];
}
argv[j] = 0;
@@ -1470,12 +1488,12 @@ int mount_main(int argc, char **argv)
if (!(opt & OPT_ALL)) {
FILE *mountTable = setmntent(bb_path_mtab_file, "r");
- if (!mountTable) bb_error_msg_and_die("no %s",bb_path_mtab_file);
+ if (!mountTable) bb_error_msg_and_die("no %s", bb_path_mtab_file);
- while (getmntent_r(mountTable,mtpair,bb_common_bufsiz1,
+ while (getmntent_r(mountTable, mtpair, bb_common_bufsiz1,
sizeof(bb_common_bufsiz1)))
{
- // Don't show rootfs.
+ // Don't show rootfs. FIXME: why??
if (!strcmp(mtpair->mnt_fsname, "rootfs")) continue;
if (!fstype || !strcmp(mtpair->mnt_type, fstype))
@@ -1493,6 +1511,8 @@ int mount_main(int argc, char **argv)
// argument when we get it.
if (argc == 2) {
+ if (nonroot)
+ bb_error_msg_and_die(must_be_root);
mtpair->mnt_fsname = argv[0];
mtpair->mnt_dir = argv[1];
mtpair->mnt_type = fstype;
@@ -1502,11 +1522,13 @@ int mount_main(int argc, char **argv)
}
i = parse_mount_options(cmdopts, 0);
+ if (nonroot && (i & ~MS_SILENT)) // Non-root users cannot specify flags
+ bb_error_msg_and_die(must_be_root);
// If we have a shared subtree flag, don't worry about fstab or mtab.
if (ENABLE_FEATURE_MOUNT_FLAGS &&
- (i & (MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE )))
+ (i & (MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE)))
{
rc = mount("", argv[0], "", i, "");
if (rc) bb_perror_msg_and_die("%s", argv[0]);
@@ -1515,10 +1537,11 @@ int mount_main(int argc, char **argv)
// Open either fstab or mtab
- if (i & MS_REMOUNT)
+ fstabname = "/etc/fstab";
+ if (i & MS_REMOUNT) {
fstabname = bb_path_mtab_file;
- else fstabname = "/etc/fstab";
- fstab = setmntent(fstabname,"r");
+ }
+ fstab = setmntent(fstabname, "r");
if (!fstab)
bb_perror_msg_and_die("cannot read %s", fstabname);
@@ -1544,11 +1567,17 @@ int mount_main(int argc, char **argv)
bb_error_msg_and_die("can't find %s in %s",
argv[0], fstabname);
+ mtcur = mtnext;
+ if (nonroot) {
+ // fstab must have "users" or "user"
+ if (!(parse_mount_options(mtcur->mnt_opts, 0) & MOUNT_USERS))
+ bb_error_msg_and_die(must_be_root);
+ }
+
// Mount the last thing we found.
- mtcur = mtnext;
mtcur->mnt_opts = xstrdup(mtcur->mnt_opts);
- append_mount_options(&(mtcur->mnt_opts),cmdopts);
+ append_mount_options(&(mtcur->mnt_opts), cmdopts);
rc = singlemount(mtcur, 0);
free(mtcur->mnt_opts);
}
@@ -1563,10 +1592,10 @@ int mount_main(int argc, char **argv)
// Is this what we're looking for?
- if (strcmp(argv[0],mtcur->mnt_fsname) &&
- strcmp(storage_path,mtcur->mnt_fsname) &&
- strcmp(argv[0],mtcur->mnt_dir) &&
- strcmp(storage_path,mtcur->mnt_dir)) continue;
+ if (strcmp(argv[0], mtcur->mnt_fsname) &&
+ strcmp(storage_path, mtcur->mnt_fsname) &&
+ strcmp(argv[0], mtcur->mnt_dir) &&
+ strcmp(storage_path, mtcur->mnt_dir)) continue;
// Remember this entry. Something later may have overmounted
// it, and we want the _last_ match.
@@ -1576,15 +1605,22 @@ int mount_main(int argc, char **argv)
// If we're mounting all.
} else {
-
// Do we need to match a filesystem type?
- if (fstype && strcmp(mtcur->mnt_type,fstype)) continue;
+ // TODO: support "-t type1,type2"; "-t notype1,type2"
+
+ if (fstype && strcmp(mtcur->mnt_type, fstype)) continue;
// Skip noauto and swap anyway.
- if (parse_mount_options(mtcur->mnt_opts,0)
+ if (parse_mount_options(mtcur->mnt_opts, 0)
& (MOUNT_NOAUTO | MOUNT_SWAP)) continue;
+ // No, mount -a won't mount anything,
+ // even user mounts, for mere humans.
+
+ if (nonroot)
+ bb_error_msg_and_die(must_be_root);
+
// Mount this thing.
if (singlemount(mtcur, 1)) {