cdf.c.diff   [plain text]


--- 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;