From dead11cdd0c282cb0bbc01d008a04d47dda2efd0 Mon Sep 17 00:00:00 2001 From: Zoltan Herczeg Date: Tue, 20 Apr 2021 11:53:58 +0200 Subject: [PATCH] Fix external pointer allocation issues. (#4658) The allocations during the update of external pointers may trigger the GC. Due to a new feature, the GC uses the external pointer data to mark objects, which caused crashes in some cases. JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com --- .../base/ecma-helpers-external-pointers.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/jerry-core/ecma/base/ecma-helpers-external-pointers.c b/jerry-core/ecma/base/ecma-helpers-external-pointers.c index eed24897b..233722194 100644 --- a/jerry-core/ecma/base/ecma-helpers-external-pointers.c +++ b/jerry-core/ecma/base/ecma-helpers-external-pointers.c @@ -58,12 +58,12 @@ ecma_create_native_pointer_property (ecma_object_t *obj_p, /**< object to create if (property_p == NULL) { + native_pointer_p = (ecma_native_pointer_t *) jmem_heap_alloc_block (sizeof (ecma_native_pointer_t)); + ecma_property_value_t *value_p; ECMA_CREATE_INTERNAL_PROPERTY (obj_p, name_p, property_p, value_p); - native_pointer_p = (ecma_native_pointer_t *) jmem_heap_alloc_block (sizeof (ecma_native_pointer_t)); ECMA_SET_INTERNAL_VALUE_POINTER (value_p->value, native_pointer_p); - *property_p |= ECMA_PROPERTY_FLAG_SINGLE_EXTERNAL; } else if (*property_p & ECMA_PROPERTY_FLAG_SINGLE_EXTERNAL) @@ -78,6 +78,10 @@ ecma_create_native_pointer_property (ecma_object_t *obj_p, /**< object to create return false; } + value_p->value = JMEM_CP_NULL; + (void) value_p->value; /* Make cppcheck happy. */ + *property_p &= (ecma_property_t) ~ECMA_PROPERTY_FLAG_SINGLE_EXTERNAL; + ecma_native_pointer_chain_t *item_p; item_p = (ecma_native_pointer_chain_t *) jmem_heap_alloc_block (sizeof (ecma_native_pointer_chain_t)); item_p->data = *native_pointer_p; @@ -88,7 +92,6 @@ ecma_create_native_pointer_property (ecma_object_t *obj_p, /**< object to create item_p->next_p->next_p = NULL; native_pointer_p = &item_p->next_p->data; - *property_p &= (ecma_property_t) ~ECMA_PROPERTY_FLAG_SINGLE_EXTERNAL; ECMA_SET_INTERNAL_VALUE_POINTER (value_p->value, item_p); } else @@ -307,15 +310,17 @@ ecma_delete_native_pointer_property (ecma_object_t *obj_p, /**< object to delete return true; } - /* Only one item remained. */ + /* Only one item remained. The ECMA_PROPERTY_FLAG_SINGLE_EXTERNAL flag is + * set early to avoid using the chain if the allocation below triggers a GC. */ + *property_p |= ECMA_PROPERTY_FLAG_SINGLE_EXTERNAL; + ecma_native_pointer_t *native_pointer_p; native_pointer_p = (ecma_native_pointer_t *) jmem_heap_alloc_block (sizeof (ecma_native_pointer_t)); *native_pointer_p = first_p->data; - jmem_heap_free_block (first_p, sizeof (ecma_native_pointer_chain_t)); - ECMA_SET_INTERNAL_VALUE_POINTER (value_p->value, native_pointer_p); - *property_p |= ECMA_PROPERTY_FLAG_SINGLE_EXTERNAL; + + jmem_heap_free_block (first_p, sizeof (ecma_native_pointer_chain_t)); return true; }