Closed Bug 1240544 Opened 5 years ago Closed 5 years ago

Crash [@ JS_NewRuntime] with use-after-free and nested evalInWorker

Categories

(Core :: JavaScript Engine, defect)

x86
Linux
defect
Not set
critical

Tracking

()

RESOLVED FIXED
mozilla46
Tracking Status
firefox46 --- fixed

People

(Reporter: decoder, Assigned: jandem)

Details

(4 keywords, Whiteboard: [fuzzblocker] [jsbugmon:])

Crash Data

Attachments

(1 file)

The following testcase crashes on mozilla-central revision 5644818538de (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 --ion-eager --ion-offthread-compile=off):

try {
    evalInWorker(`
  evalInWorker('#7: 7E1 === 70');
    `);
} catch(exc0) {}



Backtrace:

==15267==ERROR: AddressSanitizer: heap-use-after-free on address 0xf480e34c at pc 0x8f57842 bp 0xe897bfb8 sp 0xe897bfac
READ of size 4 at 0xf480e34c thread T14
    #0 0x8f57841 in JS_NewRuntime(unsigned int, unsigned int, JSRuntime*) js/src/jsapi.cpp:464
    #1 0x815e241 in WorkerMain(void*) js/src/shell/js.cpp:2755
    #2 0x96096d6 in nspr::Thread::ThreadRoutine(void*) js/src/vm/PosixNSPR.cpp:45
    #3 0x80fd2e8 in __asan::AsanThread::ThreadStart(unsigned long) /srv/repos/llvm/projects/compiler-rt/lib/asan/asan_thread.cc:167
    #4 0x80b362c in asan_thread_start(void*) /srv/repos/llvm/projects/compiler-rt/lib/asan/asan_interceptors.cc:165
    #5 0xf7734f58 in start_thread /build/buildd/eglibc-2.19/nptl/pthread_create.c:312
    #6 0xf74f7c4d (/lib32/libc.so.6+0xe9c4d)

0xf480e34c is located 332 bytes inside of 25480-byte region [0xf480e200,0xf4814588)
freed by thread T13 here:
    #0 0x80f1cec in __interceptor_free /srv/repos/llvm/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:64
    #1 0x815f15d in WorkerMain(void*) js/src/shell/js.cpp:2814
    #2 0x96096d6 in nspr::Thread::ThreadRoutine(void*) js/src/vm/PosixNSPR.cpp:45
    #3 0x80fd2e8 in __asan::AsanThread::ThreadStart(unsigned long) /srv/repos/llvm/projects/compiler-rt/lib/asan/asan_thread.cc:167
    #4 0xf74f7c4d (/lib32/libc.so.6+0xe9c4d)

previously allocated by thread T13 here:
    #0 0x80f1f64 in __interceptor_malloc /srv/repos/llvm/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:74
    #1 0x8f577ef in js_malloc(unsigned int) js/src/opt32asan/dist/include/js/Utility.h:221
    #2 0x8f577ef in _ZL6js_newI9JSRuntimeJRPS0_EEPT_DpOT0_ js/src/opt32asan/dist/include/js/Utility.h:333
    #3 0x8f577ef in JS_NewRuntime(unsigned int, unsigned int, JSRuntime*) js/src/jsapi.cpp:467
    #4 0x815e241 in WorkerMain(void*) js/src/shell/js.cpp:2755
    #5 0x96096d6 in nspr::Thread::ThreadRoutine(void*) js/src/vm/PosixNSPR.cpp:45
    #6 0x80fd2e8 in __asan::AsanThread::ThreadStart(unsigned long) /srv/repos/llvm/projects/compiler-rt/lib/asan/asan_thread.cc:167
    #7 0xf74f7c4d (/lib32/libc.so.6+0xe9c4d)

Thread T14 created by T13 here:
    #0 0x80b3597 in __interceptor_pthread_create /srv/repos/llvm/projects/compiler-rt/lib/asan/asan_interceptors.cc:175
    #1 0x9609905 in PR_CreateThread(PRThreadType, void (*)(void*), void*, PRThreadPriority, PRThreadScope, PRThreadState, unsigned int) js/src/vm/PosixNSPR.cpp:108
    #2 0x814c975 in EvalInWorker(JSContext*, unsigned int, JS::Value*) js/src/shell/js.cpp:2854
    #3 0x944ac22 in js::CallJSNative(JSContext*, bool (*)(JSContext*, unsigned int, JS::Value*), JS::CallArgs const&) js/src/jscntxtinlines.h:235
    #4 0x944ac22 in js::Invoke(JSContext*, JS::CallArgs const&, js::MaybeConstruct) js/src/vm/Interpreter.cpp:481
    #5 0x94ca44d in js::Invoke(JSContext*, JS::Value const&, JS::Value const&, unsigned int, JS::Value const*, JS::MutableHandle<JS::Value>) js/src/vm/Interpreter.cpp:533
    #6 0x84ee78b 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:6186

Thread T13 created by T0 here:
    #0 0x80b3597 in __interceptor_pthread_create /srv/repos/llvm/projects/compiler-rt/lib/asan/asan_interceptors.cc:175
    #1 0x9609905 in PR_CreateThread(PRThreadType, void (*)(void*), void*, PRThreadPriority, PRThreadScope, PRThreadState, unsigned int) js/src/vm/PosixNSPR.cpp:108
    #2 0x814c975 in EvalInWorker(JSContext*, unsigned int, JS::Value*) js/src/shell/js.cpp:2854
    #3 0x944ac22 in js::CallJSNative(JSContext*, bool (*)(JSContext*, unsigned int, JS::Value*), JS::CallArgs const&) js/src/jscntxtinlines.h:235
    #4 0x944ac22 in js::Invoke(JSContext*, JS::CallArgs const&, js::MaybeConstruct) js/src/vm/Interpreter.cpp:481
    #5 0x94ca44d in js::Invoke(JSContext*, JS::Value const&, JS::Value const&, unsigned int, JS::Value const*, JS::MutableHandle<JS::Value>) js/src/vm/Interpreter.cpp:533
    #6 0x84ee78b 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:6186

SUMMARY: AddressSanitizer: heap-use-after-free js/src/jsapi.cpp:464 JS_NewRuntime(unsigned int, unsigned int, JSRuntime*)
Shadow bytes around the buggy address:
  0x3e901c50: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
=>0x3e901c60: fd fd fd fd fd fd fd fd fd[fd]fd fd fd fd fd fd
  0x3e901c70: 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
  Freed heap region:       fd
==15267==ABORTING


Marking s-s because I don't know if this affects real workers in any way. Also marking fuzzblocker because this triggers quite often.
Looks like the parent pointer is not getting set right with nested EvalInWorker calls. I'd guess this is probably a problem with EvalInWorker rather than JS_NewRuntime, but it's hard to tell without digging in further. EvalInWorker was last touched by Jan, so I'll let him triage further.
Flags: needinfo?(jdemooij)
Attached patch PatchSplinter Review
Assignee: nobody → jdemooij
Status: NEW → ASSIGNED
Flags: needinfo?(jdemooij)
Attachment #8709903 - Flags: review?(terrence)
Attachment #8709903 - Flags: review?(terrence) → review+
This is a bug in the shell's implementation of EvalInWorker and does not implicate FF's worker implementation, which works quite differently.
Group: javascript-core-security
Thanks for fixing this! This bug gave me multiple headaches before during triage.
Whiteboard: [jsbugmon:update,bisect][fuzzblocker] → [fuzzblocker] [jsbugmon:bisect]
JSBugMon: Cannot process bug: Unable to automatically reproduce, please track manually.
Whiteboard: [fuzzblocker] [jsbugmon:bisect] → [fuzzblocker] [jsbugmon:]
https://hg.mozilla.org/mozilla-central/rev/0da4aa289e3a
Status: ASSIGNED → RESOLVED
Closed: 5 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla46
You need to log in before you can comment on or make changes to this bug.