Closed Bug 1006205 Opened 10 years ago Closed 10 years ago

ASan use-after-free [@ js::jit::BaselineScript::numICEntries] with Debugger

Categories

(Core :: JavaScript Engine: JIT, defect)

x86
Linux
defect
Not set
critical

Tracking

()

RESOLVED FIXED
mozilla32
Tracking Status
firefox32 --- fixed

People

(Reporter: decoder, Assigned: shu)

Details

(Keywords: csectype-uaf, testcase)

Attachments

(2 files)

The following testcase shows use-after-free on mozilla-central revision 1204667a2935 (run with --fuzzing-safe --ion-eager):


var lfcode = new Array();
lfcode.push = loadFile;
lfcode.push("\
var g = newGlobal();\
g.debuggeeGlobal = this;\
g.eval(\"(\" + function () {\
        dbg = new Debugger(debuggeeGlobal);\
    } + \")();\");\
");
lfcode.push("gc();");
lfcode.push("\
var g = newGlobal();\
g.debuggeeGlobal = this;\
g.eval(\"(\" + function () {\
  dbg = new Debugger(debuggeeGlobal);\
} + \")();\");\
");
function loadFile(lfVarx) {
function newFunc(x) { new Function(x)(); }; newFunc(lfVarx);
}
Crash trace:

=================================================================                                                                                                                                            
==31253==ERROR: AddressSanitizer: heap-use-after-free on address 0xf4a0b83c at pc 0x857e985 bp 0xff92aee8 sp 0xff92aee0                                                                                      
READ of size 4 at 0xf4a0b83c thread T0                                                                                                                                                                       
    #0 0x857e984 in js::jit::BaselineScript::numICEntries() const jit/BaselineJIT.h:303                                                                                    
    #1 0x857e984 in js::jit::BaselineScript::icEntryFromPCOffset(unsigned int) jit/BaselineJIT.cpp:534                                                                     
    #2 0x85235fe in PatchBaselineFramesForDebugMode(JSContext*, js::jit::JitActivationIterator const&, js::Vector<DebugModeOSREntry, 0u, js::TempAllocPolicy>&, unsigned int*) /srv/repos/mozilla-central/js/
src/jit/BaselineDebugModeOSR.cpp:280                                                                                                                                                                         
    #3 0x85235fe in js::jit::RecompileOnStackBaselineScriptsForDebugMode(JSContext*, JSCompartment*) jit/BaselineDebugModeOSR.cpp:596                                      
    #4 0x8797764 in js::jit::UpdateForDebugMode(JSContext*, JSCompartment*, js::AutoDebugModeInvalidation&) jit/Ion.cpp:3057                                               
    #5 0x8bebc4c in JSCompartment::updateJITForDebugMode(JSContext*, js::AutoDebugModeInvalidation&) jscompartment.cpp:812                                                 
    #6 0x8bebc4c in JSCompartment::addDebuggee(JSContext*, js::GlobalObject*, js::AutoDebugModeInvalidation&) jscompartment.cpp:838                                        
    #7 0x8f9d71e in js::Debugger::addDebuggeeGlobal(JSContext*, JS::Handle<js::GlobalObject*>, js::AutoDebugModeInvalidation&) vm/Debugger.cpp:2276                        
    #8 0x8fa2041 in js::Debugger::addDebuggeeGlobal(JSContext*, JS::Handle<js::GlobalObject*>) vm/Debugger.cpp:2210                                                        
    #9 0x8fa2041 in js::Debugger::construct(JSContext*, unsigned int, JS::Value*) vm/Debugger.cpp:2198                                                                     
    #10 0x90b6d6d in js::CallJSNative(JSContext*, bool (*)(JSContext*, unsigned int, JS::Value*), JS::CallArgs const&) jscntxtinlines.h:239
   [...]                                                                                                                                                                             
0xf4a0b83c is located 60 bytes inside of 344-byte region [0xf4a0b800,0xf4a0b958)                                                                                                                             
freed by thread T0 here:                                                                                                                                                                                     
    #0 0x8108b60 in free /srv/repos/llvm/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:64                                                                                                               
    #1 0x8525c11 in js_free(void*) opt32asan/js/src/../../dist/include/js/Utility.h:128                                                                                    
    #2 0x8525c11 in js::FreeOp::free_(void*) vm/Runtime.h:1477                                                                                                             
    #3 0x8525c11 in void js::FreeOp::delete_<js::jit::BaselineScript>(js::jit::BaselineScript*) vm/Runtime.h:382                                                           
    #4 0x8525c11 in js::jit::BaselineScript::Destroy(js::FreeOp*, js::jit::BaselineScript*) jit/BaselineJIT.cpp:461                                                        
    #5 0x8524117 in js::jit::RecompileOnStackBaselineScriptsForDebugMode(JSContext*, JSCompartment*) jit/BaselineDebugModeOSR.cpp:591                                      
    #6 0x8797764 in js::jit::UpdateForDebugMode(JSContext*, JSCompartment*, js::AutoDebugModeInvalidation&) jit/Ion.cpp:3057                                               
    #7 0x8bebc4c in JSCompartment::updateJITForDebugMode(JSContext*, js::AutoDebugModeInvalidation&) jscompartment.cpp:812
    [...]                                                                                                                                                                                  
previously allocated by thread T0 here:                                                                                                                                                                      
    #0 0x8108ce0 in malloc /srv/repos/llvm/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:74 
    #1 0x84e6009 in js_malloc(unsigned int) opt32asan/js/src/../../dist/include/js/Utility.h:105                                                                           
    #2 0x84e6009 in js::MallocProvider<js::ThreadSafeContext>::malloc_(unsigned int) vm/MallocProvider.h:53                                                                
    #3 0x84e6009 in js::jit::BaselineScript::New(JSContext*, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int) jit/BaselineJIT.cpp:388                                                                                                                                                                                    
    #4 0x84dd8e3 in js::jit::BaselineCompiler::compile() jit/BaselineCompiler.cpp:185                                                                                      
    #5 0x85fa9db in js::jit::BaselineCompile(JSContext*, JSScript*) jit/BaselineJIT.cpp:239                                                                                
    #6 0x8521816 in RecompileBaselineScriptForDebugMode(JSContext*, JSScript*) jit/BaselineDebugModeOSR.cpp:422                                                            
    #7 0x8521816 in js::jit::RecompileOnStackBaselineScriptsForDebugMode(JSContext*, JSCompartment*) jit/BaselineDebugModeOSR.cpp:577                                      
    #8 0x8797764 in js::jit::UpdateForDebugMode(JSContext*, JSCompartment*, js::AutoDebugModeInvalidation&) jit/Ion.cpp:3057                                               
    #9 0x8bebc4c in JSCompartment::updateJITForDebugMode(JSContext*, js::AutoDebugModeInvalidation&) jscompartment.cpp:812
    [...]                                                                                   
SUMMARY: AddressSanitizer: heap-use-after-free jit/BaselineJIT.h:303 js::jit::BaselineScript::numICEntries() const  


Not s-s because this is in the debugger.
It can happen that GCing the debugger can turn off a compartment's debug mode.
We can't recompile scripts from inside GC, so the on-stack scripts are
untouched. When debug mode is toggled on again, BaselineScripts already in
debug mode are erroneously destroyed.

I also included some spew format changes because %llx was crashing on 32bit.
Attachment #8417756 - Flags: review?(jdemooij)
Attachment #8417756 - Flags: review?(jdemooij) → review+
https://hg.mozilla.org/mozilla-central/rev/9694b5d763ac
Status: NEW → RESOLVED
Closed: 10 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla32
Assignee: nobody → shu
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: