this patch is largely from cinap. libsec: improve thumbprint code 1) handle errors when loading thumbprint file. initThumbprints() now returns nil and sets errstr on error. a syntax error in a thumbprint file should be reported instead of silently ignored. (users seem ok.) 2) fix memory leak in initThumbprints(); we have to use freeThumbprints() instead of free to release crltab. 3) use the actual head entries for thumbprint storage in the thumbprints array. most thumbprint files are rather sparse. 4) remove private emalloc() function. since this is library code, let the application deal with the error. Reference: /n/sources/patch/maybe/thumb-improve Date: Sun Mar 16 17:31:15 CET 2014 Signed-off-by: quanstro@quanstro.net --- /sys/src/libsec/port/thumb.c Sun Mar 16 17:28:14 2014 +++ /sys/src/libsec/port/thumb.c Sun Mar 16 17:28:13 2014 @@ -7,26 +7,21 @@ enum{ ThumbTab = 1<<10 }; -static void * -emalloc(int n) +static Thumbprint* +tablehead(uchar *sum, Thumbprint *table) { - void *p; - if(n==0) - n=1; - p = malloc(n); - if(p == nil){ - exits("out of memory"); - } - memset(p, 0, n); - return p; + return &table[((sum[0]<<8) + sum[1]) & (ThumbTab-1)]; } void freeThumbprints(Thumbprint *table) { Thumbprint *hd, *p, *q; + + if(table == nil) + return; for(hd = table; hd < table+ThumbTab; hd++){ - for(p = hd->next; p; p = q){ + for(p = hd->next; p && p != hd; p = q){ q = p->next; free(p); } @@ -37,61 +32,89 @@ int okThumbprint(uchar *sum, Thumbprint *table) { - Thumbprint *p; - int i = ((sum[0]<<8) + sum[1]) & (ThumbTab-1); + Thumbprint *hd, *p; - for(p = table[i].next; p; p = p->next) + if(table == nil) + return 0; + hd = tablehead(sum, table); + for(p = hd->next; p; p = p->next){ if(memcmp(sum, p->sha1, SHA1dlen) == 0) return 1; + if(p == hd) + break; + } return 0; } -static void +static int loadThumbprints(char *file, Thumbprint *table, Thumbprint *crltab) { - Thumbprint *entry; - Biobuf *bin; + Thumbprint *hd, *entry; char *line, *field[50]; uchar sum[SHA1dlen]; - int i; + Biobuf *bin; - bin = Bopen(file, OREAD); - if(bin == nil) - return; - for(; (line = Brdstr(bin, '\n', 1)) != 0; free(line)){ + if(access(file, AEXIST) < 0) + return 0; /* not an error */ + if((bin = Bopen(file, OREAD)) == nil) + return -1; + for(; (line = Brdstr(bin, '\n', 1)) != nil; free(line)){ if(tokenize(line, field, nelem(field)) < 2) continue; if(strcmp(field[0], "#include") == 0){ - loadThumbprints(field[1], table, crltab); + if(loadThumbprints(field[1], table, crltab) < 0) + goto err; continue; } - if(strcmp(field[0], "x509") != 0 || strncmp(field[1], "sha1=", strlen("sha1=")) != 0) + if(strcmp(field[0], "x509") != 0 || strncmp(field[1], "sha1=", 5) != 0) continue; - field[1] += strlen("sha1="); - dec16(sum, sizeof(sum), field[1], strlen(field[1])); + field[1] += 5; + if(dec16(sum, SHA1dlen, field[1], strlen(field[1])) != SHA1dlen){ + werrstr("malformed x509 entry in %s: %s", file, field[1]); + goto err; + } if(crltab && okThumbprint(sum, crltab)) continue; - entry = (Thumbprint*)emalloc(sizeof(*entry)); + hd = tablehead(sum, table); + if(hd->next == nil) + entry = hd; + else { + if((entry = malloc(sizeof(*entry))) == nil) + goto err; + entry->next = hd->next; + } + hd->next = entry; memcpy(entry->sha1, sum, SHA1dlen); - i = ((sum[0]<<8) + sum[1]) & (ThumbTab-1); - entry->next = table[i].next; - table[i].next = entry; } Bterm(bin); + return 0; +err: + free(line); + Bterm(bin); + return -1; } Thumbprint * initThumbprints(char *ok, char *crl) { - Thumbprint *table, *crltab = nil; + Thumbprint *table, *crltab; + table = crltab = nil; if(crl){ - crltab = emalloc(ThumbTab * sizeof(*table)); - loadThumbprints(crl, crltab, nil); + if((crltab = malloc(ThumbTab * sizeof(*crltab))) == nil) + goto err; + memset(crltab, 0, ThumbTab * sizeof(*crltab)); + if(loadThumbprints(crl, crltab, nil) < 0) + goto err; + } + if((table = malloc(ThumbTab * sizeof(*table))) == nil) + goto err; + memset(table, 0, ThumbTab * sizeof(*table)); + if(loadThumbprints(ok, table, crltab) < 0){ + freeThumbprints(table); + table = nil; } - table = emalloc(ThumbTab * sizeof(*table)); - loadThumbprints(ok, table, crltab); - free(crltab); +err: + freeThumbprints(crltab); return table; } -