config(8) assumes MAXPATHLEN is defined in a few places, but presence of this macro isn't garanteed (POSIX says that it is only present when a file length limit exists, which may not be the case).
This patch fixes a usr.sbin/config compile problem on Debian GNU/Hurd by using dynamic allocation. Doing so also reduces its memory footprint and safeguards against possible error conditions when zero-length pathnames are used. -- Robert Millan
Index: usr.sbin/config/mkoptions.c =================================================================== --- usr.sbin/config/mkoptions.c (revision 223792) +++ usr.sbin/config/mkoptions.c (working copy) @@ -290,22 +290,21 @@ 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 = strdup("options.h"); SLIST_FOREACH(po, &otab, o_next) { if (eq(po->o_name, name)) { - strlcpy(nbuf, po->o_file, sizeof(nbuf)); + free(nbuf); + nbuf = strdup(po->o_file); break; } } - (void)strlcpy(hbuf, path(nbuf), sizeof(hbuf)); - return (hbuf); + return (nbuf); } @@ -363,7 +362,7 @@ { FILE *fp; char *wd, *this, *val; - char genopt[MAXPATHLEN]; + char *genopt = NULL; fp = fopen(fname, "r"); if (fp == 0) @@ -387,7 +386,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 +398,7 @@ update_option(this, val, flags); } (void)fclose(fp); + free(genopt); return (1); } @@ -408,16 +408,17 @@ static void read_options(void) { - char fname[MAXPATHLEN]; + char *fname = NULL; 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)asprintf(&fname, "options.%s", machinename); read_option_file(fname, 0); } + free(fname); read_option_file("../../conf/options-compat", OL_ALIAS); } Index: usr.sbin/config/main.c =================================================================== --- usr.sbin/config/main.c (revision 223792) +++ usr.sbin/config/main.c (working copy) @@ -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, CDIR "%s", PREFIX); } SLIST_INIT(&cputype); @@ -229,6 +228,19 @@ exit(0); } +#ifndef __GLIBC__ +static char * +canonicalize_file_name(const char *pathname) +{ + char *ret = malloc(MAXPATHLEN); + if (realpath(pathname, ret) == NULL) { + free(ret); + ret = NULL; + } + return ret; +} +#endif + /* * get_srcdir * determine the root of the kernel source tree @@ -241,7 +253,9 @@ char *p, *pwd; int i; - if (realpath("../..", srcdir) == NULL) + if (srcdir != NULL) + free(srcdir); + if ((srcdir = canonicalize_file_name("../..")) == NULL) err(EXIT_FAILURE, "Unable to find root of source tree"); if ((pwd = getenv("PWD")) != NULL && *pwd == '/' && (pwd = strdup(pwd)) != NULL) { @@ -254,9 +268,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); + } } } Index: usr.sbin/config/mkmakefile.c =================================================================== --- usr.sbin/config/mkmakefile.c (revision 223792) +++ usr.sbin/config/mkmakefile.c (working copy) @@ -304,9 +304,9 @@ } static void -read_file(char *fname) +read_file(const char *fname) { - char ifname[MAXPATHLEN]; + char *ifname = NULL; 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 = NULL; struct files_name *nl, *tnl; - (void) snprintf(fname, sizeof(fname), "../../conf/files"); + read_file("../../conf/files"); + (void) asprintf(&fname, "../../conf/files.%s", machinename); read_file(fname); - (void) snprintf(fname, sizeof(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); Index: usr.sbin/config/config.h =================================================================== --- usr.sbin/config/config.h (revision 223792) +++ usr.sbin/config/config.h (working copy) @@ -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)
_______________________________________________ freebsd-hackers@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to "freebsd-hackers-unsubscr...@freebsd.org"