[Bf-blender-cvs] [8dbd5ea4c8a] blender-v2.79a-release: Fix buffer overflow vulnerability in curve, font, particles code.

Brecht Van Lommel noreply at git.blender.org
Thu Jan 18 19:39:02 CET 2018


Commit: 8dbd5ea4c8af218de60cab4de72624b1bb753363
Author: Brecht Van Lommel
Date:   Mon Jan 15 06:57:26 2018 +0100
Branches: blender-v2.79a-release
https://developer.blender.org/rB8dbd5ea4c8af218de60cab4de72624b1bb753363

Fix buffer overflow vulnerability in curve, font, particles code.

Solves these security issues from T52924:
CVE-2017-12102
CVE-2017-12103
CVE-2017-12104

While the specific overflow issue may be fixed, loading the repro .blend
files may still crash because they are incomplete and corrupt. The way
they crash may be impossible to exploit, but this is difficult to prove.

Differential Revision: https://developer.blender.org/D3002

===================================================================

M	source/blender/blenkernel/BKE_particle.h
M	source/blender/blenkernel/intern/curve.c
M	source/blender/blenkernel/intern/font.c
M	source/blender/blenkernel/intern/particle.c
M	source/blender/blenloader/intern/readfile.c
M	source/blender/editors/space_view3d/drawobject.c
M	source/blender/makesdna/DNA_curve_types.h

===================================================================

diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h
index 470e2e468f0..1a7f87a09d4 100644
--- a/source/blender/blenkernel/BKE_particle.h
+++ b/source/blender/blenkernel/BKE_particle.h
@@ -243,7 +243,8 @@ typedef struct ParticleDrawData {
 	float *cdata, *cd;      /* color data */
 	float *vedata, *ved;    /* velocity data */
 	float *ma_col;
-	int tot_vec_size, flag;
+	int totpart, partsize;
+	int flag;
 	int totpoint, totve;
 } ParticleDrawData;
 
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index 9fb4fc72f3c..d80f5fc6ee1 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -2686,7 +2686,8 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render)
 		/* check we are a single point? also check we are not a surface and that the orderu is sane,
 		 * enforced in the UI but can go wrong possibly */
 		if (!BKE_nurb_check_valid_u(nu)) {
-			bl = MEM_callocN(sizeof(BevList) + 1 * sizeof(BevPoint), "makeBevelList1");
+			bl = MEM_callocN(sizeof(BevList), "makeBevelList1");
+			bl->bevpoints = MEM_calloc_arrayN(1, sizeof(BevPoint), "makeBevelPoints1");
 			BLI_addtail(bev, bl);
 			bl->nr = 0;
 			bl->charidx = nu->charidx;
@@ -2703,7 +2704,8 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render)
 
 			if (nu->type == CU_POLY) {
 				len = nu->pntsu;
-				bl = MEM_callocN(sizeof(BevList) + len * sizeof(BevPoint), "makeBevelList2");
+				bl = MEM_callocN(sizeof(BevList), "makeBevelList2");
+				bl->bevpoints = MEM_calloc_arrayN(len, sizeof(BevPoint), "makeBevelPoints2");
 				if (need_seglen && (nu->flagu & CU_NURB_CYCLIC) == 0) {
 					bl->seglen = MEM_malloc_arrayN(segcount, sizeof(float), "makeBevelList2_seglen");
 					bl->segbevcount = MEM_malloc_arrayN(segcount, sizeof(int), "makeBevelList2_segbevcount");
@@ -2749,7 +2751,8 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render)
 				/* in case last point is not cyclic */
 				len = segcount * resolu + 1;
 
-				bl = MEM_callocN(sizeof(BevList) + len * sizeof(BevPoint), "makeBevelBPoints");
+				bl = MEM_callocN(sizeof(BevList), "makeBevelBPoints");
+				bl->bevpoints = MEM_calloc_arrayN(len, sizeof(BevPoint), "makeBevelBPointsPoints");
 				if (need_seglen && (nu->flagu & CU_NURB_CYCLIC) == 0) {
 					bl->seglen = MEM_malloc_arrayN(segcount, sizeof(float), "makeBevelBPoints_seglen");
 					bl->segbevcount = MEM_malloc_arrayN(segcount, sizeof(int), "makeBevelBPoints_segbevcount");
@@ -2885,7 +2888,8 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render)
 				if (nu->pntsv == 1) {
 					len = (resolu * segcount);
 
-					bl = MEM_callocN(sizeof(BevList) + len * sizeof(BevPoint), "makeBevelList3");
+					bl = MEM_callocN(sizeof(BevList), "makeBevelList3");
+					bl->bevpoints = MEM_calloc_arrayN(len, sizeof(BevPoint), "makeBevelPoints3");
 					if (need_seglen && (nu->flagu & CU_NURB_CYCLIC) == 0) {
 						bl->seglen = MEM_malloc_arrayN(segcount, sizeof(float), "makeBevelList3_seglen");
 						bl->segbevcount = MEM_malloc_arrayN(segcount, sizeof(int), "makeBevelList3_segbevcount");
@@ -2983,8 +2987,13 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render)
 		blnext = bl->next;
 		if (bl->nr && bl->dupe_nr) {
 			nr = bl->nr - bl->dupe_nr + 1;  /* +1 because vectorbezier sets flag too */
-			blnew = MEM_mallocN(sizeof(BevList) + nr * sizeof(BevPoint), "makeBevelList4");
+			blnew = MEM_callocN(sizeof(BevList), "makeBevelList4");
 			memcpy(blnew, bl, sizeof(BevList));
+			blnew->bevpoints = MEM_calloc_arrayN(nr, sizeof(BevPoint), "makeBevelPoints4");
+			if (!blnew->bevpoints) {
+				MEM_freeN(blnew);
+				break;
+			}
 			blnew->segbevcount = bl->segbevcount;
 			blnew->seglen = bl->seglen;
 			blnew->nr = 0;
@@ -3001,6 +3010,9 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render)
 				}
 				bevp0++;
 			}
+			if (bl->bevpoints != NULL) {
+				MEM_freeN(bl->bevpoints);
+			}
 			MEM_freeN(bl);
 			blnew->dupe_nr = 0;
 		}
diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c
index 0f309fcfa77..bad73bc8910 100644
--- a/source/blender/blenkernel/intern/font.c
+++ b/source/blender/blenkernel/intern/font.c
@@ -677,6 +677,9 @@ bool BKE_vfont_to_curve_ex(Main *bmain, Object *ob, int mode, ListBase *r_nubase
 
 		/* Create unicode string */
 		mem_tmp = MEM_malloc_arrayN((slen + 1), sizeof(wchar_t), "convertedmem");
+		if (!mem_tmp) {
+			return ok;
+		}
 
 		BLI_strncpy_wchar_from_utf8(mem_tmp, cu->str, slen + 1);
 
@@ -684,6 +687,9 @@ bool BKE_vfont_to_curve_ex(Main *bmain, Object *ob, int mode, ListBase *r_nubase
 			cu->strinfo = MEM_calloc_arrayN((slen + 4), sizeof(CharInfo), "strinfo compat");
 		}
 		custrinfo = cu->strinfo;
+		if (!custrinfo) {
+			return ok;
+		}
 
 		mem = mem_tmp;
 	}
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index c18cca41f77..7a0e8a3578c 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -548,7 +548,8 @@ void psys_free_pdd(ParticleSystem *psys)
 		psys->pdd->vedata = NULL;
 
 		psys->pdd->totpoint = 0;
-		psys->pdd->tot_vec_size = 0;
+		psys->pdd->totpart = 0;
+		psys->pdd->partsize = 0;
 	}
 }
 /* free everything */
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 4d16787e36b..f440ccad68d 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -3844,6 +3844,9 @@ static void direct_link_curve(FileData *fd, Curve *cu)
 	cu->adt= newdataadr(fd, cu->adt);
 	direct_link_animdata(fd, cu->adt);
 	
+	/* Protect against integer overflow vulnerability. */
+	CLAMP(cu->len_wchar, 0, INT_MAX - 4);
+
 	cu->mat = newdataadr(fd, cu->mat);
 	test_pointer_array(fd, (void **)&cu->mat);
 	cu->str = newdataadr(fd, cu->str);
@@ -4258,6 +4261,9 @@ static void direct_link_particlesettings(FileData *fd, ParticleSettings *part)
 	for (a = 0; a < MAX_MTEX; a++) {
 		part->mtex[a] = newdataadr(fd, part->mtex[a]);
 	}
+
+	/* Protect against integer overflow vulnerability. */
+	CLAMP(part->trail_count, 1, 100000);
 }
 
 static void lib_link_particlesystems(FileData *fd, Object *ob, ID *id, ListBase *particles)
@@ -8207,7 +8213,7 @@ static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, const short
 	id = read_struct(fd, bhead, "lib block");
 
 	if (id) {
-		const short idcode = (bhead->code == ID_ID) ? GS(id->name) : bhead->code;
+		const short idcode = GS(id->name);
 		/* do after read_struct, for dna reconstruct */
 		lb = which_libbase(main, idcode);
 		if (lb) {
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index 9624ef42783..5ccd3dca68c 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -5190,46 +5190,46 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
 
 /* 4. */
 	if (draw_as && ELEM(draw_as, PART_DRAW_PATH, PART_DRAW_CIRC) == 0) {
-		int tot_vec_size = (totpart + totchild) * 3 * sizeof(float);
+		int partsize = 3 * sizeof(float);
 		int create_ndata = 0;
 
 		if (!pdd)
 			pdd = psys->pdd = MEM_callocN(sizeof(ParticleDrawData), "ParticleDrawData");
 
 		if (part->draw_as == PART_DRAW_REND && part->trail_count > 1) {
-			tot_vec_size *= part->trail_count;
+			partsize *= part->trail_count;
 			psys_make_temp_pointcache(ob, psys);
 		}
 
 		switch (draw_as) {
 			case PART_DRAW_AXIS:
 			case PART_DRAW_CROSS:
-				tot_vec_size *= 6;
+				partsize *= 6;
 				if (draw_as != PART_DRAW_CROSS)
 					create_cdata = 1;
 				break;
 			case PART_DRAW_LINE:
-				tot_vec_size *= 2;
+				partsize *= 2;
 				break;
 			case PART_DRAW_BB:
-				tot_vec_size *= 4;
+				partsize *= 4;
 				create_ndata = 1;
 				break;
 		}
 
-		if (pdd->tot_vec_size != tot_vec_size)
+		if (pdd->totpart != totpart + totchild || pdd->partsize != partsize)
 			psys_free_pdd(psys);
 
 		if (!pdd->vdata)
-			pdd->vdata = MEM_callocN(tot_vec_size, "particle_vdata");
+			pdd->vdata = MEM_calloc_arrayN(totpart + totchild, partsize, "particle_vdata");
 		if (create_cdata && !pdd->cdata)
-			pdd->cdata = MEM_callocN(tot_vec_size, "particle_cdata");
+			pdd->cdata = MEM_calloc_arrayN(totpart + totchild, partsize, "particle_cdata");
 		if (create_ndata && !pdd->ndata)
-			pdd->ndata = MEM_callocN(tot_vec_size, "particle_ndata");
+			pdd->ndata = MEM_calloc_arrayN(totpart + totchild, partsize, "particle_ndata");
 
 		if (part->draw & PART_DRAW_VEL && draw_as != PART_DRAW_LINE) {
 			if (!pdd->vedata)
-				pdd->vedata = MEM_callocN(2 * (totpart + totchild) * 3 * sizeof(float), "particle_vedata");
+				pdd->vedata = MEM_calloc_arrayN(totpart + totchild, 2 * 3 * sizeof(float), "particle_vedata");
 
 			need_v = 1;
 		}
@@ -5243,7 +5243,8 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
 		pdd->ved = pdd->vedata;
 		pdd->cd = pdd->cdata;
 		pdd->nd = pdd->ndata;
-		pdd->tot_vec_size = tot_vec_size;
+		pdd->totpart = totpart + totchild;
+		pdd->partsize = partsize;
 	}
 	else if (psys->pdd) {
 		psys_free_pdd(psys);
diff --git a/source/blender/makesdna/DNA_curve_types.h b/source/blender/makesdna/DNA_curve_types.h
index 902fa4ce987..1a364742dfd 100644
--- a/source/blender/makesdna/DNA_curve_types.h
+++ b/source/blender/makesdna/DNA_curve_types.h
@@ -87,9 +87,7 @@ typedef struct BevList {
 	int charidx;
 	int *segbevcount;
 	float *seglen;
-
-	/* over-alloc */
-	BevPoint bevpoints[0];
+	BevPoint *bevpoints;
 } BevList;
 
 /**



More information about the Bf-blender-cvs mailing list