Explicitly check each mount argv building assignment for buffer over flowing.

Reviewed by:	imp (earlier version of patch)
This commit is contained in:
David E. O'Brien 2009-01-10 20:54:47 +00:00
parent 609c69b731
commit a86de99566

View File

@ -68,16 +68,21 @@ static const char rcsid[] =
#define MOUNT_META_OPTION_FSTAB "fstab" #define MOUNT_META_OPTION_FSTAB "fstab"
#define MOUNT_META_OPTION_CURRENT "current" #define MOUNT_META_OPTION_CURRENT "current"
#define MAX_ARGS 100
int debug, fstab_style, verbose; 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 *); char *catopt(char *, const char *);
struct statfs *getmntpt(const char *); struct statfs *getmntpt(const char *);
int hasopt(const char *, const char *); int hasopt(const char *, const char *);
int ismounted(struct fstab *, struct statfs *, int); int ismounted(struct fstab *, struct statfs *, int);
int isremountable(const char *); int isremountable(const char *);
void mangle(char *, int *, char *[]); void mangle(char *, struct cpa *);
char *update_options(char *, char *, int); char *update_options(char *, char *, int);
int mountfs(const char *, const char *, const char *, int mountfs(const char *, const char *, const char *,
int, const char *, const char *); int, const char *, const char *);
@ -499,12 +504,20 @@ hasopt(const char *mntopts, const char *option)
return (found); 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 int
mountfs(const char *vfstype, const char *spec, const char *name, int flags, mountfs(const char *vfstype, const char *spec, const char *name, int flags,
const char *options, const char *mntopts) const char *options, const char *mntopts)
{ {
static int argc; struct cpa mnt_argv;
char *argv[MAX_ARGS];
struct statfs sf; struct statfs sf;
int i, ret; int i, ret;
char *optbuf, execname[PATH_MAX], mntpath[PATH_MAX]; 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 */ /* Construct the name of the appropriate mount command */
(void)snprintf(execname, sizeof(execname), "mount_%s", vfstype); (void)snprintf(execname, sizeof(execname), "mount_%s", vfstype);
argc = 0; mnt_argv.m = MAX_ARGS;
argv[argc++] = execname; mnt_argv.c = -1;
mangle(optbuf, &argc, argv); append_arg(&mnt_argv, execname);
argv[argc++] = strdup(spec); mangle(optbuf, &mnt_argv);
argv[argc++] = strdup(name); append_arg(&mnt_argv, strdup(spec));
argv[argc] = NULL; append_arg(&mnt_argv, strdup(name));
append_arg(&mnt_argv, NULL);
if (MAX_ARGS <= argc )
errx(1, "Cannot process more than %d mount arguments",
MAX_ARGS);
if (debug) { if (debug) {
if (use_mountprog(vfstype)) if (use_mountprog(vfstype))
printf("exec: mount_%s", vfstype); printf("exec: mount_%s", vfstype);
else else
printf("mount -t %s", vfstype); printf("mount -t %s", vfstype);
for (i = 1; i < argc; i++) for (i = 1; i < mnt_argv.c; i++)
(void)printf(" %s", argv[i]); (void)printf(" %s", mnt_argv.a[i]);
(void)printf("\n"); (void)printf("\n");
return (0); return (0);
} }
if (use_mountprog(vfstype)) { if (use_mountprog(vfstype)) {
ret = exec_mountprog(name, execname, argv); ret = exec_mountprog(name, execname, mnt_argv.a);
} else { } else {
ret = mount_fs(vfstype, argc, argv); ret = mount_fs(vfstype, mnt_argv.c, mnt_argv.a);
} }
free(optbuf); free(optbuf);
@ -670,12 +680,10 @@ catopt(char *s0, const char *s1)
} }
void void
mangle(char *options, int *argcp, char *argv[]) mangle(char *options, struct cpa *a)
{ {
char *p, *s; char *p, *s;
int argc;
argc = *argcp;
for (s = options; (p = strsep(&s, ",")) != NULL;) for (s = options; (p = strsep(&s, ",")) != NULL;)
if (*p != '\0') { if (*p != '\0') {
if (strcmp(p, "noauto") == 0) { if (strcmp(p, "noauto") == 0) {
@ -707,19 +715,17 @@ mangle(char *options, int *argcp, char *argv[])
sizeof(groupquotaeq) - 1) == 0) { sizeof(groupquotaeq) - 1) == 0) {
continue; continue;
} else if (*p == '-') { } else if (*p == '-') {
argv[argc++] = p; append_arg(a, p);
p = strchr(p, '='); p = strchr(p, '=');
if (p != NULL) { if (p != NULL) {
*p = '\0'; *p = '\0';
argv[argc++] = p+1; append_arg(a, p + 1);
} }
} else { } else {
argv[argc++] = strdup("-o"); append_arg(a, strdup("-o"));
argv[argc++] = p; append_arg(a, p);
} }
} }
*argcp = argc;
} }