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"

Reply via email to