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
This commit is contained in:
parent
9287434fa1
commit
8dbd5ea4c8
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -87,9 +87,7 @@ typedef struct BevList {
|
|||
int charidx;
|
||||
int *segbevcount;
|
||||
float *seglen;
|
||||
|
||||
/* over-alloc */
|
||||
BevPoint bevpoints[0];
|
||||
BevPoint *bevpoints;
|
||||
} BevList;
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue