From: Michael Meffie Date: Wed, 18 Feb 2015 02:11:50 +0000 (-0500) Subject: libprot: add pr_PrintContEntry function X-Git-Tag: upstream/1.8.0_pre1^2~211 X-Git-Url: https://git.michaelhowe.org/gitweb/?a=commitdiff_plain;h=121ac2d939e19741986ddfbd387b5310c40edd0d;p=packages%2Fo%2Fopenafs.git libprot: add pr_PrintContEntry function 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. Add a new function to safely print continuation entries and change pr_PrintEntry to avoid accessing the entries array out of bounds. The pr_PrintEntry function is at this time only used by the prdb_check and ptclient debugging utilities. Change-Id: Ie836983c8a5970a9495b87d0627ba6c05d117a9b Reviewed-on: http://gerrit.openafs.org/11750 Tested-by: BuildBot Reviewed-by: Benjamin Kaduk --- diff --git a/src/ptserver/display.c b/src/ptserver/display.c index 2f57def34..64fcf6b8f 100644 --- a/src/ptserver/display.c +++ b/src/ptserver/display.c @@ -40,89 +40,107 @@ pr_TimeToString(time_t clock) #define host(a) (hostOrder ? (a) : ntohl(a)) -static void -PrintEntries(FILE *f, int hostOrder, int indent, struct prentry *e, int n) -{ - int i; - int newline; - - newline = 0; - for (i = 0; i < n; i++) { - if (e->entries[i] == 0) - break; - - if (i == 0) - fprintf(f, "%*sids ", indent, ""); - else if (newline == 0) - fprintf(f, "%*s", indent + 4, ""); +#define PRINT_COMMON_FIELDS(e) \ +do { \ + int i; \ + if ((e)->cellid) \ + fprintf(f, "cellid == %d\n", host((e)->cellid)); \ + for (i = 0; i < sizeof((e)->reserved) / sizeof((e)->reserved[0]); i++) \ + if ((e)->reserved[i]) \ + fprintf(f, "reserved field [%d] not zero: %d\n", i, \ + host((e)->reserved[i])); \ + fprintf(f, "%*s", indent, ""); \ + fprintf(f, "Entry at %d: flags 0x%x, id %di, next %d.\n", ea, \ + host((e)->flags), host((e)->id), host((e)->next)); \ +} while (0) - if (host(e->entries[i]) == PRBADID) - fprintf(f, " EMPTY"); - else - fprintf(f, "%6d", host(e->entries[i])); - newline = 1; - if (i % 10 == 9) { - fprintf(f, "\n"); - newline = 0; - } else - fprintf(f, " "); - } - if (newline) - fprintf(f, "\n"); -} +#define PRINT_IDS(e) \ +do { \ + int i; \ + int newline = 0; \ + for (i = 0; i < sizeof((e)->entries)/sizeof((e)->entries[0]); i++) { \ + if ((e)->entries[i] == 0) \ + break; \ + if (i == 0) \ + fprintf(f, "%*sids ", indent, ""); \ + else if (newline == 0) \ + fprintf(f, "%*s", indent + 4, ""); \ + if (host((e)->entries[i]) == PRBADID) \ + fprintf(f, " EMPTY"); \ + else \ + fprintf(f, "%6d", host((e)->entries[i])); \ + newline = 1; \ + if (i % 10 == 9) { \ + fprintf(f, "\n"); \ + newline = 0; \ + } else \ + fprintf(f, " "); \ + } \ + if (newline) \ + fprintf(f, "\n"); \ +} while (0) +/* regular entry */ int -pr_PrintEntry(FILE *f, int hostOrder, afs_int32 ea, struct prentry *e, int indent) +pr_PrintEntry(FILE *f, int hostOrder, afs_int32 ea, struct prentry *e, + int indent) { - int i; - - if (e->cellid) - fprintf(f, "cellid == %d\n", host(e->cellid)); - for (i = 0; i < sizeof(e->reserved) / sizeof(e->reserved[0]); i++) - if (e->reserved[i]) - fprintf(f, "reserved field [%d] not zero: %d\n", i, - host(e->reserved[i])); + /* In case we are given the wrong type of entry. */ + if ((host(e->flags) & PRTYPE) == PRCONT) { + struct contentry c; + memcpy(&c, e, sizeof(c)); + return pr_PrintContEntry(f, hostOrder, ea, &c, indent); + } - fprintf(f, "%*s", indent, ""); - fprintf(f, "Entry at %d: flags 0x%x, id %di, next %d.\n", ea, - host(e->flags), host(e->id), host(e->next)); + PRINT_COMMON_FIELDS(e); fprintf(f, "%*s", indent, ""); fprintf(f, "c:%s ", pr_TimeToString(host(e->createTime))); fprintf(f, "a:%s ", pr_TimeToString(host(e->addTime))); fprintf(f, "r:%s ", pr_TimeToString(host(e->removeTime))); fprintf(f, "n:%s\n", pr_TimeToString(host(e->changeTime))); - if (host(e->flags) & PRCONT) - PrintEntries(f, hostOrder, indent, e, COSIZE); - else { /* regular entry */ - PrintEntries(f, hostOrder, indent, e, PRSIZE); - fprintf(f, "%*s", indent, ""); - fprintf(f, "hash (id %d name %d). Owner %di, creator %di\n", - host(e->nextID), host(e->nextName), host(e->owner), - host(e->creator)); - fprintf(f, "%*s", indent, ""); + PRINT_IDS(e); + fprintf(f, "%*s", indent, ""); + fprintf(f, "hash (id %d name %d). Owner %di, creator %di\n", + host(e->nextID), host(e->nextName), host(e->owner), + host(e->creator)); + fprintf(f, "%*s", indent, ""); #if defined(SUPERGROUPS) - fprintf(f, "quota groups %d, foreign users %d. Mem: %d, cntsg: %d\n", - host(e->ngroups), host(e->nusers), host(e->count), - host(e->instance)); + fprintf(f, "quota groups %d, foreign users %d. Mem: %d, cntsg: %d\n", + host(e->ngroups), host(e->nusers), host(e->count), + host(e->instance)); #else - fprintf(f, "quota groups %d, foreign users %d. Mem: %d, inst: %d\n", - host(e->ngroups), host(e->nusers), host(e->count), - host(e->instance)); + fprintf(f, "quota groups %d, foreign users %d. Mem: %d, inst: %d\n", + host(e->ngroups), host(e->nusers), host(e->count), + host(e->instance)); #endif - fprintf(f, "%*s", indent, ""); + fprintf(f, "%*s", indent, ""); #if defined(SUPERGROUPS) - fprintf(f, "Owned chain %d, next owned %d, nextsg %d, sg (%d %d).\n", - host(e->owned), host(e->nextOwned), host(e->parent), - host(e->sibling), host(e->child)); + fprintf(f, "Owned chain %d, next owned %d, nextsg %d, sg (%d %d).\n", + host(e->owned), host(e->nextOwned), host(e->parent), + host(e->sibling), host(e->child)); #else - fprintf(f, "Owned chain %d, next owned %d, inst ptrs(%d %d %d).\n", - host(e->owned), host(e->nextOwned), host(e->parent), - host(e->sibling), host(e->child)); + fprintf(f, "Owned chain %d, next owned %d, inst ptrs(%d %d %d).\n", + host(e->owned), host(e->nextOwned), host(e->parent), + host(e->sibling), host(e->child)); #endif - fprintf(f, "%*s", indent, ""); - if (strlen(e->name) >= PR_MAXNAMELEN) - fprintf(f, "NAME TOO LONG: "); - fprintf(f, "Name is '%.*s'\n", PR_MAXNAMELEN, e->name); - } + fprintf(f, "%*s", indent, ""); + if (strlen(e->name) >= PR_MAXNAMELEN) + fprintf(f, "NAME TOO LONG: "); + fprintf(f, "Name is '%.*s'\n", PR_MAXNAMELEN, e->name); + return 0; +} + +int +pr_PrintContEntry(FILE *f, int hostOrder, afs_int32 ea, struct contentry *c, int indent) +{ + PRINT_COMMON_FIELDS(c); + /* Print the reserved fields for compatibility with older versions. + * They should always be zero, checked in PRINT_COMMON_FIELDS(). */ + fprintf(f, "%*s", indent, ""); + fprintf(f, "c:%s ", pr_TimeToString(host((c)->reserved[0]))); + fprintf(f, "a:%s ", pr_TimeToString(host((c)->reserved[1]))); + fprintf(f, "r:%s ", pr_TimeToString(host((c)->reserved[2]))); + fprintf(f, "n:%s\n", pr_TimeToString(host((c)->reserved[3]))); + PRINT_IDS(c); return 0; } diff --git a/src/ptserver/display.h b/src/ptserver/display.h index 177b7c55b..b34d41372 100644 --- a/src/ptserver/display.h +++ b/src/ptserver/display.h @@ -12,5 +12,7 @@ extern int pr_PrintEntry(FILE *f, int hostOrder, afs_int32 ea, struct prentry *e, int indent); +extern int pr_PrintContEntry(FILE *f, int hostOrder, afs_int32 ea, + struct contentry *e, int indent); #endif diff --git a/src/ptserver/liboafs_prot.la.sym b/src/ptserver/liboafs_prot.la.sym index af1109aef..dc6c78265 100644 --- a/src/ptserver/liboafs_prot.la.sym +++ b/src/ptserver/liboafs_prot.la.sym @@ -20,6 +20,7 @@ pr_ListMembers pr_ListOwned pr_ListSuperGroups pr_NameToId +pr_PrintContEntry pr_PrintEntry pr_RemoveUserFromGroup pr_SIdToName