From fdfa49e52fdc2d1486b2065d8e5419ea5641963a Mon Sep 17 00:00:00 2001 From: dipinhora Date: Mon, 13 Nov 2017 18:25:22 -0500 Subject: [PATCH] Fix small chunk finaliser premature re-use bug Prior to this commit, if a small chunk was partially used after GC and had finalisers to be run for the freed slots, the execution of the finaliser could end up reusing the slots for which finalisers were being run. If this occurred, it would lead to unpredictable results (a segfault in my case). This commit changes the order of operations to ensure that all the finalisers are run prior to the chunk being added back to the available list ensuring that the execution of the finaliser cannot allocate slots that are still to be finalised. --- src/libponyrt/mem/heap.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/libponyrt/mem/heap.c b/src/libponyrt/mem/heap.c index b0db7a000a..0a97447857 100644 --- a/src/libponyrt/mem/heap.c +++ b/src/libponyrt/mem/heap.c @@ -184,11 +184,15 @@ static size_t sweep_small(chunk_t* chunk, chunk_t** avail, chunk_t** full, } else { used += sizeof(block_t) - (__pony_popcount(chunk->slots) * size); - chunk->next = *avail; - *avail = chunk; // run finalisers for freed slots final_small_freed(chunk); + + // make chunk available for allocations only after finalisers have been + // run to prevent premature reuse of memory slots by an allocation + // required for finaliser execution + chunk->next = *avail; + *avail = chunk; } chunk = next;