mount: plug a hole where FEATURE_MOUNT_HELPERS could allow execution

of arbitrary command.

function                                             old     new   delta
mount_it_now                                         266     309     +43
This commit is contained in:
Denis Vlasenko 2008-03-17 08:46:43 +00:00
parent afc4113ed7
commit a4522c5a66

View File

@ -56,9 +56,9 @@ static struct mntent *getmntent_r(FILE* stream, struct mntent* result, char* buf
// Not real flags, but we want to be able to check for this. // Not real flags, but we want to be able to check for this.
enum { enum {
MOUNT_USERS = (1<<28)*ENABLE_DESKTOP, MOUNT_USERS = (1 << 28) * ENABLE_DESKTOP,
MOUNT_NOAUTO = (1<<29), MOUNT_NOAUTO = (1 << 29),
MOUNT_SWAP = (1<<30), MOUNT_SWAP = (1 << 30),
}; };
@ -238,8 +238,7 @@ static int verbose_mount(const char *source, const char *target,
errno = 0; errno = 0;
rc = mount(source, target, filesystemtype, mountflags, data); rc = mount(source, target, filesystemtype, mountflags, data);
if (verbose >= 2) if (verbose >= 2)
bb_perror_msg("would do mount('%s','%s','%s',0x%08lx,'%s'):%d" bb_perror_msg("mount('%s','%s','%s',0x%08lx,'%s'):%d",
+ (sizeof("would do ")-1),
source, target, filesystemtype, source, target, filesystemtype,
mountflags, (char*)data, rc); mountflags, (char*)data, rc);
return rc; return rc;
@ -407,7 +406,7 @@ static int mount_it_now(struct mntent *mp, long vfsflags, char *filteropts)
if (ENABLE_FEATURE_MOUNT_HELPERS && rc) { if (ENABLE_FEATURE_MOUNT_HELPERS && rc) {
char *args[6]; char *args[6];
int errno_save = errno; int errno_save = errno;
args[0] = mp->mnt_type; args[0] = xasprintf("mount.%s", mp->mnt_type);
rc = 1; rc = 1;
if (filteropts) { if (filteropts) {
args[rc++] = (char *)"-o"; args[rc++] = (char *)"-o";
@ -417,6 +416,7 @@ static int mount_it_now(struct mntent *mp, long vfsflags, char *filteropts)
args[rc++] = mp->mnt_dir; args[rc++] = mp->mnt_dir;
args[rc] = NULL; args[rc] = NULL;
rc = wait4pid(spawn(args)); rc = wait4pid(spawn(args));
free(args[0]);
if (!rc) if (!rc)
break; break;
errno = errno_save; errno = errno_save;
@ -1556,8 +1556,8 @@ static int singlemount(struct mntent *mp, int ignore_busy)
// Treat fstype "auto" as unspecified. // Treat fstype "auto" as unspecified.
if (mp->mnt_type && strcmp(mp->mnt_type,"auto") == 0) if (mp->mnt_type && strcmp(mp->mnt_type, "auto") == 0)
mp->mnt_type = 0; mp->mnt_type = NULL;
// Might this be a virtual filesystem? // Might this be a virtual filesystem?
@ -1566,6 +1566,8 @@ static int singlemount(struct mntent *mp, int ignore_busy)
) { ) {
char *s, *p, *args[35]; char *s, *p, *args[35];
int n = 0; int n = 0;
// FIXME: does it allow execution of arbitrary commands?!
// What args[0] can end up with?
for (s = p = mp->mnt_fsname; *s && n < 35-3; ++s) { for (s = p = mp->mnt_fsname; *s && n < 35-3; ++s) {
if (s[0] == '#' && s[1] != '#') { if (s[0] == '#' && s[1] != '#') {
*s = '\0'; *s = '\0';
@ -1583,9 +1585,9 @@ static int singlemount(struct mntent *mp, int ignore_busy)
// Might this be an CIFS filesystem? // Might this be an CIFS filesystem?
if (ENABLE_FEATURE_MOUNT_CIFS if (ENABLE_FEATURE_MOUNT_CIFS
&& (!mp->mnt_type || strcmp(mp->mnt_type,"cifs") == 0) && (!mp->mnt_type || strcmp(mp->mnt_type, "cifs") == 0)
&& (mp->mnt_fsname[0]=='/' || mp->mnt_fsname[0]=='\\') && (mp->mnt_fsname[0] == '/' || mp->mnt_fsname[0] == '\\')
&& mp->mnt_fsname[0]==mp->mnt_fsname[1] && mp->mnt_fsname[0] == mp->mnt_fsname[1]
) { ) {
len_and_sockaddr *lsa; len_and_sockaddr *lsa;
char *ip, *dotted; char *ip, *dotted;
@ -1725,7 +1727,9 @@ int mount_main(int argc, char **argv)
{ {
enum { OPT_ALL = 0x10 }; enum { OPT_ALL = 0x10 };
char *cmdopts = xstrdup(""), *fstype=0, *storage_path=0; char *cmdopts = xstrdup("");
char *fstype = NULL;
char *storage_path = NULL;
char *opt_o; char *opt_o;
const char *fstabname; const char *fstabname;
FILE *fstab; FILE *fstab;
@ -1744,7 +1748,7 @@ int mount_main(int argc, char **argv)
append_mount_options(&cmdopts, argv[i]+2); append_mount_options(&cmdopts, argv[i]+2);
} else argv[j++] = argv[i]; } else argv[j++] = argv[i];
} }
argv[j] = 0; argv[j] = NULL;
argc = j; argc = j;
// Parse remaining options // Parse remaining options
@ -1895,12 +1899,13 @@ int mount_main(int argc, char **argv)
} else { } else {
// Do we need to match a filesystem type? // Do we need to match a filesystem type?
if (fstype && match_fstype(mtcur, fstype)) continue; if (fstype && match_fstype(mtcur, fstype))
continue;
// Skip noauto and swap anyway. // 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))
& (MOUNT_NOAUTO | MOUNT_SWAP)) continue; continue;
// No, mount -a won't mount anything, // No, mount -a won't mount anything,
// even user mounts, for mere humans. // even user mounts, for mere humans.
@ -1909,9 +1914,8 @@ int mount_main(int argc, char **argv)
bb_error_msg_and_die(must_be_root); bb_error_msg_and_die(must_be_root);
// Mount this thing. // Mount this thing.
if (ENABLE_FEATURE_MOUNT_LABEL) { if (ENABLE_FEATURE_MOUNT_LABEL)
resolve_mount_spec(&mtpair->mnt_fsname); resolve_mount_spec(&mtpair->mnt_fsname);
}
// NFS mounts want this to be xrealloc-able // NFS mounts want this to be xrealloc-able
mtcur->mnt_opts = xstrdup(mtcur->mnt_opts); mtcur->mnt_opts = xstrdup(mtcur->mnt_opts);