Closed Bug 1209501 Opened 10 years ago Closed 8 years ago

Crash [@ js::frontend::TokenStream::TokenBuf::findEOLMax] with Debugger and use-after-free

Categories

(Core :: JavaScript Engine, defect)

x86
Linux
defect
Not set
critical

Tracking

()

RESOLVED DUPLICATE of bug 1161312

People

(Reporter: decoder, Unassigned)

References

Details

(4 keywords, Whiteboard: [jsbugmon:])

Crash Data

The following testcase crashes on mozilla-central revision 6256ec9113c1 (build with --enable-gczeal --enable-optimize="-O2 -g" --enable-address-sanitizer --target=i686-pc-linux-gnu --without-intl-api --enable-posix-nspr-emulation --disable-jemalloc --disable-tests --disable-debug, run with --fuzzing-safe --thread-count=2 --ion-eager --ion-offthread-compile=off --ion-extra-checks): var g = newGlobal(false); var dbg = new Debugger; var gw = dbg.addDebuggee(g); g.evaluate("function f(x) { return 2*x; }", Error(typeof newGlobal(), "object")); var fw = gw.getOwnPropertyDescriptor('f').value; Backtrace: ==29507==ERROR: AddressSanitizer: heap-buffer-overflow on address 0xe2a4d1b8 at pc 0x85ef15d bp 0xff92fd38 sp 0xff92fd2c READ of size 2 at 0xe2a4d1b8 thread T0 #0 0x85ef15c in js::frontend::TokenStream::TokenBuf::findEOLMax(unsigned int, unsigned int) js/src/frontend/TokenStream.cpp:491 #1 0x85ef15c in js::frontend::TokenStream::reportCompileErrorNumberVA(unsigned int, unsigned int, unsigned int, char*) js/src/frontend/TokenStream.cpp:686 #2 0x85d9e45 in js::frontend::TokenStream::reportError(unsigned int, ...) js/src/frontend/TokenStream.cpp:733 #3 0x86656ec in js::frontend::TokenStream::getTokenInternal(js::frontend::TokenKind*, js::frontend::Token::Modifier) js/src/frontend/TokenStream.cpp:1235 #4 0x81dbbb7 in js::frontend::TokenStream::peekTokenPos(js::frontend::TokenPos*, js::frontend::Token::Modifier) js/src/frontend/TokenStream.h:571 #5 0x81dbbb7 in js::frontend::Parser<js::frontend::FullParseHandler>::standaloneLazyFunction(JS::Handle<JSFunction*>, bool, js::GeneratorKind) js/src/frontend/Parser.cpp:2703 #6 0x85d3667 in js::frontend::CompileLazyFunction(JSContext*, JS::Handle<js::LazyScript*>, char16_t const*, unsigned int) js/src/frontend/BytecodeCompiler.cpp:867 #7 0x9837d0b in JSFunction::createScriptForLazilyInterpretedFunction(JSContext*, JS::Handle<JSFunction*>) js/src/jsfun.cpp:1407 #8 0x9836dd7 in JSFunction::getOrCreateScript(JSContext*) js/src/jsfun.h:383 #9 0x9836dd7 in js::LazyScript::functionDelazifying(JSContext*) const js/src/jsscriptinlines.h:90 #10 0x9836dd7 in JSFunction::createScriptForLazilyInterpretedFunction(JSContext*, JS::Handle<JSFunction*>) js/src/jsfun.cpp:1358 #11 0x86f1683 in JSFunction::getOrCreateScript(JSContext*) js/src/jsfun.h:383 #12 0x86f1683 in EnsureFunctionHasScript(JSContext*, JS::Handle<JSFunction*>) js/src/vm/Debugger.cpp:116 #13 0x86f1683 in js::Debugger::wrapDebuggeeValue(JSContext*, JS::MutableHandle<JS::Value>) js/src/vm/Debugger.cpp:813 #14 0x878f948 in DebuggerObject_getOwnPropertyDescriptor(JSContext*, unsigned int, JS::Value*) js/src/vm/Debugger.cpp:7201 #15 0x8884879 in js::CallJSNative(JSContext*, bool (*)(JSContext*, unsigned int, JS::Value*), JS::CallArgs const&) js/src/jscntxtinlines.h:235 #16 0x8884879 in js::Invoke(JSContext*, JS::CallArgs const&, js::MaybeConstruct) js/src/vm/Interpreter.cpp:768 #17 0x8887184 in js::Invoke(JSContext*, JS::Value const&, JS::Value const&, unsigned int, JS::Value const*, JS::MutableHandle<JS::Value>) js/src/vm/Interpreter.cpp:823 #18 0x8ec790b in js::jit::DoCallFallback(JSContext*, js::jit::BaselineFrame*, js::jit::ICCall_Fallback*, unsigned int, JS::Value*, JS::MutableHandle<JS::Value>) js/src/jit/BaselineIC.cpp:8904 0xe2a4d1b8 is located 0 bytes to the right of 56-byte region [0xe2a4d180,0xe2a4d1b8) allocated by thread T0 here: #0 0x80eefb4 in __interceptor_malloc /srv/repos/llvm/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:74 #1 0x8161b82 in js_malloc(unsigned int) js/src/opt32asan/js/src/../../dist/include/js/Utility.h:226 #2 0x8161b82 in _ZL13js_pod_mallocIhEPT_j js/src/opt32asan/js/src/../../dist/include/js/Utility.h:381 #3 0x8161b82 in unsigned char* js::MallocProvider<js::ExclusiveContext>::pod_malloc<unsigned char>(unsigned int) js/src/vm/MallocProvider.h:63 #4 0x85b5ba0 in js::ScriptSource* js::MallocProvider<js::ExclusiveContext>::new_<js::ScriptSource>() js/src/vm/MallocProvider.h:178 #5 0x85b5ba0 in js::frontend::CreateScriptSourceObject(js::ExclusiveContext*, JS::ReadOnlyCompileOptions const&) js/src/frontend/BytecodeCompiler.cpp:753 #6 0x85b7894 in BytecodeCompiler::createScriptSource() js/src/frontend/BytecodeCompiler.cpp:188 #7 0x85b7894 in BytecodeCompiler::createSourceAndParser() js/src/frontend/BytecodeCompiler.cpp:253 #8 0x85c53e2 in BytecodeCompiler::compileScript(JS::Handle<JSObject*>, JS::Handle<JSScript*>) js/src/frontend/BytecodeCompiler.cpp:540 #9 0x85d1d78 in js::frontend::CompileScript(js::ExclusiveContext*, js::LifoAlloc*, JS::Handle<JSObject*>, JS::Handle<js::ScopeObject*>, JS::Handle<JSScript*>, JS::ReadOnlyCompileOptions const&, JS::SourceBufferHolder&, JSString*, js::SourceCompressionTask*, js::ScriptSourceObject**) js/src/frontend/BytecodeCompiler.cpp:807 #10 0x97aa5fe in Compile(JSContext*, JS::ReadOnlyCompileOptions const&, SyntacticScopeOption, JS::SourceBufferHolder&, JS::MutableHandle<JSScript*>) js/src/jsapi.cpp:3976 #11 0x97ab196 in Compile(JSContext*, JS::ReadOnlyCompileOptions const&, SyntacticScopeOption, char16_t const*, unsigned int, JS::MutableHandle<JSScript*>) js/src/jsapi.cpp:3986 #12 0x97ab196 in JS::Compile(JSContext*, JS::ReadOnlyCompileOptions const&, char16_t const*, unsigned int, JS::MutableHandle<JSScript*>) js/src/jsapi.cpp:4045 #13 0x813a6b7 in Evaluate(JSContext*, unsigned int, JS::Value*) js/src/shell/js.cpp:1206 #14 0x8884879 in js::CallJSNative(JSContext*, bool (*)(JSContext*, unsigned int, JS::Value*), JS::CallArgs const&) js/src/jscntxtinlines.h:235 #15 0x8884879 in js::Invoke(JSContext*, JS::CallArgs const&, js::MaybeConstruct) js/src/vm/Interpreter.cpp:768 #16 0x8887184 in js::Invoke(JSContext*, JS::Value const&, JS::Value const&, unsigned int, JS::Value const*, JS::MutableHandle<JS::Value>) js/src/vm/Interpreter.cpp:823 #17 0x9a5cce1 in js::DirectProxyHandler::call(JSContext*, JS::Handle<JSObject*>, JS::CallArgs const&) const js/src/proxy/DirectProxyHandler.cpp:77 #18 0x9a5cce1 in js::CrossCompartmentWrapper::call(JSContext*, JS::Handle<JSObject*>, JS::CallArgs const&) const js/src/proxy/CrossCompartmentWrapper.cpp:289 #19 0x9a78217 in js::Proxy::call(JSContext*, JS::Handle<JSObject*>, JS::CallArgs const&) js/src/proxy/Proxy.cpp:412 #20 0x9a7e0cc in js::proxy_Call(JSContext*, unsigned int, JS::Value*) js/src/proxy/Proxy.cpp:724 #21 0x8884d24 in js::CallJSNative(JSContext*, bool (*)(JSContext*, unsigned int, JS::Value*), JS::CallArgs const&) js/src/jscntxtinlines.h:235 #22 0x8884d24 in js::Invoke(JSContext*, JS::CallArgs const&, js::MaybeConstruct) js/src/vm/Interpreter.cpp:756 #23 0x8887184 in js::Invoke(JSContext*, JS::Value const&, JS::Value const&, unsigned int, JS::Value const*, JS::MutableHandle<JS::Value>) js/src/vm/Interpreter.cpp:823 #24 0x8ec790b in js::jit::DoCallFallback(JSContext*, js::jit::BaselineFrame*, js::jit::ICCall_Fallback*, unsigned int, JS::Value*, JS::MutableHandle<JS::Value>) js/src/jit/BaselineIC.cpp:8904 SUMMARY: AddressSanitizer: heap-buffer-overflow js/src/frontend/TokenStream.cpp:491 js::frontend::TokenStream::TokenBuf::findEOLMax(unsigned int, unsigned int) Shadow bytes around the buggy address: 0x3c549a20: fa fa fa fa 00 00 00 00 00 00 00 02 fa fa fa fa =>0x3c549a30: 00 00 00 00 00 00 00[fa]fa fa fa fa fd fd fd fd 0x3c549a40: fd fd fd fd fa fa fa fa 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 Freed heap region: fd Not s-s because it requires the debugger.
Passing in an Error object as second argument to evaluate() looks like bug 1161312, maybe.
Group: javascript-core-security
Whiteboard: [jsbugmon:update,bisect] → [jsbugmon:bisect]
JSBugMon: Cannot process bug: Unable to automatically reproduce, please track manually.
Whiteboard: [jsbugmon:bisect] → [jsbugmon:]
Whiteboard: [jsbugmon:] → [jsbugmon:update]
Whiteboard: [jsbugmon:update] → [jsbugmon:]
JSBugMon: Cannot process bug: Unable to automatically reproduce, please track manually.
(In reply to Jeff Walden [:Waldo] (remove +bmo to email) from comment #1) > Passing in an Error object as second argument to evaluate() looks like bug > 1161312, maybe. Waldo, please double check that this bug is a dupe (if it is) of that bug, whenever that's fixed or whenever suitable.
Flags: needinfo?(jwalden+bmo)
Shu-yu, since you're fixing bug 1161312, is this a likely dupe of that?
Flags: needinfo?(jwalden+bmo) → needinfo?(shu)
Yes, this is the same bug. Here, the fuzzer hit it by passing in an Error object as the options object to |evaluate|. Error objects happen to also have a "columNumber" property.
Status: NEW → RESOLVED
Closed: 8 years ago
Flags: needinfo?(shu)
Resolution: --- → DUPLICATE
Group: javascript-core-security
You need to log in before you can comment on or make changes to this bug.