Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@gmail.com>2018-01-15 08:57:26 +0300
committerBrecht Van Lommel <brechtvanlommel@gmail.com>2018-01-18 02:54:07 +0300
commite6df02861e17f75d4dd243776f35208681b78465 (patch)
treeb4ebbb1f9752f3cab8ada017f40d91172971915a
parente04d7c49dca9dc7bbf1cbe446b612aaa5ba12581 (diff)
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
-rw-r--r--source/blender/blenkernel/BKE_particle.h3
-rw-r--r--source/blender/blenkernel/intern/curve.c26
-rw-r--r--source/blender/blenkernel/intern/font.c6
-rw-r--r--source/blender/blenkernel/intern/particle.c3
-rw-r--r--source/blender/blenloader/intern/readfile.c8
-rw-r--r--source/blender/editors/space_view3d/drawobject.c23
-rw-r--r--source/blender/makesdna/DNA_curve_types.h4
7 files changed, 49 insertions, 24 deletions
diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h
index b43d000ed35..2c72373c2a9 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 91fe44e4d54..1a744ddaf03 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -2687,7 +2687,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;
@@ -2704,7 +2705,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");
@@ -2750,7 +2752,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");
@@ -2886,7 +2889,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");
@@ -2984,8 +2988,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;
@@ -3002,6 +3011,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;
}
@@ -3440,7 +3452,7 @@ static void calchandlesNurb_intern(Nurb *nu, bool skip_align)
*/
static void *allocate_arrays(int count, float ***floats, char ***chars, const char *name)
{
- int num_floats = 0, num_chars = 0;
+ size_t num_floats = 0, num_chars = 0;
while (floats && floats[num_floats]) {
num_floats++;
@@ -3450,7 +3462,7 @@ static void *allocate_arrays(int count, float ***floats, char ***chars, const ch
num_chars++;
}
- void *buffer = (float *)MEM_mallocN(count * (sizeof(float) * num_floats + num_chars), name);
+ void *buffer = (float *)MEM_malloc_arrayN(count, (sizeof(float) * num_floats + num_chars), name);
if (!buffer)
return NULL;
diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c
index 7c4185616ac..a314cc0a131 100644
--- a/source/blender/blenkernel/intern/font.c
+++ b/source/blender/blenkernel/intern/font.c
@@ -693,6 +693,9 @@ bool BKE_vfont_to_curve_ex(Main *bmain, Object *ob, Curve *cu, int mode, ListBas
/* 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);
@@ -700,6 +703,9 @@ bool BKE_vfont_to_curve_ex(Main *bmain, Object *ob, Curve *cu, int mode, ListBas
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 8b3910c1d53..c0849e6bff4 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 8edaf071f36..39f83062401 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -3859,6 +3859,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);
@@ -4273,6 +4276,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)
@@ -8193,7 +8199,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 92faf743adf..83fb5f9df0e 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -5188,46 +5188,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;
}
@@ -5241,7 +5241,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 2207b0ec0b1..6a95865c11f 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;
/**