ChakraCore icon indicating copy to clipboard operation
ChakraCore copied to clipboard

Assertion Error in `DeleteProperty`

Open bin2415 opened this issue 4 years ago • 2 comments

PoC:

function main() {
do {
    delete isNaN.length;
    const v4 = Object.getOwnPropertyNames(isNaN);
} while (16 < 1337);
}
main();
// STDERR:
// ASSERTION 12205: (/src/chakracore/lib/Runtime/Types/SimpleTypeHandler.cpp, line 664) !GetIsLocked()
//  Failure: (!GetIsLocked())

Backtrace:

* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
    frame #0: 0x0000000104548134 libChakraCore.dylib`Js::SimpleTypeHandler<2ul>::DeleteProperty(this=0x0000000102447640, instance=0x0000000102406740, propertyId=206, propertyOperationFlags=PropertyOperation_None) at SimpleTypeHandler.cpp:664:17
   661 	            if (descriptors[index].Attributes & PropertyDeleted)
   662 	            {
   663 	                // A locked type should not have deleted properties
-> 664 	                Assert(!GetIsLocked());
   665 	                return true;
   666 	            }
   667 	            if (!(descriptors[index].Attributes & PropertyConfigurable))
Target 0: (ch) stopped.
(lldb) bt 20
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
  * frame #0: 0x0000000104548134 libChakraCore.dylib`Js::SimpleTypeHandler<2ul>::DeleteProperty(this=0x0000000102447640, instance=0x0000000102406740, propertyId=206, propertyOperationFlags=PropertyOperation_None) at SimpleTypeHandler.cpp:664:17
    frame #1: 0x000000010444b884 libChakraCore.dylib`Js::DynamicObject::DeleteProperty(this=0x0000000102406740, propertyId=206, flags=PropertyOperation_None) at DynamicType.cpp:336:34
    frame #2: 0x00000001040cc3fe libChakraCore.dylib`Js::JavascriptFunction::DeleteProperty(this=0x0000000102406740, propertyId=206, flags=PropertyOperation_None) at JavascriptFunction.cpp:3055:38
    frame #3: 0x0000000103e67188 libChakraCore.dylib`int Js::JavascriptOperators::DeleteProperty_Impl<false>(instance=0x0000000102406740, propertyId=206, propertyOperationFlags=PropertyOperation_None) at JavascriptOperators.cpp:3130:27
    frame #4: 0x0000000103e67151 libChakraCore.dylib`Js::JavascriptOperators::DeleteProperty(instance=0x0000000102406740, propertyId=206, propertyOperationFlags=PropertyOperation_None) at JavascriptOperators.cpp:3074:16
    frame #5: 0x0000000103e6739d libChakraCore.dylib`Js::JavascriptOperators::OP_DeleteProperty(instance=0x0000000102406740, propertyId=206, scriptContext=0x0000000101017c58, propertyOperationFlags=PropertyOperation_None) at JavascriptOperators.cpp:3149:13
    frame #6: 0x0000000103cc5291 libChakraCore.dylib`void Js::InterpreterStackFrame::OP_DeleteFld<Js::OpLayoutT_ElementC<Js::LayoutSizePolicy<(Js::LayoutSize)0> > __unaligned>(this=0x00007ffeefbfc9e0, playout=0x000000010246006d)0> > __unaligned const __unaligned*) at InterpreterStackFrame.cpp:7674:22
    frame #7: 0x0000000103cfda58 libChakraCore.dylib`Js::InterpreterStackFrame::ProcessProfiled(this=0x00007ffeefbfc9e0) at InterpreterHandler.inl:191:3
    frame #8: 0x0000000103c938f4 libChakraCore.dylib`Js::InterpreterStackFrame::Process(this=0x00007ffeefbfc9e0) at InterpreterStackFrame.cpp:3472:20
    frame #9: 0x0000000103c923fc libChakraCore.dylib`Js::InterpreterStackFrame::InterpreterHelper(function=0x00000001021e6730, args=ArgumentReader @ 0x00007ffeefbfcf10, returnAddress=0x0000000102480f9a, addressOfReturnAddress=0x00007ffeefbfcf58, asmJsReturn=0x0000000000000000) at InterpreterStackFrame.cpp:2153:40
    frame #10: 0x0000000103c91480 libChakraCore.dylib`Js::InterpreterStackFrame::InterpreterThunk(layout=0x00007ffeefbfcf70) at InterpreterStackFrame.cpp:1833:16
    frame #11: 0x0000000102480f9a
    frame #12: 0x000000010440d15e libChakraCore.dylib`amd64_CallFunction at JavascriptFunctionA.S:100
    frame #13: 0x00000001040c62db libChakraCore.dylib`void* Js::JavascriptFunction::CallFunction<true>(function=0x00000001021e6730, entryPoint=(libChakraCore.dylib`NativeCodeGenerator::CheckCodeGenThunk(Js::RecyclableObject*, Js::CallInfo, ...)), args=Arguments @ 0x00007ffeefbfd0a0, useLargeArgCount=false)(Js::RecyclableObject*, Js::CallInfo, ...), Js::Arguments, bool) at JavascriptFunction.cpp:1364:16
    frame #14: 0x0000000103e2be7f libChakraCore.dylib`void Js::InterpreterStackFrame::OP_CallCommon<Js::OpLayoutDynamicProfile<Js::OpLayoutT_CallIWithICIndex<Js::LayoutSizePolicy<(Js::LayoutSize)0> > > __unaligned>(this=0x00007ffeefbfe270, playout=0x000000010218cdd0, function=0x00000001021e6730, flags=16, spreadIndices=0x0000000000000000)0> > > __unaligned const __unaligned*, Js::RecyclableObject*, unsigned int, Js::AuxArray<unsigned int> const*) at InterpreterStackFrame.cpp:3973:21
    frame #15: 0x0000000103e2b971 libChakraCore.dylib`void Js::InterpreterStackFrame::OP_ProfileCallCommon<Js::OpLayoutDynamicProfile<Js::OpLayoutT_CallIWithICIndex<Js::LayoutSizePolicy<(Js::LayoutSize)0> > > __unaligned>(this=0x00007ffeefbfe270, playout=0x000000010218cdd0, function=0x00000001021e6730, flags=0, profileId=0, inlineCacheIndex=0, spreadIndices=0x0000000000000000)0> > > __unaligned const __unaligned*, Js::RecyclableObject*, unsigned int, unsigned short, unsigned int, Js::AuxArray<unsigned int> const*) at InterpreterStackFrame.cpp:4016:9
    frame #16: 0x0000000103d04dd8 libChakraCore.dylib`void Js::InterpreterStackFrame::OP_ProfiledCallIWithICIndex<Js::OpLayoutT_CallIWithICIndex<Js::LayoutSizePolicy<(Js::LayoutSize)0> > >(this=0x00007ffeefbfe270, playout=0x000000010218cdd0)0> > > const __unaligned*) at InterpreterStackFrame.h:520:115
    frame #17: 0x0000000103cf98f6 libChakraCore.dylib`Js::InterpreterStackFrame::ProcessProfiled(this=0x00007ffeefbfe270) at InterpreterHandler.inl:91:3
    frame #18: 0x0000000103c938f4 libChakraCore.dylib`Js::InterpreterStackFrame::Process(this=0x00007ffeefbfe270) at InterpreterStackFrame.cpp:3472:20
    frame #19: 0x0000000103c923fc libChakraCore.dylib`Js::InterpreterStackFrame::InterpreterHelper(function=0x00000001021e66e0, args=ArgumentReader @ 0x00007ffeefbfe760, returnAddress=0x0000000102480fa2, addressOfReturnAddress=0x00007ffeefbfe7a8, asmJsReturn=0x0000000000000000) at InterpreterStackFrame.cpp:2153:40

How to reproduce it:

- ./build.sh -d -j
- ./ch poc.js

bin2415 avatar Apr 09 '21 15:04 bin2415

I can reproduce this error with property "name" aswell, Here is the code:

do {
    delete isNaN.name;
    Object.getOwnPropertyNames(isNaN);
} while (1);

stderr is same:

ASSERTION 9816: (...\ChakraCore\lib\Runtime\Types\SimpleTypeHandler.cpp, line 664) !GetIsLocked()
 Failure: (!GetIsLocked())
FATAL ERROR: ch.exe failed due to exception code c0000420

MadProbe avatar Apr 09 '21 17:04 MadProbe

Simpler repro:

delete isNaN.name;
Object.getOwnPropertyNames(isNaN);
delete isNaN.name;

It's not going wrong at runtime in a release build but there is a logical error here - I think the first deletion should cause isNaN to change type (internal hidden class) and is failing too.

getOwnPropertyNames calls GetEnumerator which in turn calls LockType which on a SimpleTypeHandler always succeeds BUT when there is a deleted property should not.

rhuanjl avatar Apr 09 '21 17:04 rhuanjl