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

global-buffer-overflow in Escargot::InterpreterSlowPath::unaryTypeof #1333

Open
Ye0nny opened this issue Apr 7, 2024 · 0 comments
Open

global-buffer-overflow in Escargot::InterpreterSlowPath::unaryTypeof #1333

Ye0nny opened this issue Apr 7, 2024 · 0 comments
Labels
bug Something isn't working

Comments

@Ye0nny
Copy link

Ye0nny commented Apr 7, 2024

Escargot

  • OS: Ubuntu 20.04.5 LTS (Linux 5.4.0-144-generic x86_64)
  • Revision : 28451a7

Build Steps

cmake -DCMAKE_CXX_FLAGS=-fsanitize=address -DESCARGOT_MODE=debug -DESCARGOT_OUTPUT=shell -GNinja

Describe the bug
global-buffer-overflow
(sometimes detected memory leaks)

Test case

testcase

var r = [ " string ", 32, null, 1, undefined, Symbol ( " symbol " ), true, false ] ; 
var var0 = true ; 
for ( var e of r ) { 
	for ( let { func0 : n = f = typeof n, b : o = class o { },... t } of e ) 
		n = f ; 
	if ( n!== true ) 
		throw new Error ( " Error : " + n + " bad value : a = " + String. fromCharCode ( 65 + 65, n ) ) ; 
	Object. freeze ( e ) ; 
}

// poc.js
var r = [ " string " ] ; 
for ( var e of r ) { 
	for ( let { func0 : n = f = typeof n, b : o = class o { },... t } of e ) 
	Object. freeze ( e ) ; 
}

Execution steps & Output

$ ./escargot poc.js
=================================================================
==2069958==ERROR: AddressSanitizer: global-buffer-overflow on address 0x564dc5c45a90 at pc 0x564dc5035d0e bp 0x7ffeeff024b0 sp 0x7ffeeff024a0
READ of size 8 at 0x564dc5c45a90 thread T0
    #0 0x564dc5035d0d in Escargot::InterpreterSlowPath::unaryTypeof(Escargot::ExecutionState&, Escargot::UnaryTypeof*, Escargot::Value*) src/interpreter/ByteCodeInterpreter.cpp:4723
    #1 0x564dc50073de in Escargot::Interpreter::interpret(Escargot::ExecutionState*, Escargot::ByteCodeBlock*, unsigned long, Escargot::Value*) src/interpreter/ByteCodeInterpreter.cpp:1089
    #2 0x564dc501fe96 in Escargot::InterpreterSlowPath::tryOperation(Escargot::ExecutionState*&, unsigned long&, Escargot::ByteCodeBlock*, Escargot::Value*) src/interpreter/ByteCodeInterpreter.cpp:3303
    #3 0x564dc5007d29 in Escargot::Interpreter::interpret(Escargot::ExecutionState*, Escargot::ByteCodeBlock*, unsigned long, Escargot::Value*) src/interpreter/ByteCodeInterpreter.cpp:1254
    #4 0x564dc501fe96 in Escargot::InterpreterSlowPath::tryOperation(Escargot::ExecutionState*&, unsigned long&, Escargot::ByteCodeBlock*, Escargot::Value*) src/interpreter/ByteCodeInterpreter.cpp:3303
    #5 0x564dc5007d29 in Escargot::Interpreter::interpret(Escargot::ExecutionState*, Escargot::ByteCodeBlock*, unsigned long, Escargot::Value*) src/interpreter/ByteCodeInterpreter.cpp:1254
    #6 0x564dc51cd1bb in Escargot::Script::execute(Escargot::ExecutionState&, bool, bool) src/parser/Script.cpp:499
    #7 0x564dc4dbfc62 in Escargot::ScriptRef::execute(Escargot::ExecutionStateRef*) src/api/EscargotPublic.cpp:4715
    #8 0x564dc566103c in operator() src/shell/Shell.cpp:790
    #9 0x564dc5661067 in _FUN src/shell/Shell.cpp:791
    #10 0x564dc566ad3d in decltype (((forward<Escargot::ValueRef* (*&)(Escargot::ExecutionStateRef*, Escargot::ScriptRef*)>)({parm#1}))((forward<Escargot::ExecutionStateRef*&>)({parm#3}), (forward<Escargot::ScriptRef*&>)({parm#3}))) Escargot::EvaluatorUtil::ApplyTupleIntoArgumentsOfVariadicTemplateFunction<0ul>::apply<Escargot::ValueRef* (*&)(Escargot::ExecutionStateRef*, Escargot::ScriptRef*), std::tuple<Escargot::ExecutionStateRef*, Escargot::ScriptRef*>&, Escargot::ExecutionStateRef*&, Escargot::ScriptRef*&>(Escargot::ValueRef* (*&)(Escargot::ExecutionStateRef*, Escargot::ScriptRef*), std::tuple<Escargot::ExecutionStateRef*, Escargot::ScriptRef*>&, Escargot::ExecutionStateRef*&, Escargot::ScriptRef*&) src/api/EscargotPublic.h:521
    #11 0x564dc566a349 in decltype (Escargot::EvaluatorUtil::ApplyTupleIntoArgumentsOfVariadicTemplateFunction<0ul>::apply((forward<Escargot::ValueRef* (*&)(Escargot::ExecutionStateRef*, Escargot::ScriptRef*)>)({parm#1}), (forward<std::tuple<Escargot::ExecutionStateRef*, Escargot::ScriptRef*>&>)({parm#2}), (get<(1ul)-(1)>)((forward<std::tuple<Escargot::ExecutionStateRef*, Escargot::ScriptRef*>&>)({parm#2})), (forward<Escargot::ScriptRef*&>)({parm#3}))) Escargot::EvaluatorUtil::ApplyTupleIntoArgumentsOfVariadicTemplateFunction<1ul>::apply<Escargot::ValueRef* (*&)(Escargot::ExecutionStateRef*, Escargot::ScriptRef*), std::tuple<Escargot::ExecutionStateRef*, Escargot::ScriptRef*>&, Escargot::ScriptRef*&>(Escargot::ValueRef* (*&)(Escargot::ExecutionStateRef*, Escargot::ScriptRef*), std::tuple<Escargot::ExecutionStateRef*, Escargot::ScriptRef*>&, Escargot::ScriptRef*&) src/api/EscargotPublic.h:510
    #12 0x564dc56697a9 in decltype (Escargot::EvaluatorUtil::ApplyTupleIntoArgumentsOfVariadicTemplateFunction<1ul>::apply((forward<Escargot::ValueRef* (*&)(Escargot::ExecutionStateRef*, Escargot::ScriptRef*)>)({parm#1}), (forward<std::tuple<Escargot::ExecutionStateRef*, Escargot::ScriptRef*>&>)({parm#2}), (get<(2ul)-(1)>)((forward<std::tuple<Escargot::ExecutionStateRef*, Escargot::ScriptRef*>&>)({parm#2})))) Escargot::EvaluatorUtil::ApplyTupleIntoArgumentsOfVariadicTemplateFunction<2ul>::apply<Escargot::ValueRef* (*&)(Escargot::ExecutionStateRef*, Escargot::ScriptRef*), std::tuple<Escargot::ExecutionStateRef*, Escargot::ScriptRef*>&>(Escargot::ValueRef* (*&)(Escargot::ExecutionStateRef*, Escargot::ScriptRef*), std::tuple<Escargot::ExecutionStateRef*, Escargot::ScriptRef*>&) src/api/EscargotPublic.h:510
    #13 0x564dc566885c in decltype (Escargot::EvaluatorUtil::ApplyTupleIntoArgumentsOfVariadicTemplateFunction<std::tuple_size<std::decay<std::tuple<Escargot::ExecutionStateRef*, Escargot::ScriptRef*>&>::type>::value>::apply((forward<Escargot::ValueRef* (*&)(Escargot::ExecutionStateRef*, Escargot::ScriptRef*)>)({parm#1}), (forward<std::tuple<Escargot::ExecutionStateRef*, Escargot::ScriptRef*>&>)({parm#2}))) Escargot::EvaluatorUtil::applyTupleIntoArgumentsOfVariadicTemplateFunction<Escargot::ValueRef* (*&)(Escargot::ExecutionStateRef*, Escargot::ScriptRef*), std::tuple<Escargot::ExecutionStateRef*, Escargot::ScriptRef*>&>(Escargot::ValueRef* (*&)(Escargot::ExecutionStateRef*, Escargot::ScriptRef*), std::tuple<Escargot::ExecutionStateRef*, Escargot::ScriptRef*>&) src/api/EscargotPublic.h:531
    #14 0x564dc5666e70 in Escargot::Evaluator::executeImpl<Escargot::ContextRef, Escargot::ScriptRef*>(Escargot::ContextRef*, Escargot::ValueRef* (*)(Escargot::ExecutionStateRef*, Escargot::ScriptRef*), Escargot::ScriptRef*)::{lambda(Escargot::ExecutionStateRef*, void*, void*)#1}::operator()(Escargot::ExecutionStateRef*, void*, void*) const src/api/EscargotPublic.h:612
    #15 0x564dc5666efe in Escargot::Evaluator::executeImpl<Escargot::ContextRef, Escargot::ScriptRef*>(Escargot::ContextRef*, Escargot::ValueRef* (*)(Escargot::ExecutionStateRef*, Escargot::ScriptRef*), Escargot::ScriptRef*)::{lambda(Escargot::ExecutionStateRef*, void*, void*)#1}::_FUN(Escargot::ExecutionStateRef*, void*, void*) src/api/EscargotPublic.h:606
    #16 0x564dc4dbbde0 in operator() src/api/EscargotPublic.cpp:1087
    #17 0x564dc4dbbe1a in _FUN src/api/EscargotPublic.cpp:1088
    #18 0x564dc55a1dd4 in Escargot::SandBox::run(Escargot::Value (*)(Escargot::ExecutionState&, void*), void*) src/runtime/SandBox.cpp:111
    #19 0x564dc4dbc079 in Escargot::Evaluator::executeFunction(Escargot::ContextRef*, Escargot::ValueRef* (*)(Escargot::ExecutionStateRef*, void*, void*), void*, void*) src/api/EscargotPublic.cpp:1089
    #20 0x564dc5667100 in Escargot::Evaluator::EvaluatorResult Escargot::Evaluator::executeImpl<Escargot::ContextRef, Escargot::ScriptRef*>(Escargot::ContextRef*, Escargot::ValueRef* (*)(Escargot::ExecutionStateRef*, Escargot::ScriptRef*), Escargot::ScriptRef*) src/api/EscargotPublic.h:614
    #21 0x564dc566569a in execute<Escargot::ScriptRef*, evalScript(Escargot::ContextRef*, Escargot::StringRef*, Escargot::StringRef*, bool, bool)::<lambda(Escargot::ExecutionStateRef*, Escargot::ScriptRef*)> > src/api/EscargotPublic.h:585
    #22 0x564dc5661838 in evalScript src/shell/Shell.cpp:792
    #23 0x564dc56642db in main src/shell/Shell.cpp:1143
    #24 0x7f773eca3082 in __libc_start_main ../csu/libc-start.c:308
    #25 0x564dc4d9d7fd in _start (./escargot/escargot+0x2597fd)

0x564dc5c45a90 is located 16 bytes to the left of global variable 'MOD_PRIME' defined in 'third_party/robin_map/include/tsl/robin_growth_policy.h:317:5' (0x564dc5c45aa0) of size 408
0x564dc5c45a90 is located 24 bytes to the right of global variable 'MOD_PRIME' defined in 'third_party/robin_map/include/tsl/robin_growth_policy.h:317:5' (0x564dc5c458e0) of size 408
SUMMARY: AddressSanitizer: global-buffer-overflow src/interpreter/ByteCodeInterpreter.cpp:4723 in Escargot::InterpreterSlowPath::unaryTypeof(Escargot::ExecutionState&, Escargot::UnaryTypeof*, Escargot::Value*)
Shadow bytes around the buggy address:
  0x0aca38b80b00: f9 f9 f9 f9 00 00 00 00 00 00 00 00 00 00 00 00
  0x0aca38b80b10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0aca38b80b20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0aca38b80b30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0aca38b80b40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f9
=>0x0aca38b80b50: f9 f9[f9]f9 00 00 00 00 00 00 00 00 00 00 00 00
  0x0aca38b80b60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0aca38b80b70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0aca38b80b80: 00 00 00 00 00 00 00 f9 f9 f9 f9 f9 00 00 00 00
  0x0aca38b80b90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0aca38b80ba0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 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
==2069958==ABORTING

when executed in release mode

Output

Segmentation fault

Expected behavior

poc.js:3: ReferenceError: Cannot access 'n' before initialization
	for ( let { func0 : n = f = typeof n, b : o = class o { },... t } of e )
                     ^
ReferenceError: Cannot access 'n' before initialization
    at poc.js:3:22

Credits: @Ye0nny, @EJueon

@Ye0nny Ye0nny added the bug Something isn't working label Apr 7, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant