Author: imp
Date: Sat May  1 07:25:28 2010
New Revision: 207461
URL: http://svn.freebsd.org/changeset/base/207461

Log:
  sparc64, and possibly other architectures, pads the length of the
  section holding the config file to sh_addralign bytes using NULs.
  This bogusly triggers an assert.  Break out of the loop when we hit an
  NUL within that many bytes of the end.
  
  MFC after:    3 days

Modified:
  head/usr.sbin/config/main.c

Modified: head/usr.sbin/config/main.c
==============================================================================
--- head/usr.sbin/config/main.c Sat May  1 03:41:21 2010        (r207460)
+++ head/usr.sbin/config/main.c Sat May  1 07:25:28 2010        (r207461)
@@ -670,7 +670,7 @@ kernconfdump(const char *file)
        struct stat st;
        FILE *fp, *pp;
        int error, len, osz, r;
-       unsigned int i, off, size;
+       unsigned int i, off, size, t1, t2, align;
        char *cmd, *o;
 
        r = open(file, O_RDONLY);
@@ -689,8 +689,8 @@ kernconfdump(const char *file)
        if (o == NULL)
                err(EXIT_FAILURE, "Couldn't allocate memory");
        /* ELF note section header. */
-       asprintf(&cmd, "/usr/bin/elfdump -c %s | grep -A 5 kern_conf"
-           "| tail -2 | cut -d ' ' -f 2 | paste - - -", file);
+       asprintf(&cmd, "/usr/bin/elfdump -c %s | grep -A 8 kern_conf"
+           "| tail -5 | cut -d ' ' -f 2 | paste - - - - -", file);
        if (cmd == NULL)
                errx(EXIT_FAILURE, "asprintf() failed");
        pp = popen(cmd, "r");
@@ -699,24 +699,28 @@ kernconfdump(const char *file)
        free(cmd);
        len = fread(o, osz, 1, pp);
        pclose(pp);
-       r = sscanf(o, "%d\t%d", &off, &size);
+       r = sscanf(o, "%d%d%d%d%d", &off, &size, &t1, &t2, &align);
        free(o);
-       if (r != 2)
+       if (r != 5)
                errx(EXIT_FAILURE, "File %s doesn't contain configuration "
                    "file. Either unsupported, or not compiled with "
                    "INCLUDE_CONFIG_FILE", file);
        r = fseek(fp, off, SEEK_CUR);
        if (r != 0)
                err(EXIT_FAILURE, "fseek() failed");
-       for (i = 0; i < size - 1; i++) {
+       for (i = 0; i < size; i++) {
                r = fgetc(fp);
                if (r == EOF)
                        break;
                /* 
                 * If '\0' is present in the middle of the configuration
                 * string, this means something very weird is happening.
-                * Make such case very visible.
+                * Make such case very visible.  However, some architectures
+                * pad the length of the section with NULs to a multiple of
+                * sh_addralign, allow a NUL in that part of the section.
                 */
+               if (r == '\0' && (size - i) < align)
+                       break;
                assert(r != '\0' && ("Char present in the configuration "
                    "string mustn't be equal to 0"));
                fputc(r, stdout);
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to