svn commit: r187035 - head/sbin/mount

David E. O'Brien obrien at FreeBSD.org
Sat Jan 10 12:54:48 PST 2009


Author: obrien
Date: Sat Jan 10 20:54:47 2009
New Revision: 187035
URL: http://svn.freebsd.org/changeset/base/187035

Log:
  Explicitly check each mount argv building assignment for buffer over flowing.
  
  Reviewed by:	imp (earlier version of patch)

Modified:
  head/sbin/mount/mount.c

Modified: head/sbin/mount/mount.c
==============================================================================
--- head/sbin/mount/mount.c	Sat Jan 10 20:49:15 2009	(r187034)
+++ head/sbin/mount/mount.c	Sat Jan 10 20:54:47 2009	(r187035)
@@ -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 *
 	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 
 	/* 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 *
 			    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;
 }
 
 


More information about the svn-src-head mailing list