Closed Bug 1459625 Opened 6 years ago Closed 6 years ago

AddressSanitizer: heap-buffer-overflow [@ js::gc::detail::GetCellLocation] with READ of size 4 with wasm and GC

Categories

(Core :: JavaScript Engine, defect)

x86
Linux
defect
Not set
critical

Tracking

()

RESOLVED DUPLICATE of bug 1442481
Tracking Status
firefox-esr52 --- unaffected
firefox-esr60 --- unaffected
firefox60 --- unaffected
firefox61 --- disabled
firefox62 --- fix-optional

People

(Reporter: decoder, Unassigned)

Details

(4 keywords, Whiteboard: [jsbugmon:])

The following testcase crashes on mozilla-central revision fb435df9797a (build with --enable-posix-nspr-emulation --enable-valgrind --enable-gczeal --disable-tests --disable-profiling --disable-debug --without-intl-api --enable-address-sanitizer --disable-jemalloc --enable-optimize=-O2 --enable-fuzzing --target=i686-pc-linux-gnu, run with --fuzzing-safe --cpu-count=2 --ion-extra-checks --wasm-gc --ion-eager --test-wasm-await-tier2 --nursery-strings=on):

var lfGlobalTable = new WebAssembly.Table({
    element: 'anyfunc',
    initial: 1
});
var lfModule = new WebAssembly.Module(wasmTextToBinary(`
    (module
        (import "global" "func" (result i32))
        (func (export "func_0") (result i32)
         call 0 ;; calls the import, which is func #0
        )
    )
`));
var Q = 0;
try {
  (function f(i) { Q %= i; if (i == 200000) return; f(i+1); })(this)
} catch (e) {}
processModule(lfModule, `
  try {
    (function f(i) { Q %= i; if (i == 200000) return; f(i+1); })(this)
  } catch (e) {}
`);
function processModule(module, jscode) {
    imports = {};
    for (let descriptor of WebAssembly.Module.imports(module)) {
        imports[descriptor.module] = {}
        imports[descriptor.module][descriptor.name] = new Function("x", "y", "z", jscode);
        try {
            instance = new WebAssembly.Instance(module, imports);
        } catch (exc) {}
    }
    for (let descriptor of WebAssembly.Module.exports(module))
        instance.exports[descriptor.name]();
}


Backtrace:

==15017==ERROR: AddressSanitizer: heap-buffer-overflow on address 0xbcbffff0 at pc 0x0a9a0284 bp 0xffe76ba8 sp 0xffe76b9c
READ of size 4 at 0xbcbffff0 thread T0
    #0 0xa9a0283 in js::gc::detail::GetCellLocation(void const*) /srv/jenkins/jobs/mozilla-central-build-jsshell/workspace/arch/32/compiler/clang/instrumentation/asan/type/opt/dist/include/js/HeapAPI.h:414:12
    #1 0xa9a0283 in js::gc::IsInsideNursery(js::gc::Cell const*) /srv/jenkins/jobs/mozilla-central-build-jsshell/workspace/arch/32/compiler/clang/instrumentation/asan/type/opt/dist/include/js/HeapAPI.h:433
    #2 0xa9a0283 in js::gc::StoreBuffer::CellPtrEdge::trace(js::TenuringTracer&) const js/src/gc/Marking.cpp:2902
    #3 0xa9b44a1 in js::gc::StoreBuffer::MonoTypeBuffer<js::gc::StoreBuffer::CellPtrEdge>::trace(js::gc::StoreBuffer*, js::TenuringTracer&) js/src/gc/Marking.cpp:2756:15
    #4 0xa9b44a1 in js::gc::StoreBuffer::traceCells(js::TenuringTracer&) js/src/gc/StoreBuffer.h:494
    #5 0xa9b44a1 in js::Nursery::doCollection(JS::gcreason::Reason, js::gc::TenureCountCache&) js/src/gc/Nursery.cpp:875
    #6 0xa9b079a in js::Nursery::collect(JS::gcreason::Reason) js/src/gc/Nursery.cpp:736:9
    #7 0xa8de7f8 in js::gc::GCRuntime::minorGC(JS::gcreason::Reason, js::gcstats::PhaseKind) js/src/gc/GC.cpp:7820:15
    #8 0xa94aafe in JSObject* js::gc::GCRuntime::tryNewNurseryObject<(js::AllowGC)1>(JSContext*, unsigned int, unsigned int, js::Class const*) js/src/gc/Allocator.cpp:96:27
    #9 0xa94a81a in JSObject* js::Allocate<JSObject, (js::AllowGC)1>(JSContext*, js::gc::AllocKind, unsigned int, js::gc::InitialHeap, js::Class const*) js/src/gc/Allocator.cpp:56:32
    #10 0x9a7bf5d in js::NativeObject::create(JSContext*, js::gc::AllocKind, js::gc::InitialHeap, JS::Handle<js::Shape*>, JS::Handle<js::ObjectGroup*>) js/src/vm/NativeObject-inl.h:539:21
    #11 0x9d98e8c in NewObject(JSContext*, JS::Handle<js::ObjectGroup*>, js::gc::AllocKind, js::NewObjectKind, unsigned int) js/src/vm/JSObject.cpp:731:9
    #12 0x9d9a064 in js::NewObjectWithClassProtoCommon(JSContext*, js::Class const*, JS::Handle<JSObject*>, js::gc::AllocKind, js::NewObjectKind) js/src/vm/JSObject.cpp:852:21
    #13 0x869b107 in js::NewObjectWithClassProto(JSContext*, js::Class const*, JS::Handle<JSObject*>, js::gc::AllocKind, js::NewObjectKind) js/src/vm/JSObject-inl.h:692:12
    #14 0x869b107 in js::NewBuiltinClassInstance(JSContext*, js::Class const*, js::gc::AllocKind, js::NewObjectKind) js/src/vm/JSObject-inl.h:729
    #15 0x869b107 in js::PlainObject* js::NewBuiltinClassInstance<js::PlainObject>(JSContext*, js::gc::AllocKind, js::NewObjectKind) js/src/vm/JSObject-inl.h:751
    #16 0x869b107 in js::CopyInitializerObject(JSContext*, JS::Handle<js::PlainObject*>, js::NewObjectKind) js/src/vm/NativeObject-inl.h:707
    #17 0x869c2e2 in js::NewObjectOperationWithTemplate(JSContext*, JS::Handle<JSObject*>) js/src/vm/Interpreter.cpp:5020:21
    #18 0x9566608 in js::jit::DoNewObject(JSContext*, void*, js::jit::ICNewObject_Fallback*, JS::MutableHandle<JS::Value>) js/src/jit/SharedIC.cpp:2655:15
    #19 0x533a285e  (<unknown module>)

Address 0xbcbffff0 is a wild pointer.
SUMMARY: AddressSanitizer: heap-buffer-overflow dist/include/js/HeapAPI.h:414:12 in js::gc::detail::GetCellLocation(void const*)
Shadow bytes around the buggy address:
  0x3797ffe0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x3797fff0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa[fa]fa
  0x37980000: 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
  Heap left redzone:       fa
==15017==ABORTING


I was not able to reproduce this on 64-bit, the only build that shows the issue is a 32-bit ASan build. The test requires --wasm-gc which is still disabled by default.
Whiteboard: [jsbugmon:update,bisect] → [jsbugmon:bisect]
JSBugMon: Cannot process bug: Unable to automatically reproduce, please track manually.
Whiteboard: [jsbugmon:bisect] → [jsbugmon:]
This looks similar to Bug 1459633.
Fixed on inbound. Bisection shows the following, which makes sense to me, so I'll just close as dup.

The first good revision is:
changeset:   417619:102f4bab99db
user:        Steve Fink <sfink@mozilla.com>
date:        Tue Apr 03 21:13:07 2018 -0700
summary:     Bug 1442481 - Use whole cell buffer to post-barrier string -> string edges, r=jonco
Status: NEW → RESOLVED
Closed: 6 years ago
Resolution: --- → DUPLICATE
A patch is about to land in bug 1442481 that will likely fix this issue.
You need to log in before you can comment on or make changes to this bug.