--- src/cdf.c.orig 2009-04-23 15:43:38.000000000 -0700 +++ src/cdf.c 2009-04-23 16:07:04.000000000 -0700 @@ -281,6 +281,8 @@ if (h->h_master_sat[i] == CDF_SECID_FREE) break; + if (h->h_num_sectors_in_master_sat > UINT32_MAX - i) + return -1; sat->sat_len = (h->h_num_sectors_in_master_sat + i); if ((sat->sat_tab = calloc(sat->sat_len, ss)) == NULL) return -1; @@ -309,7 +311,7 @@ DPRINTF(("Reading master sector %d", mid)); goto out2; } - for (k = 0; k < (ss / sizeof(mid)) - 1; k++, i++) + for (k = 0; k < (ss / sizeof(mid)) - 1 && i < sat->sat_len; k++, i++) if (cdf_read_sector(fd, sat->sat_tab, ss * i, ss, h, CDF_TOLE4(msa[k])) != (ssize_t)ss) { DPRINTF(("Reading sector %d", @@ -324,6 +326,7 @@ free(msa); out1: free(sat->sat_tab); + sat->sat_tab = NULL; return -1; } @@ -369,7 +372,7 @@ if (scn->sst_tab == NULL) return -1; - for (j = i = 0; sid >= 0; i++, j++) { + for (j = i = 0; sid >= 0 && i < scn->sst_len; i++, j++) { if ((nr = cdf_read_sector(fd, scn->sst_tab, i * ss, ss, h, sid)) != (ssize_t)ss) { if (i == scn->sst_len - 1 && nr > 0) { @@ -389,6 +392,7 @@ return 0; out: free(scn->sst_tab); + scn->sst_tab = NULL; return (size_t)-1; } @@ -424,6 +428,7 @@ return 0; out: free(scn->sst_tab); + scn->sst_tab = NULL; return (size_t)-1; } @@ -462,6 +467,7 @@ if ((buf = malloc(ss)) == NULL) { free(dir->dir_tab); + dir->dir_tab = NULL; return -1; } @@ -488,6 +494,7 @@ return 0; out: free(dir->dir_tab); + dir->dir_tab = NULL; free(buf); return -1; } @@ -509,7 +516,7 @@ if (ssat->sat_tab == NULL) return -1; - for (j = i = 0; sid >= 0; i++, j++) { + for (j = i = 0; sid >= 0 && i < ssat->sat_len; i++, j++) { if (j >= CDF_LOOP_LIMIT) { DPRINTF(("Read short sat sector loop limit")); errno = EFTYPE; @@ -525,6 +532,7 @@ return 0; out: free(ssat->sat_tab); + ssat->sat_tab = NULL; return -1; } @@ -612,6 +620,8 @@ sh.sh_properties = CDF_TOLE4(shp->sh_properties); DPRINTF(("section len: %d properties %d\n", sh.sh_len, sh.sh_properties)); + if (sh.sh_properties > (UINT32_MAX / sizeof(*inp)) - *maxcount) + goto out; if (*maxcount) { *maxcount += sh.sh_properties; inp = realloc(*info, *maxcount * sizeof(*inp)); @@ -683,6 +693,8 @@ case CDF_LENGTH32_STRING: if (nelements > 1) { size_t nelem = inp - *info; + if (*maxcount > (UINT32_MAX / sizeof(*inp)) - nelements) + goto out; *maxcount += nelements; inp = realloc(*info, *maxcount * sizeof(*inp)); if (inp == NULL) @@ -723,6 +735,7 @@ return 0; out: free(*info); + *info = NULL; return -1; } @@ -960,6 +973,7 @@ } cdf_dump_stream(h, &scn); free(scn.sst_tab); + scn.sst_tab = NULL; break; default: break;