[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: [PATCH] avoid assuming MAXPATHLEN in config(8)



2011/7/7 Ed Schouten <ed@80386.nl>:
> Considering that the function is rather small anyway, why not compile it
> in unconditionally (though having a different name).

Hi Ed,

I made the adjustment you requested, plus a bit more polishing
(plugged a memleak, etc), and then I hit what seems like a memory
corruption heisenbug.

I haven't been able to determine whether my patch introduces this bug
or it just uncovers it.  As for now please disregard my request untill
I have time to debug this properly.

Thanks

-- 
Robert Millan
=== modified file 'config.h'
--- config.h	2011-07-07 13:59:05 +0000
+++ config.h	2011-07-07 14:06:28 +0000
@@ -199,7 +199,7 @@
 extern int	maxusers;
 
 extern char *PREFIX;		/* Config file name - for error messages */
-extern char srcdir[];		/* root of the kernel source tree */
+extern char *srcdir;		/* root of the kernel source tree */
 
 #define eq(a,b)	(!strcmp(a,b))
 #define ns(s)	strdup(s)

=== modified file 'main.c'
--- main.c	2011-07-07 13:59:05 +0000
+++ main.c	2011-07-07 17:51:39 +0000
@@ -71,8 +71,8 @@
 #define	CDIR	"../compile/"
 
 char *	PREFIX;
-char 	destdir[MAXPATHLEN];
-char 	srcdir[MAXPATHLEN];
+char *	destdir;
+char *	srcdir;
 
 int	debugging;
 int	profiling;
@@ -122,8 +122,8 @@
 			printmachine = 1;
 			break;
 		case 'd':
-			if (*destdir == '\0')
-				strlcpy(destdir, optarg, sizeof(destdir));
+			if (destdir == NULL)
+				destdir = strdup(optarg);
 			else
 				errx(EXIT_FAILURE, "directory already set");
 			break;
@@ -165,14 +165,13 @@
 			err(2, "%s", PREFIX);
 		yyfile = PREFIX;
 	}
-	if (*destdir != '\0') {
+	if (destdir != NULL) {
 		len = strlen(destdir);
 		while (len > 1 && destdir[len - 1] == '/')
 			destdir[--len] = '\0';
 		get_srcdir();
 	} else {
-		strlcpy(destdir, CDIR, sizeof(destdir));
-		strlcat(destdir, PREFIX, sizeof(destdir));
+		(void) asprintf(&destdir, "%s%s", CDIR, PREFIX);
 	}
 
 	SLIST_INIT(&cputype);
@@ -230,6 +229,27 @@
 }
 
 /*
+ * xrealpath
+ *	realpath() with extension to use malloc() when resolved is NULL.
+ */
+static char *
+xrealpath(const char *name, char *resolved)
+{
+#ifdef MAXPATHLEN
+	if (resolved == NULL) {
+		resolved = malloc(MAXPATHLEN);
+		if (realpath(name, resolved) == NULL) {
+			free(resolved);
+			resolved = NULL;
+		}
+	} else
+#endif
+		resolved = realpath(name, resolved);
+
+	return resolved;
+}
+
+/*
  * get_srcdir
  *	determine the root of the kernel source tree
  *	and save that in srcdir.
@@ -241,7 +261,9 @@
 	char *p, *pwd;
 	int i;
 
-	if (realpath("../..", srcdir) == NULL)
+	if (srcdir != NULL)
+		free(srcdir);
+	if ((srcdir = xrealpath("../..", NULL)) == NULL)
 		err(EXIT_FAILURE, "Unable to find root of source tree");
 	if ((pwd = getenv("PWD")) != NULL && *pwd == '/' &&
 	    (pwd = strdup(pwd)) != NULL) {
@@ -254,9 +276,12 @@
 			*p = '\0';
 		}
 		if (stat(pwd, &lg) != -1 && stat(srcdir, &phy) != -1 &&
-		    lg.st_dev == phy.st_dev && lg.st_ino == phy.st_ino)
-			strlcpy(srcdir, pwd, MAXPATHLEN);
-		free(pwd);
+		    lg.st_dev == phy.st_dev && lg.st_ino == phy.st_ino) {
+			free(srcdir);
+			srcdir = pwd;
+		} else {
+			free(pwd);
+		}
 	}
 }
 
@@ -386,9 +411,9 @@
 	char *cp = NULL;
 
 	if (file)
-		asprintf(&cp, "%s/%s", destdir, file);
+		asprintf(&cp, "%s/%s", destdir ? destdir : "", file);
 	else
-		cp = strdup(destdir);
+		cp = strdup(destdir ? destdir : "");
 	return (cp);
 }
 

=== modified file 'mkmakefile.c'
--- mkmakefile.c	2011-07-07 13:59:05 +0000
+++ mkmakefile.c	2011-07-07 14:12:06 +0000
@@ -152,7 +152,7 @@
 		fprintf(ofp, "DEBUG=-g\n");
 	if (profiling)
 		fprintf(ofp, "PROFLEVEL=%d\n", profiling);
-	if (*srcdir != '\0')
+	if (srcdir != NULL)
 		fprintf(ofp,"S=%s\n", srcdir);
 	while (fgets(line, BUFSIZ, ifp) != 0) {
 		if (*line != '%') {
@@ -304,9 +304,9 @@
 }
 
 static void
-read_file(char *fname)
+read_file(const char *fname)
 {
-	char ifname[MAXPATHLEN];
+	char *ifname;
 	FILE *fp;
 	struct file_list *tp;
 	struct device *dp;
@@ -349,8 +349,9 @@
 			    fname);
 			exit(1);
 		}
-		(void) snprintf(ifname, sizeof(ifname), "../../%s", wd);
+		(void) asprintf(&ifname, "../../%s", wd);
 		read_file(ifname);
+		free(ifname);
 		while (((wd = get_word(fp)) != (char *)EOF) && wd)
 			;
 		goto next;
@@ -559,14 +560,13 @@
 static void
 read_files(void)
 {
-	char fname[MAXPATHLEN];
+	char *fname;
 	struct files_name *nl, *tnl;
 	
-	(void) snprintf(fname, sizeof(fname), "../../conf/files");
-	read_file(fname);
-	(void) snprintf(fname, sizeof(fname),
-		       	"../../conf/files.%s", machinename);
-	read_file(fname);
+	read_file("../../conf/files");
+	(void) asprintf(&fname, "../../conf/files.%s", machinename);
+	read_file(fname);
+	free(fname);
 	for (nl = STAILQ_FIRST(&fntab); nl != NULL; nl = tnl) {
 		read_file(nl->f_name);
 		tnl = STAILQ_NEXT(nl, f_next);

=== modified file 'mkoptions.c'
--- mkoptions.c	2011-07-07 13:59:05 +0000
+++ mkoptions.c	2011-07-07 17:51:39 +0000
@@ -290,22 +290,20 @@
 static char *
 tooption(char *name)
 {
-	static char hbuf[MAXPATHLEN];
-	char nbuf[MAXPATHLEN];
+	char *nbuf;
 	struct opt_list *po;
 
 	/* "cannot happen"?  the otab list should be complete.. */
-	(void)strlcpy(nbuf, "options.h", sizeof(nbuf));
+	nbuf = "options.h";
 
 	SLIST_FOREACH(po, &otab, o_next) {
 		if (eq(po->o_name, name)) {
-			strlcpy(nbuf, po->o_file, sizeof(nbuf));
+			nbuf = po->o_file;
 			break;
 		}
 	}
 
-	(void)strlcpy(hbuf, path(nbuf), sizeof(hbuf));
-	return (hbuf);
+	return (path(nbuf));
 }
 
 	
@@ -363,7 +361,7 @@
 {
 	FILE *fp;
 	char *wd, *this, *val;
-	char genopt[MAXPATHLEN];
+	char *genopt;
 
 	fp = fopen(fname, "r");
 	if (fp == 0)
@@ -387,7 +385,7 @@
 				exit(1);
 			}
 			char *s = ns(this);
-			(void)snprintf(genopt, sizeof(genopt), "opt_%s.h",
+			(void)asprintf(&genopt, "opt_%s.h",
 			    lower(s));
 			val = genopt;
 			free(s);
@@ -399,6 +397,7 @@
 			update_option(this, val, flags);
 	}
 	(void)fclose(fp);
+	free(genopt);
 	return (1);
 }
 
@@ -408,16 +407,17 @@
 static void
 read_options(void)
 {
-	char fname[MAXPATHLEN];
+	char *fname;
 
 	SLIST_INIT(&otab);
 	read_option_file("../../conf/options", 0);
-	(void)snprintf(fname, sizeof fname, "../../conf/options.%s",
+	(void)asprintf(&fname, "../../conf/options.%s",
 	    machinename);
 	if (!read_option_file(fname, 0)) {
-		(void)snprintf(fname, sizeof fname, "options.%s", machinename);
+		(void)sprintf(fname, "options.%s", machinename);
 		read_option_file(fname, 0);
 	}
+	free(fname);
 	read_option_file("../../conf/options-compat", OL_ALIAS);
 }
 


Reply to: