]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
prdb_check: fix out of bounds array access in continuation entries
authorMichael Meffie <mmeffie@sinenomine.net>
Wed, 18 Feb 2015 02:54:46 +0000 (21:54 -0500)
committerStephan Wiesand <stephan.wiesand@desy.de>
Fri, 20 Nov 2015 13:25:49 +0000 (08:25 -0500)
A continuation entry (struct contentry) contains 39 id elements, however
a regular entry (struct prentry) contains only 10 id elements.
Attempting to access more than 10 elements of a regular entry is
undefined behavior.

Use a stuct contentry when when processing continuation entries in
prdb_check.  This is done to safely traverse the id arrays of the
continuation entries.  Use the new pr_PrintContEntry to print
continuation entries.

The undefined behavior manfests as a segmentation violation in
WalkNextChain() when built with GCC 4.8 with optimization enabled.

Reviewed-on: http://gerrit.openafs.org/11742
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>
(cherry picked from commit 15e8678661ec49f5eac3954defad84c06b3e0164)

Change-Id: Ifc0682cd2b6b1590b10c44ccdda181fd4227c1c2
Reviewed-on: http://gerrit.openafs.org/12104
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Michael Meffie <mmeffie@sinenomine.net>
Reviewed-by: Stephan Wiesand <stephan.wiesand@desy.de>
src/ptserver/db_verify.c

index 65b5be789f433343a84db20ecc8cf217c4a40ae0..50bd037a3fae5bd44a63595a0048502586024338 100644 (file)
@@ -267,6 +267,13 @@ PrintEntryError(struct misc_data *misc, afs_int32 ea, struct prentry *e, int ind
     return 0;
 }
 
+int
+PrintContError(struct misc_data *misc, afs_int32 ea, struct contentry *c, int indent)
+{
+    pr_PrintContEntry(stderr, /*net order */ 0, ea, c, indent);
+    return 0;
+}
+
 afs_int32
 WalkHashTable(afs_int32 hashtable[],   /* hash table to walk */
              int hashType,             /* hash function to use */
@@ -392,7 +399,7 @@ WalkNextChain(char map[],           /* one byte per db entry */
     afs_int32 head;
     int bit;
     afs_int32 code;
-    struct prentry c;          /* continuation entry */
+    struct contentry c;                /* continuation entry */
     afs_int32 na;              /* next thread */
     int ni;
     afs_int32 eid = 0;
@@ -500,7 +507,7 @@ WalkNextChain(char map[],           /* one byte per db entry */
                return PRDBBAD;
            if (na != sghead) {
                fprintf(stderr, "last block: \n");
-               if (PrintEntryError(misc, na, &c, 4))
+               if (PrintContError(misc, na, &c, 4))
                    return PRDBBAD;
            }
            return 0;
@@ -514,7 +521,7 @@ WalkNextChain(char map[],           /* one byte per db entry */
            fprintf(stderr, "Continuation entry reused\n");
            if (PrintEntryError(misc, ea, e, 2))
                return PRDBBAD;
-           if (PrintEntryError(misc, na, &c, 4))
+           if (PrintContError(misc, na, &c, 4))
                return PRDBBAD;
            noErrors = 0;
            break;
@@ -524,7 +531,7 @@ WalkNextChain(char map[],           /* one byte per db entry */
            fprintf(stderr, "Continuation id mismatch\n");
            if (PrintEntryError(misc, ea, e, 2))
                return PRDBBAD;
-           if (PrintEntryError(misc, na, &c, 4))
+           if (PrintContError(misc, na, &c, 4))
                return PRDBBAD;
            noErrors = 0;
            continue;
@@ -548,7 +555,7 @@ WalkNextChain(char map[],           /* one byte per db entry */
                            "User can't be member of supergroup list\n");
                    if (PrintEntryError(misc, ea, e, 2))
                        return PRDBBAD;
-                   if (PrintEntryError(misc, na, &c, 4))
+                   if (PrintContError(misc, na, &c, 4))
                        return PRDBBAD;
                    noErrors = 0;
                }
@@ -575,7 +582,7 @@ WalkNextChain(char map[],           /* one byte per db entry */
                return PRDBBAD;
            if (na != head) {
                fprintf(stderr, "last block: \n");
-               if (PrintEntryError(misc, na, &c, 4))
+               if (PrintContError(misc, na, &c, 4))
                    return PRDBBAD;
            }
            return 0;
@@ -591,7 +598,7 @@ WalkNextChain(char map[],           /* one byte per db entry */
                fprintf(stderr, "walking free list");
            else if (PrintEntryError(misc, ea, e, 2))
                return PRDBBAD;
-           if (PrintEntryError(misc, na, &c, 4))
+           if (PrintContError(misc, na, &c, 4))
                return PRDBBAD;
            noErrors = 0;
            break;
@@ -603,7 +610,7 @@ WalkNextChain(char map[],           /* one byte per db entry */
                fprintf(stderr, "walking free list");
            else if (PrintEntryError(misc, ea, e, 2))
                return PRDBBAD;
-           if (PrintEntryError(misc, na, &c, 4))
+           if (PrintContError(misc, na, &c, 4))
                return PRDBBAD;
            noErrors = 0;
            continue;
@@ -633,7 +640,7 @@ WalkNextChain(char map[],           /* one byte per db entry */
                                "User can't be member of user in membership list\n");
                        if (PrintEntryError(misc, ea, e, 2))
                            return PRDBBAD;
-                       if (PrintEntryError(misc, na, &c, 4))
+                       if (PrintContError(misc, na, &c, 4))
                            return PRDBBAD;
                        noErrors = 0;
                    }
@@ -643,7 +650,7 @@ WalkNextChain(char map[],           /* one byte per db entry */
                                "Bad user/group dicotomy in membership list\n");
                        if (PrintEntryError(misc, ea, e, 2))
                            return PRDBBAD;
-                       if (PrintEntryError(misc, na, &c, 4))
+                       if (PrintContError(misc, na, &c, 4))
                            return PRDBBAD;
                        noErrors = 0;
                    }
@@ -1206,7 +1213,7 @@ DumpRecreate(char map[], struct misc_data *misc)
                }
                na = ntohl(e.next);
                while (na) {
-                   struct prentry c;
+                   struct contentry c;
                    code = pr_Read(na, (char *)&c, sizeof(c));
                    if (code)
                        return code;