chakra-core / ChakraCore

ChakraCore is an open source Javascript engine with a C API.
MIT License
9.06k stars 1.19k forks source link

big JS object causes Abort call to block oom #6972

Open coolboy43 opened 3 months ago

coolboy43 commented 3 months ago

commit

c3ead3f8a6e0bb8e32e043adc091c68cba5935e9

bug

big JS object causes oom

build and run

os: Ubuntu 22.04.2 LTS mem: 2G build: ./build.sh --debug --static -j=8 run: ./DebugBuild/Debug/ch poc.js Run 10 times, 10 crashes

POC

const v10 = [0];
v10[1836277064] = 0;
JSON["stringify"](v10);

Abort output

# ./DebugBuild/Debug/ch poc.js
# Aborted (core dumped)

crash stack

#0  DBG_DebugBreak () at /root/work/xxxx/ChakraCore_dir/ChakraCore/pal/src/arch/i386/debugbreak.S:18
#1  0x00005565345541e2 in DebugBreak () at /root/work/xxxx/ChakraCore_dir/ChakraCore/pal/src/debug/debug.cpp:408
#2  0x00005565330288a6 in ReportFatalException (context=0, exceptionCode=-2147024882, reasonCode=Fatal_OutOfMemory, scenario=10)
    at /root/work/xxxx/ChakraCore_dir/ChakraCore/lib/Common/Exceptions/ReportError.cpp:20
#3  0x0000556533028d42 in RecyclerSingleAllocationLimit_unrecoverable_error () at /root/work/xxxx/ChakraCore_dir/ChakraCore/lib/Common/Exceptions/ReportError.cpp:151
#4  0x000055653317488f in Memory::Recycler::LargeAlloc<false> (this=0x5565363a1a48, heap=0x5565363a64a0, size=44070649568, attributes=Memory::WithBarrierBit)
    at /root/work/xxxx/ChakraCore_dir/ChakraCore/lib/Common/Memory/Recycler.cpp:1380
#5  0x0000556532ecf90b in Memory::Recycler::RealAlloc<(Memory::ObjectInfoBits)256, false> (this=0x5565363a1a48, heap=0x5565363a64a0, size=44070649568)
    at /root/work/xxxx/ChakraCore_dir/ChakraCore/lib/Common/Memory/Recycler.inl:384
#6  0x0000556532ecf4ec in Memory::Recycler::AllocWithAttributesInlined<(Memory::ObjectInfoBits)256, false> (this=0x5565363a1a48, size=44070649568)
    at /root/work/xxxx/ChakraCore_dir/ChakraCore/lib/Common/Memory/Recycler.inl:108
#7  0x0000556532f793ad in Memory::Recycler::AllocZeroWithAttributesInlined<(Memory::ObjectInfoBits)256, false> (this=0x5565363a1a48, size=44070649568)
    at /root/work/xxxx/ChakraCore_dir/ChakraCore/lib/Common/Memory/Recycler.inl:229
#8  0x0000556532f79369 in Memory::Recycler::AllocZeroWithAttributes<(Memory::ObjectInfoBits)256, false> (this=0x5565363a1a48, size=44070649568)
    at /root/work/xxxx/ChakraCore_dir/ChakraCore/lib/Common/Memory/Recycler.h:1598
#9  0x0000556532f78e49 in Memory::Recycler::AllocZero (this=0x5565363a1a48, size=44070649568) at /root/work/xxxx/ChakraCore_dir/ChakraCore/lib/Common/Memory/Recycler.h:1360
#10 0x0000556532f790ba in operator new<Memory::Recycler> (byteSize=8, alloc=0x5565363a1a48, 
    AllocFunc=(char *(Memory::Recycler::*)(Memory::Recycler * const, size_t)) 0x556532f78e10 <Memory::Recycler::AllocZero(unsigned long)>, plusSize=44070649560)
    at /root/work/xxxx/ChakraCore_dir/ChakraCore/lib/Common/DataStructures/../Memory/Allocator.h:513
#11 0x000055653490d281 in Js::JSONStringifier::ReadArray (this=0x7ffe2d47abb8, arr=0x7f0b964a22a0, objectStack=0x7ffe2d47abe8)
    at /root/work/xxxx/ChakraCore_dir/ChakraCore/lib/Runtime/Library/JSONStringifier.cpp:407
#12 0x000055653490bf6e in Js::JSONStringifier::ReadProperty (this=0x7ffe2d47abb8, key=0x7f0b964b1450, holder=0x0, prop=0x7f0b9647f360, value=0x7f0b964a22a0, 
--Type <RET> for more, q to quit, c to continue without paging--
    47abe8) at /root/work/xxxx/ChakraCore_dir/ChakraCore/lib/Runtime/Library/JSONStringifier.cpp:877
#13 0x000055653490bac3 in Js::JSONStringifier::Stringify (scriptContext=0x5565363cf488, value=0x7f0b964a22a0, replacer=0x0, space=0x7f0b964b5020)
    at /root/work/xxxx/ChakraCore_dir/ChakraCore/lib/Runtime/Library/JSONStringifier.cpp:196
#14 0x00005565348feaa1 in JSON::Stringify (function=0x7f0b96482600, callInfo=...) at /root/work/xxxx/ChakraCore_dir/ChakraCore/lib/Runtime/Library/JSON.cpp:141
#15 0x00005565340a56ee in amd64_CallFunction () at /root/work/xxxx/ChakraCore_dir/ChakraCore/lib/Runtime/Library/amd64/JavascriptFunctionA.S:100
#16 0x0000556533c73f7a in Js::JavascriptFunction::CallFunction<true> (function=0x7f0b96482600, 
    entryPoint=0x5565348fdf00 <JSON::Stringify(Js::RecyclableObject*, Js::CallInfo, ...)>, args=..., useLargeArgCount=false)
    at /root/work/xxxx/ChakraCore_dir/ChakraCore/lib/Runtime/Library/JavascriptFunction.cpp:1364
#17 0x00005565339d426f in Js::InterpreterStackFrame::OP_CallCommon<Js::OpLayoutDynamicProfile<Js::OpLayoutT_CallIWithICIndex<Js::LayoutSizePolicy<(Js::LayoutSize)0> > > __unaligned>(Js::OpLayoutDynamicProfile<Js::OpLayoutT_CallIWithICIndex<Js::LayoutSizePolicy<(Js::LayoutSize)0> > > __unaligned const __unaligned*, Js::RecyclableObject*, unsigned int, Js::AuxArray<unsigned int> const*) (this=0x7ffe2d47c170, playout=0x7f0b964fd4a5, function=0x7f0b96482600, flags=16, spreadIndices=0x0)
    at /root/work/xxxx/ChakraCore_dir/ChakraCore/lib/Runtime/Language/InterpreterStackFrame.cpp:3973
#18 0x00005565339d3b29 in Js::InterpreterStackFrame::OP_ProfileCallCommon<Js::OpLayoutDynamicProfile<Js::OpLayoutT_CallIWithICIndex<Js::LayoutSizePolicy<(Js::LayoutSize)0> > > __unaligned>(Js::OpLayoutDynamicProfile<Js::OpLayoutT_CallIWithICIndex<Js::LayoutSizePolicy<(Js::LayoutSize)0> > > __unaligned const __unaligned*, Js::RecyclableObject*, unsigned int, unsigned short, unsigned int, Js::AuxArray<unsigned int> const*) (this=0x7ffe2d47c170, playout=0x7f0b964fd4a5, function=0x7f0b96482600, flags=0, profileId=0, 
    inlineCacheIndex=0, spreadIndices=0x0) at /root/work/xxxx/ChakraCore_dir/ChakraCore/lib/Runtime/Language/InterpreterStackFrame.cpp:4016
#19 0x000055653382ce16 in Js::InterpreterStackFrame::OP_ProfiledCallIWithICIndex<Js::OpLayoutT_CallIWithICIndex<Js::LayoutSizePolicy<(Js::LayoutSize)0> > >(Js::OpLayoutDynamicProfile<Js::OpLayoutT_CallIWithICIndex<Js::LayoutSizePolicy<(Js::LayoutSize)0> > > const __unaligned*) (this=0x7ffe2d47c170, playout=0x7f0b964fd4a5)
    at /root/work/xxxx/ChakraCore_dir/ChakraCore/lib/Runtime/./Language/InterpreterStackFrame.h:520
#20 0x000055653381c43b in Js::InterpreterStackFrame::ProcessProfiled (this=0x7ffe2d47c170)
    at /root/work/xxxx/ChakraCore_dir/ChakraCore/lib/Runtime/Language/InterpreterHandler.inl:91
#21 0x000055653378731f in Js::InterpreterStackFrame::Process (this=0x7ffe2d47c170)
    at /root/work/xxxx/ChakraCore_dir/ChakraCore/lib/Runtime/Language/InterpreterStackFrame.cpp:3472
#22 0x0000556533784e11 in Js::InterpreterStackFrame::InterpreterHelper (function=0x7f0b964b66e0, args=..., returnAddress=0x7f0b960d0fa2, addressOfReturnAddress=0x7ffe2d47c728, 
    asmJsReturn=0x0) at /root/work/xxxx/ChakraCore_dir/ChakraCore/lib/Runtime/Language/InterpreterStackFrame.cpp:2153
#23 0x0000556533783678 in Js::InterpreterStackFrame::InterpreterThunk (layout=0x7ffe2d47c740)
    at /root/work/xxxx/ChakraCore_dir/ChakraCore/lib/Runtime/Language/InterpreterStackFrame.cpp:1833
#24 0x00007f0b960d0fa2 in ?? ()
#25 0x00007ffe2d47c750 in ?? ()
#26 0x00005565340a56ee in amd64_CallFunction () at /root/work/xxxx/ChakraCore_dir/ChakraCore/lib/Runtime/Library/amd64/JavascriptFunctionA.S:100
rhuanjl commented 2 months ago

This JS snippet attempts to Allocate several Gb of memory, Chakracore sees this as dangerous and calls Abort to block it.

This behaviour is by design. I have mixed feelings about this design choice - but it was a deliberate choice by the MS chakra team a while back to block certain potential security risks by calling Abort.