Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Security: NULL word of bytecode.literal lead to heap memory corruption results in OOB write. #2008

Closed
dwfault opened this issue Sep 7, 2017 · 2 comments
Labels
bug Undesired behaviour

Comments

@dwfault
Copy link

dwfault commented Sep 7, 2017

PoC and Crash in release 1.0.0

Assigned as CVE-2017-14749, Credit by ADLab of Venustech
PoC.js is as follows(hex displayed):

00000000: 275c 0a27 2b27 3035 3627 3b0a            '\.'+'056';.

Among the first string, there is a '\n'(0x0a). This byte could be replaced by '\r'(0x0d) or other bytes as with a '\' at front. And this kind of bytes makes the generated byte code contains an NULL word(0x00), which lead to a crash as the following stack trace shows:

#0  jmem_heap_alloc_block_internal (size=size@entry=0xb) at /home/default/Desktop/jerryscript-jerryscript-release-1.0.0/jerry-core/jmem/jmem-heap.c:250
#1  0x08051dcd in jmem_heap_gc_and_alloc_block (size=size@entry=0xb, ret_null_on_error=ret_null_on_error@entry=0x0)
    at /home/default/Desktop/jerryscript-jerryscript-release-1.0.0/jerry-core/jmem/jmem-heap.c:346
#2  0x08059096 in jmem_heap_alloc_block (size=0xb) at /home/default/Desktop/jerryscript-jerryscript-release-1.0.0/jerry-core/jmem/jmem-heap.c:392
#3  ecma_concat_ecma_strings (string1_p=0x82899c0 <jerry_global_heap>, string2_p=0x8289b08 <jerry_global_heap+328>)
    at /home/default/Desktop/jerryscript-jerryscript-release-1.0.0/jerry-core/ecma/base/ecma-helpers-string.c:459
#4  0x0806597a in opfunc_addition (left_value=0x82899c2, right_value=0x8289b0a)
    at /home/default/Desktop/jerryscript-jerryscript-release-1.0.0/jerry-core/vm/opcodes-ecma-arithmetics.c:142
#5  0x08073d95 in vm_loop (frame_ctx_p=frame_ctx_p@entry=0xffffcce8)
    at /home/default/Desktop/jerryscript-jerryscript-release-1.0.0/jerry-core/vm/vm.c:1641
#6  0x08074c48 in vm_execute (frame_ctx_p=frame_ctx_p@entry=0xffffcce8, arg_p=<optimized out>, arg_list_len=<optimized out>)
    at /home/default/Desktop/jerryscript-jerryscript-release-1.0.0/jerry-core/vm/vm.c:2579
#7  0x08074e67 in vm_run_with_inline_stack (frame_ctx_p=frame_ctx_p@entry=0xffffcce8, arg_p=<optimized out>, arg_list_len=<optimized out>)
    at /home/default/Desktop/jerryscript-jerryscript-release-1.0.0/jerry-core/vm/vm.c:2624
#8  0x08074f13 in vm_run (bytecode_header_p=0x8289b48 <jerry_global_heap+392>, this_binding_value=0x82899db, 
    lex_env_p=0x82899e8 <jerry_global_heap+40>, is_eval_code=0x0, arg_list_p=0x0, arg_list_len=0x0)
    at /home/default/Desktop/jerryscript-jerryscript-release-1.0.0/jerry-core/vm/vm.c:2696
#9  0x08074f58 in vm_run_global (bytecode_p=0x8289b48 <jerry_global_heap+392>)
    at /home/default/Desktop/jerryscript-jerryscript-release-1.0.0/jerry-core/vm/vm.c:208
#10 0x08074fa5 in jerry_run (func_val=<optimized out>) at /home/default/Desktop/jerryscript-jerryscript-release-1.0.0/jerry-core/jerry.c:355
#11 0x08048d82 in main (argc=0x2, argv=0xffffd064) at /home/default/Desktop/jerryscript-jerryscript-release-1.0.0/jerry-main/main-unix.c:396
#12 0xf7e16637 in __libc_start_main (main=0x80487cf <main>, argc=0x2, argv=0xffffd064, init=0x8079360 <__libc_csu_init>, 
    fini=0x80793c0 <__libc_csu_fini>, rtld_fini=0xf7fe88a0 <_dl_fini>, stack_end=0xffffd05c) at ../csu/libc-start.c:291
#13 0x0804912d in _start ()

Root cause

When processing the strings, the generated byte code are as follows:

b vm.c:669 
668    uint8_t *byte_code_p = frame_ctx_p->byte_code_p;
669    jmem_cpointer_t *literal_start_p = frame_ctx_p->literal_start_p;
crash:
08289b54     [00 00 29 00] 86 00 01 08 46 00 00 00 ff ff ff ff
08289b64     60 fe 07 00 00 00 00 00 00 00 00 00 00 00 00 00
08289b74     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
08289b84     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
normal:
08289b6c     [32 00 29 00] 86 00 01 08 46 00 00 00 ff ff ff ff
08289b7c     48 fe 07 00 00 00 00 00 00 00 00 00 00 00 00 00
08289b8c     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
08289b9c     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

The NULL word in 0x00290000 is one of the bytecode.literal compressed pointer. When bytecode is executed, the reference of the literal add 0x10 while jerry_global_heap.next_offset was overwritten because of the compressed pointer. Twice as it was referenced so the field was added up to 0x20. This makes the index of the free chunk lists corrupts.

Potential Risks

With the heap memory corruption the free chunk lists could be faked. Potentially there exists an local write primitive in memory. If jerry is embedded in some host and could execute js, this vulnerability could result in remote code execution.

Fix Suggestion

Check code in bytecode generation: the failed literal's compressed pointer should not be NULL word.

@LaszloLango LaszloLango added the bug Undesired behaviour label Sep 7, 2017
@akosthekiss
Copy link
Member

Thanks for reporting. v1.0 is quite old though (dated Sep 2016). The bug is not reproducible on latest master anymore.

$ git checkout v1.0
HEAD is now at 63f739e5... Add documentation to port API
$ tools/build.py --clean --debug
==============================
Build succeeded!
==============================
$ ./build/bin/jerry issue-2008.js 
ICE: Assertion 'compressed_pointer != JMEM_CP_NULL' failed at jerry-core/jmem/jmem-heap.c(jmem_heap_decompress_pointer):557.
Error: ERR_FAILED_INTERNAL_ASSERTION

$ git checkout master 
$ git branch -vv | grep master
* master                       d9cc3fd4 [origin/master] Improve runtime by concatenation of opcodes. (#2059)
$ tools/build.py --clean --debug
==============================
Build succeeded!
==============================
$ ./build/bin/jerry issue-2008.js 
$ 

akosthekiss added a commit to akosthekiss/jerryscript that referenced this issue Oct 30, 2017
The issue was reported against v1.0 and isn't reproducible anymore.
Still, adding the then-faulty input to the regression test suite to
prevent it occuring again.

JerryScript-DCO-1.0-Signed-off-by: Akos Kiss akiss@inf.u-szeged.hu
dbatyai pushed a commit that referenced this issue Oct 30, 2017
The issue was reported against v1.0 and isn't reproducible anymore.
Still, adding the then-faulty input to the regression test suite to
prevent it occuring again.

JerryScript-DCO-1.0-Signed-off-by: Akos Kiss akiss@inf.u-szeged.hu
pmarcinkiew pushed a commit to pmarcinkiew/jerryscript that referenced this issue Oct 30, 2017
…project#2066)

The issue was reported against v1.0 and isn't reproducible anymore.
Still, adding the then-faulty input to the regression test suite to
prevent it occuring again.

JerryScript-DCO-1.0-Signed-off-by: Akos Kiss akiss@inf.u-szeged.hu
@akosthekiss
Copy link
Member

#2066 is merged, added the test case to the regression test suite. Fix was not needed (anymore). Closing.

pmarcinkiew pushed a commit to pmarcinkiew/jerryscript that referenced this issue Oct 31, 2017
…project#2066)

The issue was reported against v1.0 and isn't reproducible anymore.
Still, adding the then-faulty input to the regression test suite to
prevent it occuring again.

JerryScript-DCO-1.0-Signed-off-by: Akos Kiss akiss@inf.u-szeged.hu
pmarcinkiew pushed a commit to pmarcinkiew/jerryscript that referenced this issue Oct 31, 2017
…project#2066)

The issue was reported against v1.0 and isn't reproducible anymore.
Still, adding the then-faulty input to the regression test suite to
prevent it occuring again.

JerryScript-DCO-1.0-Signed-off-by: Akos Kiss akiss@inf.u-szeged.hu
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Undesired behaviour
Projects
None yet
Development

No branches or pull requests

3 participants