Crash [@ js::EnqueuePendingParseTasksAfterGC] or Crash [@ JSObject::setFlags] with use-after-free

VERIFIED FIXED in Firefox 50

Status

()

Core
JavaScript Engine
--
critical
VERIFIED FIXED
2 years ago
2 years ago

People

(Reporter: decoder, Assigned: jandem)

Tracking

(Blocks: 1 bug, 5 keywords)

Trunk
mozilla50
x86_64
Linux
crash, csectype-uaf, regression, sec-critical, testcase
Points:
---
Dependency tree / graph

Firefox Tracking Flags

(firefox49 unaffected, firefox-esr45 unaffected, firefox50+ verified)

Details

(Whiteboard: [jsbugmon:], crash signature)

Attachments

(1 attachment)

(Reporter)

Description

2 years ago
The following testcase crashes on mozilla-central revision e45890951ce7 (build with --enable-posix-nspr-emulation --enable-valgrind --enable-gczeal --disable-tests --disable-debug --enable-optimize, run with --fuzzing-safe --thread-count=2 --nursery-size=1):

gczeal(9, 1);
lfVarx = `Function.prototype.__proto__ = proxy;`
var lfGlobal = newGlobal();
lfGlobal.offThreadCompileScript(lfVarx);



Backtrace:

 received signal SIGSEGV, Segmentation fault.
js::EnqueuePendingParseTasksAfterGC (rt=0x7ffff69751c8) at js/src/vm/HelperThreads.cpp:550
#0  js::EnqueuePendingParseTasksAfterGC (rt=0x7ffff69751c8) at js/src/vm/HelperThreads.cpp:550
#1  0x00000000007ea468 in js::AutoEnqueuePendingParseTasksAfterGC::~AutoEnqueuePendingParseTasksAfterGC (this=<synthetic pointer>, __in_chrg=<optimized out>) at js/src/jsgc.cpp:6362
#2  js::gc::GCRuntime::collect (this=this@entry=0x7ffff69755c8, nonincrementalByAPI=nonincrementalByAPI@entry=true, budget=..., reason=reason@entry=JS::gcreason::DESTROY_RUNTIME) at js/src/jsgc.cpp:6308
#3  0x00000000007ea4d8 in js::gc::GCRuntime::gc (this=this@entry=0x7ffff69755c8, gckind=gckind@entry=GC_NORMAL, reason=reason@entry=JS::gcreason::DESTROY_RUNTIME) at js/src/jsgc.cpp:6384
#4  0x000000000091cd48 in JSRuntime::destroyRuntime (this=this@entry=0x7ffff69751c8) at js/src/vm/Runtime.cpp:430
#5  0x000000000079373d in JSContext::~JSContext (this=0x7ffff6975000, __in_chrg=<optimized out>) at js/src/jscntxt.cpp:892
#6  0x0000000000793e72 in js_delete_poison<JSContext> (p=0x7ffff6975000) at /srv/jenkins/jobs/mozilla-central-build-jsshell/workspace/arch/64/compiler/gcc/sanitizer/none/type/opt/dist/include/js/Utility.h:392
#7  js::DestroyContext (cx=0x7ffff6975000) at js/src/jscntxt.cpp:133
#8  0x0000000000741eac in JS_DestroyRuntime (rt=<optimized out>) at js/src/jsapi.cpp:464
#9  0x0000000000433c25 in main (argc=<optimized out>, argv=<optimized out>, envp=<optimized out>) at js/src/shell/js.cpp:7446
rax	0x0	0
rbx	0x0	0
rcx	0x0	0
rdx	0x1	1
rsi	0x0	0
rdi	0x1	1
rbp	0x7ffff54b9180	140737308758400
rsp	0x7fffffffd430	140737488344112
r8	0x7ffff6941bb0	140737330289584
r9	0x0	0
r10	0x740	1856
r11	0x7ffff69a3848	140737330690120
r12	0x7fffffffd440	140737488344128
r13	0x7ffff696f0b0	140737330475184
r14	0x7ffff69751c8	140737330500040
r15	0x0	0
rip	0x8e0729 <js::EnqueuePendingParseTasksAfterGC(JSRuntime*)+153>
=> 0x8e0729 <js::EnqueuePendingParseTasksAfterGC(JSRuntime*)+153>:	cmp    0xffff8(%rax),%r14
   0x8e0730 <js::EnqueuePendingParseTasksAfterGC(JSRuntime*)+160>:	jne    0x8e0700 <js::EnqueuePendingParseTasksAfterGC(JSRuntime*)+112>


This used to be covered by the signature of bug 1282113 but it still reproduces now that this bug is fixed. Filing s-s because it's a GC issue.
(Reporter)

Updated

2 years ago
Crash Signature: [@ js::EnqueuePendingParseTasksAfterGC] → [@ js::EnqueuePendingParseTasksAfterGC] [@ JSObject::setFlags]
Keywords: csectype-uaf, sec-critical
Summary: Crash [@ js::EnqueuePendingParseTasksAfterGC] → Crash [@ js::EnqueuePendingParseTasksAfterGC] or Crash [@ JSObject::setFlags] with use-after-free
Here's another testcase:

// jsfunfuzz-generated
startgc(45);
// Adapted from randomly chosen test: js/src/jit-test/tests/auto-regress/bug1268034.js
offThreadCompileScript("");

Run with --fuzzing-safe --ion-offthread-compile=off --ion-eager and tested on m-c rev b69a5bbb5e40 with --enable-debug --enable-more-deterministic, also crashes at js::EnqueuePendingParseTasksAfterGC.

autoBisect shows this is probably related to the following changeset:

The first bad revision is:
changeset:   https://hg.mozilla.org/mozilla-central/rev/0ca871e39a20
user:        Jan de Mooij
date:        Wed Jun 22 09:47:52 2016 +0200
summary:     Bug 1279295 - Create the runtime's JSContext when we create the runtime. r=luke

Jan, is bug 1279295 a likely regressor?
Blocks: 1279295
Flags: needinfo?(jdemooij)
(Assignee)

Comment 2

2 years ago
Created attachment 8766722 [details] [diff] [review]
Patch

Nice find.

This is another thing that happened to work because we did a DESTROY_CONTEXT GC right before the DESTROY_RUNTIME GC, but we no longer do that.

We call destroyRuntime and have an in-progress incremental GC, so the parseWaitingOnGC list is not empty. This patch calls FinishGC before we call CancelOffThreadParses, and asserts the parseWaitingOnGC list is empty there.
Assignee: nobody → jdemooij
Status: NEW → ASSIGNED
Flags: needinfo?(jdemooij)
Attachment #8766722 - Flags: review?(jcoppeard)
Comment on attachment 8766722 [details] [diff] [review]
Patch

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

LGTM.
Attachment #8766722 - Flags: review?(jcoppeard) → review+

Updated

2 years ago
Crash Signature: [@ js::EnqueuePendingParseTasksAfterGC] [@ JSObject::setFlags] → [@ js::EnqueuePendingParseTasksAfterGC] [@ JSObject::setFlags]
Whiteboard: [jsbugmon:update,bisect] → [jsbugmon:bisect]

Comment 4

2 years ago
JSBugMon: Cannot process bug: Unable to automatically reproduce, please track manually.

Updated

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

Comment 5

2 years ago
https://hg.mozilla.org/integration/mozilla-inbound/rev/eef71b01a8210f3e9e03328c35d31aef9872d3c1
Crash Signature: [@ js::EnqueuePendingParseTasksAfterGC] [@ JSObject::setFlags] → [@ js::EnqueuePendingParseTasksAfterGC] [@ JSObject::setFlags]
https://hg.mozilla.org/mozilla-central/rev/eef71b01a821
Status: ASSIGNED → RESOLVED
Last Resolved: 2 years ago
status-firefox50: affected → fixed
Resolution: --- → FIXED
Target Milestone: --- → mozilla50
Regression from 50, marking 49 as unaffected.
status-firefox49: --- → unaffected
tracking-firefox50: --- → +

Updated

2 years ago
Status: RESOLVED → VERIFIED
Crash Signature: [@ js::EnqueuePendingParseTasksAfterGC] [@ JSObject::setFlags] → [@ js::EnqueuePendingParseTasksAfterGC] [@ JSObject::setFlags]
status-firefox50: fixed → verified

Comment 8

2 years ago
JSBugMon: This bug has been automatically verified fixed.
Depends on: 1285186
Group: javascript-core-security → core-security-release
Crash Signature: [@ js::EnqueuePendingParseTasksAfterGC] [@ JSObject::setFlags] → [@ js::EnqueuePendingParseTasksAfterGC] [@ JSObject::setFlags]
status-firefox-esr45: --- → unaffected
Depends on: 1287063
Group: core-security-release
You need to log in before you can comment on or make changes to this bug.