Changeset View
Changeset View
Standalone View
Standalone View
source/blender/makesrna/intern/rna_access.c
| Context not available. | |||||
| PropertyRNA *parm; | PropertyRNA *parm; | ||||
| PointerRNA null_ptr = PointerRNA_NULL; | PointerRNA null_ptr = PointerRNA_NULL; | ||||
| void *data; | void *data; | ||||
| int alloc_size = 0, size; | int alloc_size = 0, alignment = 1, item_alignment, size; | ||||
| parms->arg_count = 0; | parms->arg_count = 0; | ||||
| parms->ret_count = 0; | parms->ret_count = 0; | ||||
| /* allocate data */ | /* allocate data */ | ||||
| for (parm = func->cont.properties.first; parm; parm = parm->next) { | for (parm = func->cont.properties.first; parm; parm = parm->next) { | ||||
| alloc_size += rna_parameter_size(parm); | item_alignment = rna_parameter_alignment(parm); | ||||
| if (item_alignment > alignment) { | |||||
| alignment = item_alignment; | |||||
| } | |||||
| alloc_size += rna_aligned_parameter_size(alloc_size, parm, parm->next); | |||||
| if (parm->flag_parameter & PARM_OUTPUT) { | if (parm->flag_parameter & PARM_OUTPUT) { | ||||
| parms->ret_count++; | parms->ret_count++; | ||||
| Context not available. | |||||
| } | } | ||||
| } | } | ||||
| parms->data = MEM_callocN(alloc_size, "RNA_parameter_list_create"); | /* MEM_mallocN_aligned should be able to handle alignment == 1 also, but | ||||
| * this should ensure old behavior is maintained when no additional | |||||
| * alignment is required */ | |||||
| if (alignment > 1) { | |||||
| parms->data = MEM_mallocN_aligned(alloc_size, alignment, "RNA_parameter_list_create"); | |||||
| } | |||||
| else { | |||||
| parms->data = MEM_callocN(alloc_size, "RNA_parameter_list_create"); | |||||
| } | |||||
brecht: `MEM_mallocN_aligned` should be unnecessary, we're not using that for every struct allocation… | |||||
linux_drAuthorUnsubmitted Done Inline ActionsSince then I learned that all malloc Allocations default to alignof(std::max_align_t) (which is intended to be sizeof(void*)), which means explicitly aligned allocations should only be necessary for weird types used for things like SSE instructions. I will update this in my next revision linux_dr: Since then I learned that all `malloc` Allocations default to `alignof(std::max_align_t)`… | |||||
| parms->func = func; | parms->func = func; | ||||
| parms->alloc_size = alloc_size; | parms->alloc_size = alloc_size; | ||||
| Context not available. | |||||
| data = parms->data; | data = parms->data; | ||||
| for (parm = func->cont.properties.first; parm; parm = parm->next) { | for (parm = func->cont.properties.first; parm; parm = parm->next) { | ||||
| size = rna_parameter_size(parm); | size = rna_aligned_parameter_size(alloc_size, parm, parm->next); | ||||
linux_drAuthorUnsubmitted Done Inline ActionsTHIS IS THE SOURCE OF THE POSSIBLE MEMORY CORRUPTION: This size can later be used for memcpy()s which can read off the end of memory, or worse, write over the end of memory. linux_dr: **THIS IS THE SOURCE OF THE POSSIBLE MEMORY CORRUPTION**:
This `size` can later be used for… | |||||
| /* set length to 0, these need to be set later, see bpy_array.c's py_to_array */ | /* set length to 0, these need to be set later, see bpy_array.c's py_to_array */ | ||||
| if (parm->flag & PROP_DYNAMIC) { | if (parm->flag & PROP_DYNAMIC) { | ||||
| Context not available. | |||||
| } | } | ||||
| } | } | ||||
| data = ((char *)data) + rna_parameter_size(parm); | data = ((char *)data) + rna_aligned_parameter_size(alloc_size, parm, parm->next); | ||||
| } | } | ||||
| return parms; | return parms; | ||||
| Context not available. | |||||
| } | } | ||||
| } | } | ||||
| tot += rna_parameter_size(parm); | tot += rna_aligned_parameter_size(tot, parm, parm->next); | ||||
| } | } | ||||
| MEM_freeN(parms->data); | MEM_freeN(parms->data); | ||||
| Context not available. | |||||
| iter->offset = 0; | iter->offset = 0; | ||||
| if (iter->valid) { | if (iter->valid) { | ||||
| iter->size = rna_parameter_size(iter->parm); | iter->size = rna_aligned_parameter_size(iter->offset, iter->parm, iter->parm->next); | ||||
linux_drAuthorUnsubmitted Done Inline Actions(memory corruption)...and here linux_dr: (**memory corruption**)...and here | |||||
brechtUnsubmitted Done Inline ActionsI don't think changing the size here makes sense. It should be modifying only the offset. brecht: I don't think changing the size here makes sense. It should be modifying only the offset. | |||||
| iter->data = (((char *)iter->parms->data)); /* +iter->offset, always 0 */ | iter->data = (((char *)iter->parms->data)); /* +iter->offset, always 0 */ | ||||
| } | } | ||||
| } | } | ||||
| Context not available. | |||||
| iter->valid = iter->parm != NULL; | iter->valid = iter->parm != NULL; | ||||
| if (iter->valid) { | if (iter->valid) { | ||||
| iter->size = rna_parameter_size(iter->parm); | iter->size = rna_aligned_parameter_size(iter->offset, iter->parm, iter->parm->next); | ||||
linux_drAuthorUnsubmitted Done Inline Actions(memory corruption)...and here linux_dr: (**memory corruption**)...and here | |||||
brechtUnsubmitted Done Inline ActionsSame comment. brecht: Same comment. | |||||
| iter->data = (((char *)iter->parms->data) + iter->offset); | iter->data = (((char *)iter->parms->data) + iter->offset); | ||||
| } | } | ||||
| } | } | ||||
| Context not available. | |||||
MEM_mallocN_aligned should be unnecessary, we're not using that for every struct allocation that may contain arbitrary types, and this is no different as far as I can tell.