ChakraCore
ChakraCore copied to clipboard
for-loop optimization causes a null pointer exception
Version:
chakra-1.11.24.0
Description:
For the TestCase below, after judging that !p is true in line 2, the function should return directly, but chakra terminates the program abnormally. Through the stack information of the program#1 0x00007ffff34ddece in ByteCodeGenerator::EmitInvertedLoop ( this=0x7fffffffb4e0, outerLoop=0x7ff7f0b72da0, invertedLoop=0x7ff7f0b75030, funcInfo=0x7ff7f0b74800), maybe there is a problem in optimizing the for loop.
TestCase:
var NISLFuzzingFunc = function(p) {
if (!p) return;
var a = 0;
for (var h = 0;; ++h) {
for (var r = 0; r < 1; ++r) {
a = r;
}
}
};
var NISLParameter0 = false;
var NISLCallingResult = NISLFuzzingFunc(NISLParameter0);
print(NISLCallingResult);
Command:
~/ChakraCore/out/Release/ch TestCase.js
Output:
Aborted (core dumped)
Backtrace (using gdb debugging) :
gdb -q -args ~/ChakraCore-1.11.24/out/Debug/ch TestCase.js
Reading symbols from ~/ChakraCore-1.11.24/out/Debug/ch...done.
(gdb) r
Starting program: ~/ChakraCore-1.11.24/out/Debug/ch TestCase.js
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[New Thread 0x7ff7f242f700 (LWP 8102)]
[New Thread 0x7ff7f1bff700 (LWP 8103)]
[New Thread 0x7ff7f13fe700 (LWP 8104)]
Thread 1 "ch" received signal SIGSEGV, Segmentation fault.
0x00007ffff34dcc75 in EmitBooleanExpression (expr=0x0, trueLabel=10, falseLabel=4, byteCodeGenerator=0x7fffffffb4e0, funcInfo=0x7ff7f0b74800, trueFallthrough=true, falseFallthrough=false)
at ~/ChakraCore-1.11.24/lib/Runtime/ByteCode/ByteCodeEmitter.cpp:8835
8835 switch (expr->nop)
(gdb) bt
#0 0x00007ffff34dcc75 in EmitBooleanExpression (expr=0x0, trueLabel=10, falseLabel=4, byteCodeGenerator=0x7fffffffb4e0, funcInfo=0x7ff7f0b74800, trueFallthrough=true, falseFallthrough=false)
at ~/ChakraCore-1.11.24/lib/Runtime/ByteCode/ByteCodeEmitter.cpp:8835
#1 0x00007ffff34ddece in ByteCodeGenerator::EmitInvertedLoop (this=0x7fffffffb4e0, outerLoop=0x7ff7f0b72da0, invertedLoop=0x7ff7f0b75030, funcInfo=0x7ff7f0b74800)
at ~/ChakraCore-1.11.24/lib/Runtime/ByteCode/ByteCodeEmitter.cpp:9170
#2 0x00007ffff34bbff7 in Emit (pnode=0x7ff7f0b72da0, byteCodeGenerator=0x7fffffffb4e0, funcInfo=0x7ff7f0b74800, fReturnValue=0, isConstructorCall=false, bindingNameLocation=4294967295, isTopLevel=true)
at ~/ChakraCore-1.11.24/lib/Runtime/ByteCode/ByteCodeEmitter.cpp:11085
#3 0x00007ffff34b82de in ByteCodeGenerator::EmitTopLevelStatement (this=0x7fffffffb4e0, stmt=0x7ff7f0b72da0, funcInfo=0x7ff7f0b74800, fReturnValue=0) at ~/ChakraCore-1.11.24/lib/Runtime/ByteCode/ByteCodeEmitter.cpp:956
#4 0x00007ffff34c73ed in ByteCodeGenerator::EmitFunctionBody (this=0x7fffffffb4e0, funcInfo=0x7ff7f0b74800) at ~/ChakraCore-1.11.24/lib/Runtime/ByteCode/ByteCodeEmitter.cpp:2507
#5 0x00007ffff34ca160 in ByteCodeGenerator::EmitOneFunction (this=0x7fffffffb4e0, pnodeFnc=0x7ff7f0b722d0) at ~/ChakraCore-1.11.24/lib/Runtime/ByteCode/ByteCodeEmitter.cpp:3132
#6 0x00007ffff34c7880 in ByteCodeGenerator::EmitScopeList (this=0x7fffffffb4e0, pnode=0x7ff7f0b722d0, breakOnBodyScopeNode=0x0) at ~/ChakraCore-1.11.24/lib/Runtime/ByteCode/ByteCodeEmitter.cpp:3423
#7 0x00007ffff34c79dd in ByteCodeGenerator::EmitScopeList (this=0x7fffffffb4e0, pnode=0x7ff7f0b72170, breakOnBodyScopeNode=0x0) at ~/ChakraCore-1.11.24/lib/Runtime/ByteCode/ByteCodeEmitter.cpp:3436
#8 0x00007ffff34c786b in ByteCodeGenerator::EmitScopeList (this=0x7fffffffb4e0, pnode=0x7ff7f0b72030, breakOnBodyScopeNode=0x0) at ~/ChakraCore-1.11.24/lib/Runtime/ByteCode/ByteCodeEmitter.cpp:3420
#9 0x00007ffff34c7646 in ByteCodeGenerator::EmitProgram (this=0x7fffffffb4e0, pnodeProg=0x7ff7f0b72030) at ~/ChakraCore-1.11.24/lib/Runtime/ByteCode/ByteCodeEmitter.cpp:2541
#10 0x00007ffff34fffb1 in ByteCodeGenerator::Generate (pnodeProg=0x7ff7f0b72030, grfscr=4112, byteCodeGenerator=0x7fffffffb4e0, ppRootFunc=0x7fffffffb778, sourceIndex=0, forceNoNative=false, parser=0x7fffffffb9f0, functionRef=0x0)
at ~/ChakraCore-1.11.24/lib/Runtime/ByteCode/ByteCodeGenerator.cpp:2021
#11 0x00007ffff3503a8d in GenerateByteCode (pnode=0x7ff7f0b72030, grfscr=4112, scriptContext=0x5555561af538, ppRootFunc=0x7fffffffb778, sourceIndex=0, forceNoNative=false, parser=0x7fffffffb9f0, pse=0x7fffffffc930, parentScopeInfo=0x0, functionRef=0x0)
at ~/ChakraCore-1.11.24/lib/Runtime/ByteCode/ByteCodeGenerator.cpp:2192
#12 0x00007ffff33c514a in Js::ScriptContext::GenerateRootFunction (this=0x5555561af538, parseTree=0x7ff7f0b72030, sourceIndex=0, parser=0x7fffffffb9f0, grfscr=4112, pse=0x7fffffffc930, rootDisplayName=0x7ffff43d3f80 <Js::Constants::GlobalCode> u"Global code")
at ~/ChakraCore-1.11.24/lib/Runtime/Base/ScriptContext.cpp:2550
#13 0x00007ffff33c4de9 in Js::ScriptContext::LoadScriptInternal (this=0x5555561af538, parser=0x7fffffffb9f0,
script=0x55555617d5d0 "var NISLFuzzingFunc = function(p) {\n if (!p) return;\n var a = 0;\n for (var h = 0;; ++h) {\n for (var r = 0; r < 1; ++r) {\n", ' ' <repeats 12 times>, "a = r;\n }\n }\n};\nvar NISLParameter0 = fals"..., cb=286,
pSrcInfo=0x7fffffffc5e0, pse=0x7fffffffc930, ppSourceInfo=0x7fffffffc5d8, rootDisplayName=0x7ffff43d3f80 <Js::Constants::GlobalCode> u"Global code", loadScriptFlag=(LoadScriptFlag_Utf8Source | LoadScriptFlag_ExternalArrayBuffer), scriptSource=0x7ff7f0b97000)
at ~/ChakraCore-1.11.24/lib/Runtime/Base/ScriptContext.cpp:2488
#14 0x00007ffff33c5437 in Js::ScriptContext::LoadScript (this=0x5555561af538,
script=0x55555617d5d0 "var NISLFuzzingFunc = function(p) {\n if (!p) return;\n var a = 0;\n for (var h = 0;; ++h) {\n for (var r = 0; r < 1; ++r) {\n", ' ' <repeats 12 times>, "a = r;\n }\n }\n};\nvar NISLParameter0 = fals"..., cb=286,
pSrcInfo=0x7fffffffc5e0, pse=0x7fffffffc930, ppSourceInfo=0x7fffffffc5d8, rootDisplayName=0x7ffff43d3f80 <Js::Constants::GlobalCode> u"Global code", loadScriptFlag=(LoadScriptFlag_Utf8Source | LoadScriptFlag_ExternalArrayBuffer), scriptSource=0x7ff7f0b97000)
at ~/ChakraCore-1.11.24/lib/Runtime/Base/ScriptContext.cpp:2526
#15 0x00007ffff2c81751 in RunScriptCore(void*, unsigned char const*, unsigned long, LoadScriptFlag, unsigned long, char16_t const*, bool, _JsParseScriptAttributes, bool, void**)::$_86::operator()(Js::ScriptContext*, TTD::TTDJsRTActionResultAutoRecorder&) const (
this=0x7fffffffc820, scriptContext=0x5555561af538, _actionEntryPopper=...) at ~/ChakraCore-1.11.24/lib/Jsrt/Jsrt.cpp:3538
#16 0x00007ffff2c81427 in _JsErrorCode ContextAPINoScriptWrapper<RunScriptCore(void*, unsigned char const*, unsigned long, LoadScriptFlag, unsigned long, char16_t const*, bool, _JsParseScriptAttributes, bool, void**)::$_86>(RunScriptCore(void*, unsigned char const*, unsigned long, LoadScriptFlag, unsigned long, char16_t const*, bool, _JsParseScriptAttributes, bool, void**)::$_86, bool, bool)::{lambda(Js::ScriptContext*)#1}::operator()(Js::ScriptContext*) const (this=0x7fffffffc7a8, scriptContext=0x5555561af538)
at ~/ChakraCore-1.11.24/lib/Jsrt/JsrtInternal.h:316
#17 0x00007ffff2c80d2a in ContextAPINoScriptWrapper_Core<_JsErrorCode ContextAPINoScriptWrapper<RunScriptCore(void*, unsigned char const*, unsigned long, LoadScriptFlag, unsigned long, char16_t const*, bool, _JsParseScriptAttributes, bool, void**)::$_86>(RunScriptCore(void*, unsigned char const*, unsigned long, LoadScriptFlag, unsigned long, char16_t const*, bool, _JsParseScriptAttributes, bool, void**)::$_86, bool, bool)::{lambda(Js::ScriptContext*)#1}>(_JsErrorCode ContextAPINoScriptWrapper<RunScriptCore(void*, unsigned char const*, unsigned long, LoadScriptFlag, unsigned long, char16_t const*, bool, _JsParseScriptAttributes, bool, void**)::$_86>(RunScriptCore(void*, unsigned char const*, unsigned long, LoadScriptFlag, unsigned long, char16_t const*, bool, _JsParseScriptAttributes, bool, void**)::$_86, bool, bool)::{lambda(Js::ScriptContext*)#1}, bool, bool) (fn=..., allowInObjectBeforeCollectCallback=false, scriptExceptionAllowed=false) at ~/ChakraCore-1.11.24/lib/Jsrt/JsrtInternal.h:277
#18 0x00007ffff2c4b4b8 in ContextAPINoScriptWrapper<RunScriptCore(void*, unsigned char const*, unsigned long, LoadScriptFlag, unsigned long, char16_t const*, bool, _JsParseScriptAttributes, bool, void**)::$_86>(RunScriptCore(void*, unsigned char const*, unsigned long, LoadScriptFlag, unsigned long, char16_t const*, bool, _JsParseScriptAttributes, bool, void**)::$_86, bool, bool) (fn=..., allowInObjectBeforeCollectCallback=false, scriptExceptionAllowed=false)
at ~/ChakraCore-1.11.24/lib/Jsrt/JsrtInternal.h:314
#19 0x00007ffff2c4b35f in RunScriptCore (scriptSource=0x7ff7f0b97000,
script=0x55555617d5d0 "var NISLFuzzingFunc = function(p) {\n if (!p) return;\n var a = 0;\n for (var h = 0;; ++h) {\n for (var r = 0; r < 1; ++r) {\n", ' ' <repeats 12 times>, "a = r;\n }\n }\n};\nvar NISLParameter0 = fals"..., cb=286,
loadScriptFlag=(LoadScriptFlag_Utf8Source | LoadScriptFlag_ExternalArrayBuffer), sourceContext=0, sourceUrl=0x7ff7f0b70000 u"/home/nisl1/nisl8121/yw/TencentProject/result_analyse/crash/TestCase.js", parseOnly=false, parseAttributes=JsParseScriptAttributeNone,
isSourceModule=false, result=0x0) at ~/ChakraCore-1.11.24/lib/Jsrt/Jsrt.cpp:3487
#20 0x00007ffff2c4deee in CompileRun (scriptVal=0x7ff7f0b97000, sourceContext=0, sourceUrl=0x7ff7f0bd5f00, parseAttributes=JsParseScriptAttributeNone, result=0x0, parseOnly=false)
at ~/ChakraCore-1.11.24/lib/Jsrt/Jsrt.cpp:4991
#21 JsRun (scriptVal=0x7ff7f0b97000, sourceContext=0, sourceUrl=0x7ff7f0bd5f00, parseAttributes=JsParseScriptAttributeNone, result=0x0) at ~/ChakraCore-1.11.24/lib/Jsrt/Jsrt.cpp:5013
#22 0x000055555556045e in ChakraRTInterface::JsRun (script=0x7ff7f0b97000, sourceContext=0, sourceUrl=0x7ff7f0bd5f00, parseAttributes=JsParseScriptAttributeNone, result=0x0)
at ~/ChakraCore-1.11.24/bin/ch/ChakraRtInterface.h:419
#23 0x000055555555d653 in RunScript (fileName=0x55555617c530 "./TestCase.js",
fileContents=0x55555617d5d0 "var NISLFuzzingFunc = function(p) {\n if (!p) return;\n var a = 0;\n for (var h = 0;; ++h) {\n for (var r = 0; r < 1; ++r) {\n", ' ' <repeats 12 times>, "a = r;\n }\n }\n};\nvar NISLParameter0 = fals"...,
fileLength=286, fileContentsFinalizeCallback=0x55555556c580 <WScriptJsrt::FinalizeFree(void*)>, bufferValue=0x0, fullPath=0x7fffffffd160 "/home/nisl1/nisl8121/yw/TencentProject/result_analyse/crash/TestCase.js", parserStateCache=0x0)
at ~/ChakraCore-1.11.24/bin/ch/ch.cpp:479
#24 0x000055555555f0e1 in ExecuteTest (fileName=0x55555617c530 "./TestCase.js") at ~/ChakraCore-1.11.24/bin/ch/ch.cpp:913
#25 0x000055555555f1ac in ExecuteTestWithMemoryCheck (fileName=0x55555617c530 "./TestCase.js") at ~/ChakraCore-1.11.24/bin/ch/ch.cpp:963
#26 0x000055555555fa9b in main (argc=2, c_argv=0x7fffffffd5a8) at ~/ChakraCore-1.11.24/bin/ch/ch.cpp:1270
Using ASAN:
AddressSanitizer:DEADLYSIGNAL
=================================================================
==8178==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x561fcd822a34 bp 0x7ffc3ac7b580 sp 0x7ffc3ac7b530 T0)
==8178==The signal is caused by a READ memory access.
==8178==Hint: address points to the zero page.
#0 0x561fcd822a33 in EmitBooleanExpression(ParseNode*, int, int, ByteCodeGenerator*, FuncInfo*, bool, bool) (~/ChakraCore-1.11.24/out/Release/ch+0x177ea33)
#1 0x561fcd8245b9 in ByteCodeGenerator::EmitInvertedLoop(ParseNodeLoop*, ParseNodeFor*, FuncInfo*) (~/ChakraCore-1.11.24/out/Release/ch+0x17805b9)
#2 0x561fcd7ea583 in Emit(ParseNode*, ByteCodeGenerator*, FuncInfo*, int, bool, unsigned int, bool) (~/ChakraCore-1.11.24/out/Release/ch+0x1746583)
#3 0x561fcd7e4275 in ByteCodeGenerator::EmitTopLevelStatement(ParseNode*, FuncInfo*, int) (~/ChakraCore-1.11.24/out/Release/ch+0x1740275)
#4 0x561fcd800fa2 in ByteCodeGenerator::EmitFunctionBody(FuncInfo*) (~/ChakraCore-1.11.24/out/Release/ch+0x175cfa2)
#5 0x561fcd806b76 in ByteCodeGenerator::EmitOneFunction(ParseNodeFnc*) (~/ChakraCore-1.11.24/out/Release/ch+0x1762b76)
#6 0x561fcd8019ae in ByteCodeGenerator::EmitScopeList(ParseNode*, ParseNode*) (~/ChakraCore-1.11.24/out/Release/ch+0x175d9ae)
#7 0x561fcd8016f6 in ByteCodeGenerator::EmitScopeList(ParseNode*, ParseNode*) (~/ChakraCore-1.11.24/out/Release/ch+0x175d6f6)
#8 0x561fcd80199b in ByteCodeGenerator::EmitScopeList(ParseNode*, ParseNode*) (~/ChakraCore-1.11.24/out/Release/ch+0x175d99b)
#9 0x561fcc7ef220 in ByteCodeGenerator::Generate(ParseNodeProg*, unsigned int, ByteCodeGenerator*, Js::ParseableFunctionInfo**, unsigned int, bool, Parser*, Js::ScriptFunction**) (~/ChakraCore-1.11.24/out/Release/ch+0x74b220)
#10 0x561fcc7f5f31 in GenerateByteCode(ParseNodeProg*, unsigned int, Js::ScriptContext*, Js::ParseableFunctionInfo**, unsigned int, bool, Parser*, CompileScriptException*, Js::ScopeInfo*, Js::ScriptFunction**) (~/ChakraCore-1.11.24/out/Release/ch+0x751f31)
#11 0x561fcc767a9e in Js::ScriptContext::LoadScriptInternal(Parser*, unsigned char const*, unsigned long, SRCINFO const*, CompileScriptException*, Js::Utf8SourceInfo**, char16_t const*, LoadScriptFlag, void*) (~/ChakraCore-1.11.24/out/Release/ch+0x6c3a9e)
#12 0x561fcc76821f in Js::ScriptContext::LoadScript(unsigned char const*, unsigned long, SRCINFO const*, CompileScriptException*, Js::Utf8SourceInfo**, char16_t const*, LoadScriptFlag, void*) (~/ChakraCore-1.11.24/out/Release/ch+0x6c421f)
#13 0x561fcc52a8ef in RunScriptCore(void*, unsigned char const*, unsigned long, LoadScriptFlag, unsigned long, char16_t const*, bool, _JsParseScriptAttributes, bool, void**) (~/ChakraCore-1.11.24/out/Release/ch+0x4868ef)
#14 0x561fcc534cc5 in JsRun (~/ChakraCore-1.11.24/out/Release/ch+0x490cc5)
#15 0x561fcc432002 in RunScript(char const*, char const*, unsigned long, void (*)(void*), void*, char*, void*) (~/ChakraCore-1.11.24/out/Release/ch+0x38e002)
#16 0x561fcc434380 in ExecuteTest(char const*) (~/ChakraCore-1.11.24/out/Release/ch+0x390380)
#17 0x561fcc435116 in main (~/ChakraCore-1.11.24/out/Release/ch+0x391116)
#18 0x7f91738bac86 in __libc_start_main /build/glibc-uZu3wS/glibc-2.27/csu/../csu/libc-start.c:310
#19 0x561fcc333a69 in _start (~/ChakraCore-1.11.24/out/Release/ch+0x28fa69)
AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV (~/ChakraCore-1.11.24/out/Release/ch+0x177ea33) in EmitBooleanExpression(ParseNode*, int, int, ByteCodeGenerator*, FuncInfo*, bool, bool)
==8178==ABORTING
I debugged this issue further using GBD, it appears to be a null pointer issue, here is the detailed debug info:
(gdb) set disassembly-flavor intel
(gdb) info r
rax 0x42 66
rbx 0x7fffffffb3d8 140737488335832
rcx 0x7fffffffb528 140737488336168
rdx 0x0 0
rsi 0x0 0
rdi 0x7fffffffb598 140737488336280
rbp 0x7fffffff9ba0 0x7fffffff9ba0
rsp 0x7fffffff9ad0 0x7fffffff9ad0
r8 0x7ff7f0b74800 140702872193024
r9 0x1 1
r10 0x0 0
r11 0x0 0
r12 0x7ffff43d3f80 140737291042688
r13 0x140 320
r14 0x7fffffffb9f0 140737488337392
r15 0x7fffffffc5d8 140737488340440
rip 0x7ffff34dcc75 0x7ffff34dcc75 <EmitBooleanExpression(ParseNode*, int, int, ByteCodeGenerator*, FuncInfo*, bool, bool)+229>
eflags 0x10206 [ PF IF RF ]
cs 0x33 51
ss 0x2b 43
ds 0x0 0
es 0x0 0
fs 0x0 0
gs 0x0 0
k0 0x0 0
k1 0x0 0
k2 0x0 0
k3 0x0 0
k4 0x0 0
k5 0x0 0
k6 0x0 0
k7 0x0 0
(gdb) x/i $pc
=> 0x7ffff34dcc75 <EmitBooleanExpression(ParseNode*, int, int, ByteCodeGenerator*, FuncInfo*, bool, bool)+229>: movzx eax,BYTE PTR [rsi]
Combine the above stack information#0 0x00007ffff34dcc75 in EmitBooleanExpression (expr=0x0, trueLabel=10, falseLabel=4, byteCodeGenerator=0x7fffffffb4e0, funcInfo=0x7ff7f0b74800, trueFallthrough=true, falseFallthrough=false) at ~/ChakraCore-1.11.24/lib/Runtime/ByteCode/ByteCodeEmitter.cpp:8835, we can know that the pointer expr value is 0x0, so this is a null pointer problem.
This passes with development version.
This passes with development version.
Thanks for your reply. We tested the latest development version and found this bug has been fixed. I will close this issue soon :)
By the way, I have a few additional findngs summaried as follows: Firstly, I found this security bug has been exposed by a previous issue report #5532 back in 2018, and was quickly fixed. I just wonder why this bug still exits after fixed.
Secondly, through the detailed annalysis, I think this bug is caused due to the incomplete repair of #5332.