From 32fd85e6f995e3478c94c5c9eededbd3c325e15a Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Thu, 12 May 2022 17:19:22 +0200 Subject: Fix (unreported) bad memory access in read/write code of MeshDeform modifier. This abuse of one one size value to handle another allocated array of a different size is bad in itself, but at least now read/write code of this modifier should not risk invalid memory access anymore. NOTE: invalid memory access would in practice only happen in case endian switch would be performed at read time I think (those switches only check for given length being non-zero, not for a NULL data pointer...). --- source/blender/modifiers/intern/MOD_meshdeform.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) (limited to 'source/blender/modifiers') diff --git a/source/blender/modifiers/intern/MOD_meshdeform.c b/source/blender/modifiers/intern/MOD_meshdeform.c index 09e6819a2ae..c2e9e5ebe7d 100644 --- a/source/blender/modifiers/intern/MOD_meshdeform.c +++ b/source/blender/modifiers/intern/MOD_meshdeform.c @@ -587,7 +587,16 @@ static void blendWrite(BlendWriter *writer, const ModifierData *md) int size = mmd->dyngridsize; BLO_write_struct_array(writer, MDefInfluence, mmd->influences_num, mmd->bindinfluences); - BLO_write_int32_array(writer, mmd->verts_num + 1, mmd->bindoffsets); + + /* NOTE: `bindoffset` is abusing `verts_num + 1` as its size, this becomes an incorrect value in + * case `verts_num == 0`, since `bindoffset` is then NULL, not a size 1 allocated array. */ + if (mmd->verts_num > 0) { + BLO_write_int32_array(writer, mmd->verts_num + 1, mmd->bindoffsets); + } + else { + BLI_assert(mmd->bindoffsets == NULL); + } + BLO_write_float3_array(writer, mmd->cage_verts_num, mmd->bindcagecos); BLO_write_struct_array(writer, MDefCell, size * size * size, mmd->dyngrid); BLO_write_struct_array(writer, MDefInfluence, mmd->influences_num, mmd->dyninfluences); @@ -599,7 +608,13 @@ static void blendRead(BlendDataReader *reader, ModifierData *md) MeshDeformModifierData *mmd = (MeshDeformModifierData *)md; BLO_read_data_address(reader, &mmd->bindinfluences); - BLO_read_int32_array(reader, mmd->verts_num + 1, &mmd->bindoffsets); + + /* NOTE: `bindoffset` is abusing `verts_num + 1` as its size, this becomes an incorrect value in + * case `verts_num == 0`, since `bindoffset` is then NULL, not a size 1 allocated array. */ + if (mmd->verts_num > 0) { + BLO_read_int32_array(reader, mmd->verts_num + 1, &mmd->bindoffsets); + } + BLO_read_float3_array(reader, mmd->cage_verts_num, &mmd->bindcagecos); BLO_read_data_address(reader, &mmd->dyngrid); BLO_read_data_address(reader, &mmd->dyninfluences); -- cgit v1.2.3