Use-after-free [@ js::mjit::Compiler::bytecodeInChunk]

VERIFIED FIXED

Status

()

Core
JavaScript Engine
--
critical
VERIFIED FIXED
5 years ago
4 years ago

People

(Reporter: decoder, Assigned: decoder)

Tracking

(Blocks: 1 bug, {testcase, valgrind})

Trunk
x86_64
Linux
testcase, valgrind
Points:
---
Dependency tree / graph
Bug Flags:
in-testsuite -

Firefox Tracking Flags

(firefox10 unaffected, firefox11 unaffected, firefox12 unaffected, firefox13+ fixed, firefox-esr10 unaffected, status1.9.2 unaffected)

Details

(Whiteboard: [sg:critical] js-triage-needed [asan][advisory-tracking+])

Attachments

(1 attachment)

(Assignee)

Description

5 years ago
Created attachment 598655 [details]
Test case for shell (see README file inside).

The attached test shows a use-after-free in Valgrind and ASan on mozilla-central revision 78fde7e54d92 (see README for running instructions). The test requires a threadsafe shell build (configure with --enable-debug --disable-optimize --enable-valgrind --enable-threadsafe --with-system-nspr) to reproduce, although the original test ( which I unfortunately did not backup :x ) even showed this behavior in a normal shell build and even crashed in a non-deterministic way.

That said, the test here is also non-deterministic, you might need to run it a few times to observe the error. I used ASan to reduce it to a few files but didn't minimize it further because it got even less reliable with smaller sizes.

Here's a Valgrind trace (before that, it also spews out some uninitialized use warnings, probably not related though):


==59936== Invalid read of size 4
==59936==    at 0x6D1AF8: js::mjit::Compiler::bytecodeInChunk(unsigned char*) (Compiler.h:526)
==59936==    by 0x6C1616: js::mjit::Compiler::jumpAndRun(JSC::AbstractMacroAssembler<JSC::X86Assembler>::Jump, unsigned char*, JSC::AbstractMacroAssembler<JSC::X86Assembler>::Jump*, bool*, bool) (Compiler.cpp:7132)
==59936==    by 0x6AACEE: js::mjit::Compiler::generateMethod() (Compiler.cpp:2212)
==59936==    by 0x6A2A8A: js::mjit::Compiler::performCompilation() (Compiler.cpp:543)
==59936==    by 0x6A17A8: js::mjit::Compiler::compile() (Compiler.cpp:159)
==59936==    by 0x6A3E25: js::mjit::CanMethodJIT(JSContext*, JSScript*, unsigned char*, bool, js::mjit::CompileRequest) (Compiler.cpp:996)
==59936==    by 0x750CDD: UncachedInlineCall(js::VMFrame&, js::InitialFrameFlags, void**, bool*, unsigned int) (InvokeHelpers.cpp:322)
==59936==    by 0x75146A: js::mjit::stubs::UncachedCallHelper(js::VMFrame&, unsigned int, bool, js::mjit::stubs::UncachedCallResult*) (InvokeHelpers.cpp:471)
==59936==    by 0x738CFE: CallCompiler::update() (MonoIC.cpp:960)
==59936==    by 0x733D12: js::mjit::ic::Call(js::VMFrame&, js::mjit::ic::CallICInfo*) (MonoIC.cpp:1018)
==59936==    by 0x69C038: ??? (MethodJIT.cpp:160)
==59936==    by 0x69C30F: js::mjit::EnterMethodJIT(JSContext*, js::StackFrame*, void*, JS::Value*, bool) (MethodJIT.cpp:1053)
==59936==  Address 0x809d5cc is 108 bytes inside a block of size 128 free'd
==59936==    at 0x4C282ED: free (vg_replace_malloc.c:366)
==59936==    by 0x403F4B: js_free (Utility.h:152)
==59936==    by 0x41258C: js::Foreground::free_(void*) (Utility.h:566)
==59936==    by 0x4C8ADA: js::GCHelperThread::freeElementsAndArray(void**, void**) (jsgc.h:1467)
==59936==    by 0x4C3BF7: js::GCHelperThread::doSweep() (jsgc.cpp:2547)
==59936==    by 0x4C3579: js::GCHelperThread::threadLoop() (jsgc.cpp:2403)
==59936==    by 0x4C34DF: js::GCHelperThread::threadMain(void*) (jsgc.cpp:2382)
==59936==    by 0x547D012: ??? (in /usr/lib/libnspr4.so)
==59936==    by 0x4E35D8B: start_thread (pthread_create.c:304)
==59936==    by 0x611C04C: clone (clone.S:112)
Whiteboard: js-triage-needed, [asan] → [sg:critical] js-triage-needed [asan]

Updated

5 years ago
status-firefox10: --- → wontfix
status-firefox11: --- → wontfix
status-firefox12: --- → affected
status-firefox13: --- → affected
tracking-firefox10: --- → -
tracking-firefox11: --- → -
tracking-firefox12: --- → +
tracking-firefox13: --- → +
I haven't been able to reproduce this.  The call stack suggests that the compiler's script is being freed out from under it, which doesn't make any sense at all.  Can you reproduce this on other revisions?  When did it appear?
This sorta sounds like a dupe of bug 728609.
Closing as dup based on comment 1 and comment 2.
Status: NEW → RESOLVED
Last Resolved: 5 years ago
Depends on: 728609
Resolution: --- → WORKSFORME
Status: RESOLVED → REOPENED
Resolution: WORKSFORME → ---
Reassigning to :decoder for investigation of which releases are actually affected, to know which branches we need to take the patch from bug 728609. Also to verify it as fixed in Firefox 13
Assignee: general → choller
Status: REOPENED → RESOLVED
Last Resolved: 5 years ago5 years ago
status-firefox10: wontfix → ---
status-firefox11: wontfix → ---
status-firefox12: affected → ---
status-firefox13: affected → fixed
tracking-firefox10: - → ---
tracking-firefox11: - → ---
tracking-firefox12: + → ---
Resolution: --- → FIXED
(Assignee)

Updated

5 years ago
status1.9.2: --- → unaffected
status-firefox-esr10: --- → unaffected
status-firefox10: --- → unaffected
status-firefox11: --- → unaffected
status-firefox12: --- → unaffected
(Assignee)

Updated

5 years ago
Status: RESOLVED → VERIFIED
Group: core-security
Whiteboard: [sg:critical] js-triage-needed [asan] → [sg:critical] js-triage-needed [asan][advisory-tracking+]
(Assignee)

Comment 5

4 years ago
Only an unreliable test available here, marking in-testsuite-.
Flags: in-testsuite-
You need to log in before you can comment on or make changes to this bug.