From cbc3f0813406af5becc516cbf462645f5f2819ff Mon Sep 17 00:00:00 2001 From: Michael Meffie Date: Tue, 17 Feb 2015 21:54:46 -0500 Subject: [PATCH] prdb_check: fix out of bounds array access in continuation entries 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 Reviewed-by: Benjamin Kaduk (cherry picked from commit 15e8678661ec49f5eac3954defad84c06b3e0164) Change-Id: Ifc0682cd2b6b1590b10c44ccdda181fd4227c1c2 Reviewed-on: http://gerrit.openafs.org/12104 Tested-by: BuildBot Reviewed-by: Michael Meffie Reviewed-by: Stephan Wiesand --- src/ptserver/db_verify.c | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/src/ptserver/db_verify.c b/src/ptserver/db_verify.c index 65b5be789..50bd037a3 100644 --- a/src/ptserver/db_verify.c +++ b/src/ptserver/db_verify.c @@ -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; -- 2.39.5