Crash with heap-use-after-free [@ JS::Rooted<JSFunction*>::init]

RESOLVED FIXED in Firefox 43

Status

()

Core
JavaScript Engine
--
critical
RESOLVED FIXED
3 years ago
9 months ago

People

(Reporter: decoder, Assigned: shu)

Tracking

(Blocks: 1 bug, 4 keywords)

Trunk
mozilla43
x86_64
Linux
crash, csectype-uaf, regression, testcase
Points:
---
Bug Flags:
in-testsuite +

Firefox Tracking Flags

(firefox40 affected, firefox43 fixed)

Details

(Whiteboard: [jsbugmon:], crash signature)

Attachments

(1 attachment)

(Reporter)

Description

3 years ago
The following testcase crashes on mozilla-central revision dc5f85980a82 (build with --enable-gczeal --enable-optimize="-O2 -g" --enable-address-sanitizer --enable-posix-nspr-emulation --disable-jemalloc --disable-tests --disable-debug, run with --fuzzing-safe --thread-count=2):

var g = newGlobal();
g.eval('function f(a) { if (a == 1) debugger; evaluate("f(" + a + " - 1);", {newContext: true}); }');
var N = 9;
var dbg = new Debugger(g);
var frames = [];
dbg.onEnterFrame = function (frame) {
   frames.push(frame);
   frame.onPop = function () { assertEq(frame.onPop, frame); };
};
dbg.onDebuggerStatement = function (frame) {
    for (var f of frames)
        assertEq(f.eval('a').return, i--);
};
evaluate("g.f(N);");



Backtrace:

==28450==ERROR: AddressSanitizer: heap-use-after-free on address 0x613000034318 at pc 0x10487c7 bp 0x7fff87560f90 sp 0x7fff87560f88
READ of size 8 at 0x613000034318 thread T0
    #0 0x10487c6 in void JS::Rooted<JSFunction*>::init<js::ContextFriendFields>(js::ContextFriendFields*) js/src/opt64asan/js/src/../../dist/include/js/RootingAPI.h:702
    #1 0x10487c6 in SnapshotIterator js/src/opt64asan/js/src/../../dist/include/js/RootingAPI.h:712
    #2 0x10487c6 in js::jit::InlineFrameIterator::InlineFrameIterator(JSContext*, js::jit::JitFrameIterator const*) js/src/jit/JitFrames.cpp:2347
    #3 0xb1a634 in js::FrameIter::FrameIter(js::FrameIter::Data const&) js/src/vm/Stack.cpp:663
    #4 0x998c50 in ScriptFrameIter js/src/vm/Stack.h:1781
    #5 0x998c50 in DebuggerFrame_getOnPop(JSContext*, unsigned int, JS::Value*) js/src/vm/Debugger.cpp:6132
    #6 0xd542a8 in js::jit::DoCallNativeGetter(JSContext*, JS::Handle<JSFunction*>, JS::Handle<JSObject*>, JS::MutableHandle<JS::Value>) js/src/jit/BaselineIC.cpp:1661

0x613000034318 is located 24 bytes inside of 360-byte region [0x613000034300,0x613000034468)
freed by thread T0 here:
    #0 0x4ac07f in __interceptor_free /srv/repos/llvm/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:64
    #1 0x4fda32 in DestroyContext(JSContext*, bool) js/src/shell/js.cpp:5624
    #2 0x4fda32 in AutoNewContext::~AutoNewContext() js/src/shell/js.cpp:1007
    #3 0x4e607c in Evaluate(JSContext*, unsigned int, JS::Value*) js/src/shell/js.cpp:1366
    #4 0x8e400f in js::CallJSNative(JSContext*, bool (*)(JSContext*, unsigned int, JS::Value*), JS::CallArgs const&) js/src/jscntxtinlines.h:235
    #5 0x8e400f in js::Invoke(JSContext*, JS::CallArgs, js::MaybeConstruct) js/src/vm/Interpreter.cpp:720
    #6 0x9250dc in Interpret(JSContext*, js::RunState&) js/src/vm/Interpreter.cpp:2956
    #7 0x9041f1 in js::RunScript(JSContext*, js::RunState&) js/src/vm/Interpreter.cpp:677
    #8 0x936b0d in js::ExecuteKernel(JSContext*, JS::Handle<JSScript*>, JSObject&, JS::Value const&, js::ExecuteType, js::AbstractFramePtr, JS::Value*) js/src/vm/Interpreter.cpp:902
    #9 0x937154 in js::Execute(JSContext*, JS::Handle<JSScript*>, JSObject&, JS::Value*) js/src/vm/Interpreter.cpp:941
    #10 0x1409a2d in ExecuteScript(JSContext*, JS::Handle<JSObject*>, JS::Handle<JSScript*>, JS::Value*) js/src/jsapi.cpp:4159
    #11 0x4e63cd in Evaluate(JSContext*, unsigned int, JS::Value*) js/src/shell/js.cpp:1327
    #12 0x8e400f in js::CallJSNative(JSContext*, bool (*)(JSContext*, unsigned int, JS::Value*), JS::CallArgs const&) js/src/jscntxtinlines.h:235
    #13 0x8e400f in js::Invoke(JSContext*, JS::CallArgs, js::MaybeConstruct) js/src/vm/Interpreter.cpp:720
    #14 0x9250dc in Interpret(JSContext*, js::RunState&) js/src/vm/Interpreter.cpp:2956
    #15 0x9041f1 in js::RunScript(JSContext*, js::RunState&) js/src/vm/Interpreter.cpp:677
    #16 0x936b0d in js::ExecuteKernel(JSContext*, JS::Handle<JSScript*>, JSObject&, JS::Value const&, js::ExecuteType, js::AbstractFramePtr, JS::Value*) js/src/vm/Interpreter.cpp:902
    #17 0x937154 in js::Execute(JSContext*, JS::Handle<JSScript*>, JSObject&, JS::Value*) js/src/vm/Interpreter.cpp:941
    #18 0x1409a2d in ExecuteScript(JSContext*, JS::Handle<JSObject*>, JS::Handle<JSScript*>, JS::Value*) js/src/jsapi.cpp:4159
    #19 0x4e63cd in Evaluate(JSContext*, unsigned int, JS::Value*) js/src/shell/js.cpp:1327
    #20 0x8e400f in js::CallJSNative(JSContext*, bool (*)(JSContext*, unsigned int, JS::Value*), JS::CallArgs const&) js/src/jscntxtinlines.h:235
    #21 0x8e400f in js::Invoke(JSContext*, JS::CallArgs, js::MaybeConstruct) js/src/vm/Interpreter.cpp:720
    #22 0x9250dc in Interpret(JSContext*, js::RunState&) js/src/vm/Interpreter.cpp:2956
    #23 0x9041f1 in js::RunScript(JSContext*, js::RunState&) js/src/vm/Interpreter.cpp:677
    #24 0x936b0d in js::ExecuteKernel(JSContext*, JS::Handle<JSScript*>, JSObject&, JS::Value const&, js::ExecuteType, js::AbstractFramePtr, JS::Value*) js/src/vm/Interpreter.cpp:902
    #25 0x937154 in js::Execute(JSContext*, JS::Handle<JSScript*>, JSObject&, JS::Value*) js/src/vm/Interpreter.cpp:941
    #26 0x1409a2d in ExecuteScript(JSContext*, JS::Handle<JSObject*>, JS::Handle<JSScript*>, JS::Value*) js/src/jsapi.cpp:4159
    #27 0x4e63cd in Evaluate(JSContext*, unsigned int, JS::Value*) js/src/shell/js.cpp:1327
    #28 0x8e400f in js::CallJSNative(JSContext*, bool (*)(JSContext*, unsigned int, JS::Value*), JS::CallArgs const&) js/src/jscntxtinlines.h:235
    #29 0x8e400f in js::Invoke(JSContext*, JS::CallArgs, js::MaybeConstruct) js/src/vm/Interpreter.cpp:720
    #30 0x9250dc in Interpret(JSContext*, js::RunState&) js/src/vm/Interpreter.cpp:2956
    #31 0x9041f1 in js::RunScript(JSContext*, js::RunState&) js/src/vm/Interpreter.cpp:677
    #32 0x936b0d in js::ExecuteKernel(JSContext*, JS::Handle<JSScript*>, JSObject&, JS::Value const&, js::ExecuteType, js::AbstractFramePtr, JS::Value*) js/src/vm/Interpreter.cpp:902
    #33 0x937154 in js::Execute(JSContext*, JS::Handle<JSScript*>, JSObject&, JS::Value*) js/src/vm/Interpreter.cpp:941
    #34 0x1409a2d in ExecuteScript(JSContext*, JS::Handle<JSObject*>, JS::Handle<JSScript*>, JS::Value*) js/src/jsapi.cpp:4159

previously allocated by thread T0 here:
    #0 0x4ac297 in __interceptor_malloc /srv/repos/llvm/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:74
    #1 0x13e4452 in js_malloc(unsigned long) js/src/opt64asan/js/src/../../dist/include/js/Utility.h:119
    #2 0x13e4452 in _ZL6js_newI9JSContextJRP9JSRuntimeEEPT_DpOT0_ js/src/opt64asan/js/src/../../dist/include/js/Utility.h:231
    #3 0x13e4452 in js::NewContext(JSRuntime*, unsigned long) js/src/jscntxt.cpp:101
    #4 0x4fd09f in NewContext(JSRuntime*) js/src/shell/js.cpp:5601
    #5 0x4fd09f in AutoNewContext::enter(JSContext*) js/src/shell/js.cpp:985
    #6 0x4e4df0 in Evaluate(JSContext*, unsigned int, JS::Value*) js/src/shell/js.cpp:1256
    #7 0x8e400f in js::CallJSNative(JSContext*, bool (*)(JSContext*, unsigned int, JS::Value*), JS::CallArgs const&) js/src/jscntxtinlines.h:235
    #8 0x8e400f in js::Invoke(JSContext*, JS::CallArgs, js::MaybeConstruct) js/src/vm/Interpreter.cpp:720
    #9 0x9250dc in Interpret(JSContext*, js::RunState&) js/src/vm/Interpreter.cpp:2956
    #10 0x9041f1 in js::RunScript(JSContext*, js::RunState&) js/src/vm/Interpreter.cpp:677
    #11 0x936b0d in js::ExecuteKernel(JSContext*, JS::Handle<JSScript*>, JSObject&, JS::Value const&, js::ExecuteType, js::AbstractFramePtr, JS::Value*) js/src/vm/Interpreter.cpp:902
    #12 0x937154 in js::Execute(JSContext*, JS::Handle<JSScript*>, JSObject&, JS::Value*) js/src/vm/Interpreter.cpp:941
    #13 0x1409a2d in ExecuteScript(JSContext*, JS::Handle<JSObject*>, JS::Handle<JSScript*>, JS::Value*) js/src/jsapi.cpp:4159
    #14 0x4e63cd in Evaluate(JSContext*, unsigned int, JS::Value*) js/src/shell/js.cpp:1327
    #15 0x8e400f in js::CallJSNative(JSContext*, bool (*)(JSContext*, unsigned int, JS::Value*), JS::CallArgs const&) js/src/jscntxtinlines.h:235
    #16 0x8e400f in js::Invoke(JSContext*, JS::CallArgs, js::MaybeConstruct) js/src/vm/Interpreter.cpp:720
    #17 0x9250dc in Interpret(JSContext*, js::RunState&) js/src/vm/Interpreter.cpp:2956
    #18 0x9041f1 in js::RunScript(JSContext*, js::RunState&) js/src/vm/Interpreter.cpp:677
    #19 0x936b0d in js::ExecuteKernel(JSContext*, JS::Handle<JSScript*>, JSObject&, JS::Value const&, js::ExecuteType, js::AbstractFramePtr, JS::Value*) js/src/vm/Interpreter.cpp:902
    #20 0x937154 in js::Execute(JSContext*, JS::Handle<JSScript*>, JSObject&, JS::Value*) js/src/vm/Interpreter.cpp:941
    #21 0x1409a2d in ExecuteScript(JSContext*, JS::Handle<JSObject*>, JS::Handle<JSScript*>, JS::Value*) js/src/jsapi.cpp:4159
    #22 0x4e63cd in Evaluate(JSContext*, unsigned int, JS::Value*) js/src/shell/js.cpp:1327
    #23 0x8e400f in js::CallJSNative(JSContext*, bool (*)(JSContext*, unsigned int, JS::Value*), JS::CallArgs const&) js/src/jscntxtinlines.h:235
    #24 0x8e400f in js::Invoke(JSContext*, JS::CallArgs, js::MaybeConstruct) js/src/vm/Interpreter.cpp:720
    #25 0x9250dc in Interpret(JSContext*, js::RunState&) js/src/vm/Interpreter.cpp:2956
    #26 0x9041f1 in js::RunScript(JSContext*, js::RunState&) js/src/vm/Interpreter.cpp:677
    #27 0x936b0d in js::ExecuteKernel(JSContext*, JS::Handle<JSScript*>, JSObject&, JS::Value const&, js::ExecuteType, js::AbstractFramePtr, JS::Value*) js/src/vm/Interpreter.cpp:902
    #28 0x937154 in js::Execute(JSContext*, JS::Handle<JSScript*>, JSObject&, JS::Value*) js/src/vm/Interpreter.cpp:941
    #29 0x1409a2d in ExecuteScript(JSContext*, JS::Handle<JSObject*>, JS::Handle<JSScript*>, JS::Value*) js/src/jsapi.cpp:4159
    #30 0x4e63cd in Evaluate(JSContext*, unsigned int, JS::Value*) js/src/shell/js.cpp:1327
    #31 0x8e400f in js::CallJSNative(JSContext*, bool (*)(JSContext*, unsigned int, JS::Value*), JS::CallArgs const&) js/src/jscntxtinlines.h:235
    #32 0x8e400f in js::Invoke(JSContext*, JS::CallArgs, js::MaybeConstruct) js/src/vm/Interpreter.cpp:720
    #33 0x9250dc in Interpret(JSContext*, js::RunState&) js/src/vm/Interpreter.cpp:2956
    #34 0x9041f1 in js::RunScript(JSContext*, js::RunState&) js/src/vm/Interpreter.cpp:677
    #35 0x936b0d in js::ExecuteKernel(JSContext*, JS::Handle<JSScript*>, JSObject&, JS::Value const&, js::ExecuteType, js::AbstractFramePtr, JS::Value*) js/src/vm/Interpreter.cpp:902
    #36 0x937154 in js::Execute(JSContext*, JS::Handle<JSScript*>, JSObject&, JS::Value*) js/src/vm/Interpreter.cpp:941

SUMMARY: AddressSanitizer: heap-use-after-free js/src/opt64asan/js/src/../../dist/include/js/RootingAPI.h:702 void JS::Rooted<JSFunction*>::init<js::ContextFriendFields>(js::ContextFriendFields*)
Shadow bytes around the buggy address:
  0x0c267fffe810: 00 00 00 00 00 00 00 00 00 00 00 fa fa fa fa fa
  0x0c267fffe820: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd
  0x0c267fffe830: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c267fffe840: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c267fffe850: fd fd fd fd fd fd fd fd fa fa fa fa fa fa fa fa
=>0x0c267fffe860: fd fd fd[fd]fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c267fffe870: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c267fffe880: fd fd fd fd fd fd fd fd fd fd fd fd fd fa fa fa
  0x0c267fffe890: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd
  0x0c267fffe8a0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c267fffe8b0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
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
  Heap right redzone:      fb
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack partial redzone:   f4
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Contiguous container OOB:fc
  ASan internal:           fe
==28450==ABORTING
(Reporter)

Updated

3 years ago
Whiteboard: [jsbugmon:update,bisect] → [jsbugmon:bisect]
(Reporter)

Comment 1

3 years ago
JSBugMon: Cannot process bug: Unable to automatically reproduce, please track manually.
(Reporter)

Updated

3 years ago
Whiteboard: [jsbugmon:bisect] → [jsbugmon:]
(Assignee)

Comment 2

3 years ago
Created attachment 8644687 [details] [diff] [review]
Don't save the JSContext when saving FrameIter::Data.
Attachment #8644687 - Flags: review?(jimb)
(Assignee)

Updated

3 years ago
Assignee: nobody → shu
Status: NEW → ASSIGNED

Comment 3

3 years ago
Comment on attachment 8644687 [details] [diff] [review]
Don't save the JSContext when saving FrameIter::Data.

Review of attachment 8644687 [details] [diff] [review]:
-----------------------------------------------------------------

This is missing the test case. r=me with that added.
Attachment #8644687 - Flags: review?(jimb) → review+
https://hg.mozilla.org/mozilla-central/rev/80dbbf6dab20
Status: ASSIGNED → RESOLVED
Last Resolved: 3 years ago
status-firefox43: --- → fixed
Flags: in-testsuite+
Resolution: --- → FIXED
Target Milestone: --- → mozilla43
Keywords: csectype-uaf
You need to log in before you can comment on or make changes to this bug.