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

dynamic-stack-buffer-overflow JSC::Yarr::Interpreter<unsigned char>::interpret() #1379

Open
7331akasokoan opened this issue Aug 26, 2024 · 0 comments
Labels
bug Something isn't working

Comments

@7331akasokoan
Copy link

commit: d398f1e

build setting:

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

poc.js:

const v0 = /(?<v>>||||`|^||||||||||(?<c>(?<d>.)?).)+(?<c>(?<d>.D*))\b/dsyig;
v0.kwstIndex = "2";
v0.test("nud");

ASAN report:

=================================================================
==44525==ERROR: AddressSanitizer: dynamic-stack-buffer-overflow on address 0x7ffd79505130 at pc 0x55d4114d7279 bp 0x7ffd79504f80 sp 0x7ffd79504f70
WRITE of size 4 at 0x7ffd79505130 thread T0
    #0 0x55d4114d7278 in JSC::Yarr::Interpreter<unsigned char>::interpret() (/home/fuzzer/escargot/escargot+0xbd1278)
    #1 0x55d4114d4af9 in JSC::Yarr::interpret(JSC::Yarr::BytecodePattern*, unsigned char const*, unsigned int, unsigned int, unsigned int*) /home/fuzzer/escargot/third_party/yarr/YarrInterpreter.cpp:2769
    #2 0x55d4113b39cf in Escargot::RegExpObject::match(Escargot::ExecutionState&, Escargot::String*, Escargot::RegexMatchResult&, bool, unsigned long) /home/fuzzer/escargot/src/runtime/RegExpObject.cpp:361
    #3 0x55d410cf924c in Escargot::builtinRegExpTest(Escargot::ExecutionState&, Escargot::Value, unsigned long, Escargot::Value*, Escargot::Optional<Escargot::Object*>) (/home/fuzzer/escargot/escargot+0x3f324c)
    #4 0x55d411342ee6 in Escargot::Value Escargot::NativeFunctionObject::processNativeFunctionCall<false, true>(Escargot::ExecutionState&, Escargot::Value const&, unsigned long, Escargot::Value*, Escargot::Optional<Escargot::Object*>) /home/fuzzer/escargot/src/runtime/FunctionObjectInlines.h:312
    #5 0x55d41134233f in Escargot::NativeFunctionObject::call(Escargot::ExecutionState&, Escargot::Value const&, unsigned long, Escargot::Value*) /home/fuzzer/escargot/src/runtime/NativeFunctionObject.cpp:78
    #6 0x55d410e245e0 in Escargot::Interpreter::interpret(Escargot::ExecutionState*, Escargot::ByteCodeBlock*, unsigned long, Escargot::Value*) /home/fuzzer/escargot/src/interpreter/ByteCodeInterpreter.cpp:791
    #7 0x55d41100396e in Escargot::Script::execute(Escargot::ExecutionState&, bool, bool) /home/fuzzer/escargot/src/parser/Script.cpp:499
    #8 0x55d410bcb87e in Escargot::ScriptRef::execute(Escargot::ExecutionStateRef*) /home/fuzzer/escargot/src/api/EscargotPublic.cpp:4722
    #9 0x55d4114a76cc in operator() /home/fuzzer/escargot/src/shell/Shell.cpp:790
    #10 0x55d4114a76f7 in _FUN /home/fuzzer/escargot/src/shell/Shell.cpp:791
    #11 0x55d4114b14b3 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*&) /home/fuzzer/escargot/src/api/EscargotPublic.h:521
    #12 0x55d4114b0ad2 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*&) /home/fuzzer/escargot/src/api/EscargotPublic.h:510
    #13 0x55d4114b0092 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*>&) /home/fuzzer/escargot/src/api/EscargotPublic.h:510
    #14 0x55d4114af24c 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*>&) /home/fuzzer/escargot/src/api/EscargotPublic.h:531
    #15 0x55d4114ad8bc 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 /home/fuzzer/escargot/src/api/EscargotPublic.h:612
    #16 0x55d4114ad94a 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*) /home/fuzzer/escargot/src/api/EscargotPublic.h:606
    #17 0x55d410bc79f0 in operator() /home/fuzzer/escargot/src/api/EscargotPublic.cpp:1094
    #18 0x55d410bc7a2a in _FUN /home/fuzzer/escargot/src/api/EscargotPublic.cpp:1095
    #19 0x55d4113e4a08 in Escargot::SandBox::run(Escargot::Value (*)(Escargot::ExecutionState&, void*), void*) /home/fuzzer/escargot/src/runtime/SandBox.cpp:111
    #20 0x55d410bc7c88 in Escargot::Evaluator::executeFunction(Escargot::ContextRef*, Escargot::ValueRef* (*)(Escargot::ExecutionStateRef*, void*, void*), void*, void*) /home/fuzzer/escargot/src/api/EscargotPublic.cpp:1096
    #21 0x55d4114adb46 in Escargot::Evaluator::EvaluatorResult Escargot::Evaluator::executeImpl<Escargot::ContextRef, Escargot::ScriptRef*>(Escargot::ContextRef*, Escargot::ValueRef* (*)(Escargot::ExecutionStateRef*, Escargot::ScriptRef*), Escargot::ScriptRef*) /home/fuzzer/escargot/src/api/EscargotPublic.h:614
    #22 0x55d4114ac0bb in execute<Escargot::ScriptRef*, evalScript(Escargot::ContextRef*, Escargot::StringRef*, Escargot::StringRef*, bool, bool)::<lambda(Escargot::ExecutionStateRef*, Escargot::ScriptRef*)> > /home/fuzzer/escargot/src/api/EscargotPublic.h:585
    #23 0x55d4114a7ee1 in evalScript /home/fuzzer/escargot/src/shell/Shell.cpp:792
    #24 0x55d4114aa9cd in main /home/fuzzer/escargot/src/shell/Shell.cpp:1149
    #25 0x7ff273c68d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #26 0x7ff273c68e3f in __libc_start_main_impl ../csu/libc-start.c:392
    #27 0x55d410ba88a4 in _start (/home/fuzzer/escargot/escargot+0x2a28a4)

Address 0x7ffd79505130 is located in stack of thread T0 at offset 320 in frame
    #0 0x55d4114d49fa in JSC::Yarr::interpret(JSC::Yarr::BytecodePattern*, unsigned char const*, unsigned int, unsigned int, unsigned int*) /home/fuzzer/escargot/third_party/yarr/YarrInterpreter.cpp:2768

  This frame has 1 object(s):
    [48, 120) '<unknown>' <== Memory access at offset 320 overflows this variable
HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork
      (longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: dynamic-stack-buffer-overflow (/home/fuzzer/escargot/escargot+0xbd1278) in JSC::Yarr::Interpreter<unsigned char>::interpret()
Shadow bytes around the buggy address:
  0x10002f2989d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10002f2989e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10002f2989f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1
  0x10002f298a00: f1 f1 f1 f1 00 00 00 00 00 00 00 00 00 f3 f3 f3
  0x10002f298a10: f3 f3 00 00 00 00 00 00 00 00 00 00 ca ca ca ca
=>0x10002f298a20: 00 00 00 00 00 00[cb]cb cb cb cb cb 00 00 00 00
  0x10002f298a30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10002f298a40: 00 00 f1 f1 f1 f1 f8 f2 f8 f2 04 f2 04 f2 f8 f2
  0x10002f298a50: f2 f2 00 f2 f2 f2 00 f2 f2 f2 00 f2 f2 f2 00 00
  0x10002f298a60: 00 00 00 00 00 f2 f2 f2 f2 f2 00 00 00 00 00 00
  0x10002f298a70: 00 f2 f2 f2 f2 f2 00 00 00 00 00 f2 f2 f2 f2 f2
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
==44525==ABORTING
@7331akasokoan 7331akasokoan added the bug Something isn't working label Aug 26, 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

4 participants
@7331akasokoan and others