Closed Bug 1232682 Opened 10 years ago Closed 10 years ago

Crash [@ js::frontend::TokenStream::TokenBuf::findEOLMax] with heap-buffer-overflow

Categories

(Core :: JavaScript Engine, defect)

x86
Linux
defect
Not set
critical

Tracking

()

RESOLVED DUPLICATE of bug 1161312
Tracking Status
firefox46 --- wontfix

People

(Reporter: decoder, Unassigned)

References

Details

(Keywords: crash, regression, testcase, Whiteboard: [fuzzblocker] [jsbugmon:])

Crash Data

The following testcase crashes on mozilla-central revision 871d92a1b070 (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 --baseline-eager): evaluate('function g() { f(); }', { columnNumber: true }); g(0); Backtrace: ==32612==ERROR: AddressSanitizer: heap-buffer-overflow on address 0xf5224a3a at pc 0x992e05d bp 0xfff888d8 sp 0xfff888cc READ of size 2 at 0xf5224a3a thread T0 #0 0x992e05c in js::frontend::TokenStream::TokenBuf::findEOLMax(unsigned int, unsigned int) js/src/frontend/TokenStream.cpp:490 #1 0x992e05c in js::frontend::TokenStream::reportCompileErrorNumberVA(unsigned int, unsigned int, unsigned int, char*) js/src/frontend/TokenStream.cpp:685 #2 0x81f7925 in js::frontend::Parser<js::frontend::FullParseHandler>::reportHelper(js::frontend::ParseReportKind, bool, unsigned int, unsigned int, char*) js/src/frontend/Parser.cpp:574 #3 0x81f7925 in js::frontend::Parser<js::frontend::FullParseHandler>::report(js::frontend::ParseReportKind, bool, js::frontend::ParseNode*, unsigned int, ...) js/src/frontend/Parser.h:598 #4 0x8226a74 in js::frontend::Parser<js::frontend::FullParseHandler>::functionArguments(js::frontend::YieldHandling, js::frontend::FunctionSyntaxKind, js::frontend::ParseNode*, bool*) js/src/frontend/Parser.cpp:2229 #5 0x8224f29 in js::frontend::Parser<js::frontend::FullParseHandler>::functionArgsAndBodyGeneric(js::frontend::InHandling, js::frontend::YieldHandling, js::frontend::ParseNode*, JS::Handle<JSFunction*>, js::frontend::FunctionSyntaxKind) js/src/frontend/Parser.cpp:3029 #6 0x81ea39b in js::frontend::Parser<js::frontend::FullParseHandler>::standaloneLazyFunction(JS::Handle<JSFunction*>, bool, js::GeneratorKind) js/src/frontend/Parser.cpp:2994 #7 0x988a14e in js::frontend::CompileLazyFunction(JSContext*, JS::Handle<js::LazyScript*>, char16_t const*, unsigned int) js/src/frontend/BytecodeCompiler.cpp:799 #8 0x8fef92d in JSFunction::createScriptForLazilyInterpretedFunction(JSContext*, JS::Handle<JSFunction*>) js/src/jsfun.cpp:1427 #9 0x8feea18 in JSFunction::getOrCreateScript(JSContext*) js/src/jsfun.h:389 #10 0x8feea18 in js::LazyScript::functionDelazifying(JSContext*) const js/src/jsscriptinlines.h:90 #11 0x8feea18 in JSFunction::createScriptForLazilyInterpretedFunction(JSContext*, JS::Handle<JSFunction*>) js/src/jsfun.cpp:1378 #12 0x94ee5a8 in JSFunction::getOrCreateScript(JSContext*) js/src/jsfun.h:389 #13 0x94ee5a8 in js::Invoke(JSContext*, JS::CallArgs const&, js::MaybeConstruct) js/src/vm/Interpreter.cpp:447 #14 0x94f00cd in js::Invoke(JSContext*, JS::Value const&, JS::Value const&, unsigned int, JS::Value const*, JS::MutableHandle<JS::Value>) js/src/vm/Interpreter.cpp:496 #15 0x850fd9c 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:6160 0xf5224a3a is located 0 bytes to the right of 42-byte region [0xf5224a10,0xf5224a3a) allocated by thread T0 here: #0 0x80f1d94 in __interceptor_malloc /srv/repos/llvm/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:74 #1 0x9229d5b in js_malloc(unsigned int) js/src/opt32asan/js/src/../../dist/include/js/Utility.h:221 #2 0x9229d5b in _ZL13js_pod_mallocIDsEPT_j js/src/opt32asan/js/src/../../dist/include/js/Utility.h:407 #3 0x9229d5b in char16_t* js::MallocProvider<JS::Zone>::maybe_pod_malloc<char16_t>(unsigned int) js/src/vm/MallocProvider.h:57 #4 0x9229d5b in char16_t* js::MallocProvider<JS::Zone>::pod_malloc<char16_t>(unsigned int) js/src/vm/MallocProvider.h:90 #5 0x917ac75 in js::ScriptSource::ensureOwnsSource(js::ExclusiveContext*) js/src/jsscript.cpp:2017 #6 0x917ac75 in js::ScriptSource::setSourceCopy(js::ExclusiveContext*, JS::SourceBufferHolder&, bool, js::SourceCompressionTask*) js/src/jsscript.cpp:2070 #7 0x98739ed in BytecodeCompiler::maybeCompressSource() js/src/frontend/BytecodeCompiler.cpp:205 #8 0x98739ed in BytecodeCompiler::createSourceAndParser() js/src/frontend/BytecodeCompiler.cpp:253 #9 0x987c297 in BytecodeCompiler::compileScript(JS::Handle<JSObject*>, JS::Handle<JSScript*>) js/src/frontend/BytecodeCompiler.cpp:496 #10 0x98884f8 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:738 #11 0x8f29fc6 in Compile(JSContext*, JS::ReadOnlyCompileOptions const&, SyntacticScopeOption, JS::SourceBufferHolder&, JS::MutableHandle<JSScript*>) js/src/jsapi.cpp:4017 #12 0x8f2ac66 in Compile(JSContext*, JS::ReadOnlyCompileOptions const&, SyntacticScopeOption, char16_t const*, unsigned int, JS::MutableHandle<JSScript*>) js/src/jsapi.cpp:4027 #13 0x8f2ac66 in JS::Compile(JSContext*, JS::ReadOnlyCompileOptions const&, char16_t const*, unsigned int, JS::MutableHandle<JSScript*>) js/src/jsapi.cpp:4086 #14 0x81437ab in Evaluate(JSContext*, unsigned int, JS::Value*) js/src/shell/js.cpp:1365 [...] #29 0x8141c8b in Load(JSContext*, unsigned int, JS::Value*) js/src/shell/js.cpp:955 SUMMARY: AddressSanitizer: heap-buffer-overflow js/src/frontend/TokenStream.cpp:490 js::frontend::TokenStream::TokenBuf::findEOLMax(unsigned int, unsigned int) Shadow bytes around the buggy address: 0x3ea44930: fa fa fa fa fa fa fa fa fa fa 00 00 00 00 03 fa =>0x3ea44940: fa fa 00 00 00 00 00[02]fa fa fd fd fd fd fd fd 0x3ea44950: fa fa 00 00 00 00 00 00 fa fa 00 00 00 00 00 00 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 I assume this is a shell-only problem with the evaluate function failing to check the columnNumber property, so not marking s-s. Marking as fuzzblocker though because the signature looks like a security bug.
Whiteboard: [jsbugmon:update,bisect][fuzzblocker] → [fuzzblocker] [jsbugmon:bisect]
JSBugMon: Cannot process bug: Error: Failed to isolate test from comment
Whiteboard: [fuzzblocker] [jsbugmon:bisect] → [fuzzblocker] [jsbugmon:]
JSBugMon: Bisection requested, failed due to error: Error: Failed to isolate test from comment
Christian, there is something going wrong with jsbugmon, see comment 1 and comment 2.
Flags: needinfo?(choller)
Most likely JSBugMon is unable to isolate the test from comment 0 because it throws some kind of error even with syntax checking only. This looks like a simple shell-only bug to me, please assign some developer to look into it. I doubt it's worth bisecting etc.
Flags: needinfo?(choller)
OK I can take a look.
Flags: needinfo?(jdemooij)
Seems to be a regression from bug 1083913, where we added the columnNumber option to evaluate. Here's a simpler testcase that crashes more reliably: evaluate('function g() { with(this){} }', {columnNumber: 999999999}); print(g.toSource()); Basically JSScript sourceStart/sourceEnd become huge values and we crash trying to get the source. Looks like the API/frontend expects us to pass the whole line, including the part before our start column. Or something.
Flags: needinfo?(jdemooij) → needinfo?(jimb)
Group: javascript-core-security
Status: NEW → RESOLVED
Closed: 10 years ago
Flags: needinfo?(jimb)
Resolution: --- → DUPLICATE
Group: javascript-core-security
You need to log in before you can comment on or make changes to this bug.