Closed Bug 1571439 Opened 6 years ago Closed 6 years ago

AddressSanitizer: use-after-poison [@ js::gc::Cell::runtimeFromAnyThread] with READ of size 8 or Assertion failure: gc::IsCellPointerValid(obj), at dist/include/js/Value.h:1320

Categories

(Core :: JavaScript: GC, defect, P1)

x86_64
Linux
defect

Tracking

()

RESOLVED FIXED
mozilla70
Tracking Status
thunderbird_esr60 --- unaffected
thunderbird_esr68 --- unaffected
firefox-esr60 --- unaffected
firefox-esr68 --- unaffected
firefox68 --- unaffected
firefox69 --- unaffected
firefox70 --- fixed

People

(Reporter: decoder, Assigned: pbone)

References

(Blocks 1 open bug, Regression)

Details

(6 keywords, Whiteboard: [fuzzblocker] [jsbugmon:][post-critsmash-triage])

Attachments

(1 file)

The following testcase crashes on mozilla-central revision d681969e4480 (build with --enable-valgrind --enable-gczeal --disable-tests --disable-profiling --disable-debug --enable-address-sanitizer --disable-jemalloc --enable-optimize=-O2 --enable-fuzzing, run with --fuzzing-safe --ion-offthread-compile=off --blinterp-warmup-threshold=1):

function complex(aReal, aImag) {
    this.r35 = aReal;
    gczeal(4, 10);
    this.square = function() {
        return new complex(this.r35 * this.r35 - this.i14 * this.i14, 2 * this.r35 * this.i14);
    }
}
function mandelbrotValueOO(aC, aIterMax) {
    let Z90 = new complex(0.0, 0.0);
    Z90 = Z90.square().add(aC);
}
const width = 60;
const height = 60;
const max_iters = 50;
for (let img_x = 0; img_x < width; img_x++) {
    for (let img_y = 0; img_y < height; img_y++) {
        let C57 = new complex(-2 + (img_x / width) * 3, -1.5 + (img_y / height) * 3);
        var res = mandelbrotValueOO(C57, max_iters);
    }
}

Backtrace:

==29101==ERROR: AddressSanitizer: use-after-poison on address 0x22bd45affff8 at pc 0x55f10ef1b33c bp 0x7ffdfd0747f0 sp 0x7ffdfd0747e8
READ of size 8 at 0x22bd45affff8 thread T0
    #0 0x55f10ef1b33b in js::gc::Cell::runtimeFromAnyThread() const js/src/gc/Cell.h:263:27
    #1 0x55f10ef1b33b in js::VerifyPreTracer::onChild(JS::GCCellPtr const&) js/src/gc/Verifier.cpp:128
    #2 0x55f10e2fe98c in JS::CallbackTracer::onObjectEdge(JSObject**) dist/include/js/TracingAPI.h:158:12
    #3 0x55f10ef0ea77 in JS::CallbackTracer::dispatchToOnEdge(JSObject**) dist/include/js/TracingAPI.h:265:51
    #4 0x55f10ef0ea77 in bool DoCallback<JSObject>(JS::CallbackTracer*, JSObject**, char const*) js/src/gc/Tracer.cpp:45
    #5 0x55f10ef0ea77 in auto DoCallback<JS::Value>(JS::CallbackTracer*, JS::Value*, char const*)::{lambda(auto:1)#1}::operator()<JSObject*>(JSObject*) const js/src/gc/Tracer.cpp:57
    #6 0x55f10ef0ea77 in auto js::MapGCThingTyped<DoCallback<JS::Value>(JS::CallbackTracer*, JS::Value*, char const*)::{lambda(auto:1)#1}>(JS::Value const&, DoCallback<JS::Value>(JS::CallbackTracer*, JS::Value*, char const*)::{lambda(auto:1)#1}&&) dist/include/js/Value.h:1321
    #7 0x55f10ef0e3e9 in bool DoCallback<JS::Value>(JS::CallbackTracer*, JS::Value*, char const*) js/src/gc/Tracer.cpp:56:16
    #8 0x55f10ee89a20 in bool js::gc::TraceEdgeInternal<JS::Value>(JSTracer*, JS::Value*, char const*) js/src/gc/Marking.cpp:593:10
    #9 0x55f10dfbd7df in void js::TraceManuallyBarrieredEdge<JS::Value>(JSTracer*, JS::Value*, char const*) js/src/gc/Tracer.h:191:3
    #10 0x55f10dfbd7df in JSObject::traceChildren(JSTracer*) js/src/vm/JSObject.cpp:4077
    #11 0x55f10ef1beac in js::gc::GCRuntime::startVerifyPreBarriers() js/src/gc/Verifier.cpp:241:9
    #12 0x55f10db34e04 in Interpret(JSContext*, js::RunState&) js/src/vm/Interpreter.cpp
    #13 0x55f10db0d7ed in js::RunScript(JSContext*, js::RunState&) js/src/vm/Interpreter.cpp:425:10
    #14 0x55f10db43bd0 in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) js/src/vm/Interpreter.cpp:568:13
    #15 0x55f10f003e4e 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:3209:10
    #16 0x23f9f16a3797  (<unknown module>)

Address 0x22bd45affff8 is a wild pointer.
SUMMARY: AddressSanitizer: use-after-poison js/src/gc/Cell.h:263:27 in js::gc::Cell::runtimeFromAnyThread() const
Shadow bytes around the buggy address:
  0x045828b57fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x045828b57ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 f7 f7[f7]
  0x045828b58000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x045828b58010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Poisoned by user:        f7
==29101==ABORTING

Marking s-s based on use-after-poison and GC assertion. Also seeing various crashes that might be related.

This is causing a large amount of random GC crashes, marking as fuzzblocker.

Whiteboard: [jsbugmon:update,bisect] → [jsbugmon:update,bisect][fuzzblocker]
This is an automated crash issue comment: Summary: AddressSanitizer: use-after-poison [@ js::gc::Cell::runtimeFromAnyThread] with READ of size 8 Build version: mozilla-central revision d681969e4480 Build flags: --enable-valgrind --enable-gczeal --disable-tests --disable-profiling --disable-debug --enable-address-sanitizer --disable-jemalloc --enable-optimize=-O2 --enable-fuzzing Runtime options: --fuzzing-safe --ion-offthread-compile=off Testcase: gczeal(4); actual = ''; var p9 = 1; for (var i99 = 0; i99 < 5; + i99) { p9 = p9 * 2; actual += p9 + ','; } Backtrace: ==21781==ERROR: AddressSanitizer: use-after-poison on address 0x3270ad8ffff8 at pc 0x55cdfd7be33c bp 0x7ffc67422370 sp 0x7ffc67422368 READ of size 8 at 0x3270ad8ffff8 thread T0 #0 0x55cdfd7be33b in js::gc::Cell::runtimeFromAnyThread() const js/src/gc/Cell.h:263:27 #1 0x55cdfd7be33b in js::VerifyPreTracer::onChild(JS::GCCellPtr const&) js/src/gc/Verifier.cpp:128 #2 0x55cdfcba1b00 in JS::CallbackTracer::onStringEdge(JSString**) dist/include/js/TracingAPI.h:161:12 #3 0x55cdfd7b1824 in JS::CallbackTracer::dispatchToOnEdge(JSString**) dist/include/js/TracingAPI.h:266:51 #4 0x55cdfd7b1824 in bool DoCallback<JSString>(JS::CallbackTracer*, JSString**, char const*) js/src/gc/Tracer.cpp:45 #5 0x55cdfd7b1824 in auto DoCallback<JS::Value>(JS::CallbackTracer*, JS::Value*, char const*)::{lambda(auto:1)#1}::operator()<JSString*>(JSString*) const js/src/gc/Tracer.cpp:57 #6 0x55cdfd7b1824 in auto js::MapGCThingTyped<DoCallback<JS::Value>(JS::CallbackTracer*, JS::Value*, char const*)::{lambda(auto:1)#1}>(JS::Value const&, DoCallback<JS::Value>(JS::CallbackTracer*, JS::Value*, char const*)::{lambda(auto:1)#1}&&) dist/include/js/Value.h:1316 #7 0x55cdfd7b13e9 in bool DoCallback<JS::Value>(JS::CallbackTracer*, JS::Value*, char const*) js/src/gc/Tracer.cpp:56:16 #8 0x55cdfd72ca20 in bool js::gc::TraceEdgeInternal<JS::Value>(JSTracer*, JS::Value*, char const*) js/src/gc/Marking.cpp:593:10 #9 0x55cdfc8607df in void js::TraceManuallyBarrieredEdge<JS::Value>(JSTracer*, JS::Value*, char const*) js/src/gc/Tracer.h:191:3 #10 0x55cdfc8607df in JSObject::traceChildren(JSTracer*) js/src/vm/JSObject.cpp:4077 #11 0x55cdfd7beeac in js::gc::GCRuntime::startVerifyPreBarriers() js/src/gc/Verifier.cpp:241:9 #12 0x55cdfd98b38f in js::jit::InterruptCheck(JSContext*) js/src/jit/VMFunctions.cpp:638:3 #13 0x3a9a116827c1 (<unknown module>) Found a much simpler testcase for this.
Type: task → defect

Jon, is something GC team should look at?

Flags: needinfo?(jcoppeard)
Component: JavaScript Engine → JavaScript: GC

I can reproduce this at d681969e4480 but not at 08dac69a3727, which points at bug 1568740. Paul can you take a look at this?

Flags: needinfo?(jcoppeard) → needinfo?(pbone)

autobisectjs shows this is probably related to the following changeset:

The first bad revision is:
changeset: https://hg.mozilla.org/mozilla-central/rev/251f98554914
user: Paul Bone
date: Wed Jul 31 04:06:45 2019 +0000
summary: Bug 1568740 - (part 1) Remove Nursery::exists r=nbp

Paul, is bug 1568740 a likely regressor?

Regressed by: 1568740

Thanks decoder/gkw/jonco, looking now.

Assignee: nobody → pbone
Status: NEW → ASSIGNED
Flags: needinfo?(pbone)
Priority: -- → P1

In Bug 1568740 I incorrectly assumed that the nursery existing and being enabled is the same thing. This is not true and it can exist (be configured) but be disabled. This caused some barriers not to be emitted which lead to these crashes. I think that this means that it's only a security problem if an attacker can somehow cause the nursery to be disabled - I don't know if that's possible.

Bug 1568740 removes the ability to set the maximum nursery size to 0 (making it not exist) then we can remove these checks whether the nursery exists - it always exists. I have a patch.

(In reply to Paul Bone [:pbone] from comment #7)

In Bug 1568740 I incorrectly assumed that the nursery existing and being enabled is the same thing. This is not true and it can exist (be configured) but be disabled. This caused some barriers not to be emitted which lead to these crashes. I think that this means that it's only a security problem if an attacker can somehow cause the nursery to be disabled - I don't know if that's possible.

The testcases in comment 0 and comment 2 don't use gcparam though. They just use regular gczeal, or does that also disable the nursery?

Assuming sec-high after discussing this with :pbone on IRC. Also, this will be fixed by the backout in bug 1568740.

Keywords: sec-high

CC'ing nbp so he can see the context when I update the patch and request re-review on Bug 1568740.

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:]
Group: javascript-core-security → core-security-release
Status: ASSIGNED → RESOLVED
Closed: 6 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla70
Flags: in-testsuite+
Flags: qe-verify-
Whiteboard: [fuzzblocker] [jsbugmon:] → [fuzzblocker] [jsbugmon:][post-critsmash-triage]
Group: core-security-release
Has Regression Range: --- → yes
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: