diff options
author | obrien <obrien@FreeBSD.org> | 2009-01-10 20:54:47 +0000 |
---|---|---|
committer | obrien <obrien@FreeBSD.org> | 2009-01-10 20:54:47 +0000 |
commit | 52de835e285f6f5843ca2ba5421d9e128e9f328f (patch) | |
tree | 2e963fc95deac6a8c034b8cd14d3921be011af0d /sbin/mount | |
parent | 2303bb091283a58b587e236f8fe832aaaaab0002 (diff) | |
download | FreeBSD-src-52de835e285f6f5843ca2ba5421d9e128e9f328f.zip FreeBSD-src-52de835e285f6f5843ca2ba5421d9e128e9f328f.tar.gz |
Explicitly check each mount argv building assignment for buffer over flowing.
Reviewed by: imp (earlier version of patch)
Diffstat (limited to 'sbin/mount')
-rw-r--r-- | sbin/mount/mount.c | 62 |
1 files changed, 34 insertions, 28 deletions
diff --git a/sbin/mount/mount.c b/sbin/mount/mount.c index 1cc15a7..56f01d8 100644 --- a/sbin/mount/mount.c +++ b/sbin/mount/mount.c @@ -68,16 +68,21 @@ static const char rcsid[] = #define MOUNT_META_OPTION_FSTAB "fstab" #define MOUNT_META_OPTION_CURRENT "current" -#define MAX_ARGS 100 - int debug, fstab_style, verbose; +#define MAX_ARGS 100 +struct cpa { + char *a[MAX_ARGS]; + ssize_t m; + int c; +}; + char *catopt(char *, const char *); struct statfs *getmntpt(const char *); int hasopt(const char *, const char *); int ismounted(struct fstab *, struct statfs *, int); int isremountable(const char *); -void mangle(char *, int *, char *[]); +void mangle(char *, struct cpa *); char *update_options(char *, char *, int); int mountfs(const char *, const char *, const char *, int, const char *, const char *); @@ -499,12 +504,20 @@ hasopt(const char *mntopts, const char *option) return (found); } +static void +append_arg(struct cpa *sa, char *arg) +{ + if (sa->c >= sa->m) + errx(1, "Cannot process more than %zd mount arguments", sa->m); + + sa->a[++sa->c] = arg; +} + int mountfs(const char *vfstype, const char *spec, const char *name, int flags, const char *options, const char *mntopts) { - static int argc; - char *argv[MAX_ARGS]; + struct cpa mnt_argv; struct statfs sf; int i, ret; char *optbuf, execname[PATH_MAX], mntpath[PATH_MAX]; @@ -542,32 +555,29 @@ mountfs(const char *vfstype, const char *spec, const char *name, int flags, /* Construct the name of the appropriate mount command */ (void)snprintf(execname, sizeof(execname), "mount_%s", vfstype); - argc = 0; - argv[argc++] = execname; - mangle(optbuf, &argc, argv); - argv[argc++] = strdup(spec); - argv[argc++] = strdup(name); - argv[argc] = NULL; - - if (MAX_ARGS <= argc ) - errx(1, "Cannot process more than %d mount arguments", - MAX_ARGS); + mnt_argv.m = MAX_ARGS; + mnt_argv.c = -1; + append_arg(&mnt_argv, execname); + mangle(optbuf, &mnt_argv); + append_arg(&mnt_argv, strdup(spec)); + append_arg(&mnt_argv, strdup(name)); + append_arg(&mnt_argv, NULL); if (debug) { if (use_mountprog(vfstype)) printf("exec: mount_%s", vfstype); else printf("mount -t %s", vfstype); - for (i = 1; i < argc; i++) - (void)printf(" %s", argv[i]); + for (i = 1; i < mnt_argv.c; i++) + (void)printf(" %s", mnt_argv.a[i]); (void)printf("\n"); return (0); } if (use_mountprog(vfstype)) { - ret = exec_mountprog(name, execname, argv); + ret = exec_mountprog(name, execname, mnt_argv.a); } else { - ret = mount_fs(vfstype, argc, argv); + ret = mount_fs(vfstype, mnt_argv.c, mnt_argv.a); } free(optbuf); @@ -670,12 +680,10 @@ catopt(char *s0, const char *s1) } void -mangle(char *options, int *argcp, char *argv[]) +mangle(char *options, struct cpa *a) { char *p, *s; - int argc; - argc = *argcp; for (s = options; (p = strsep(&s, ",")) != NULL;) if (*p != '\0') { if (strcmp(p, "noauto") == 0) { @@ -707,19 +715,17 @@ mangle(char *options, int *argcp, char *argv[]) sizeof(groupquotaeq) - 1) == 0) { continue; } else if (*p == '-') { - argv[argc++] = p; + append_arg(a, p); p = strchr(p, '='); if (p != NULL) { *p = '\0'; - argv[argc++] = p+1; + append_arg(a, p + 1); } } else { - argv[argc++] = strdup("-o"); - argv[argc++] = p; + append_arg(a, strdup("-o")); + append_arg(a, p); } } - - *argcp = argc; } |