Closed Bug 1871947 Opened 1 year ago Closed 1 year ago

AddressSanitizer: heap-use-after-free in js::jit::ICScript::active

Categories

(Core :: JavaScript Engine: JIT, defect, P2)

defect

Tracking

()

RESOLVED FIXED
123 Branch
Tracking Status
firefox-esr115 --- unaffected
firefox121 --- unaffected
firefox122 + fixed
firefox123 + fixed

People

(Reporter: lukas.bernhard, Assigned: jandem)

References

(Blocks 2 open bugs, Regression)

Details

(Keywords: regression, reporter-external, sec-high)

Attachments

(2 files)

Steps to reproduce:

On git commit 3bd65516eb9b3a9568806d846ba8c81a9402a885 the attached sample triggers an asan violation when invoking the js-shell as obj-x86_64-pc-linux-gnu/dist/bin/js --fuzzing-safe --fast-warmup --gc-zeal=10,83 crash.js

function f14(a15, a16) {
    const o22 = { 
        ...a16,
        toString(a18) {
            try { a15(WeakMap, this); } catch (e) {}
        },
        get b() {
            let v20 = this;
            --v20;
        },
    };  
    o22[o22];
}

for (let i = 0; i < 5; i++) {
    f14(f14);
}
==3626214==ERROR: AddressSanitizer: heap-use-after-free on address 0x6190000ce534 at pc 0x55c017eefac8 bp 0x7ffc1a353590 sp 0x7ffc1a353588
READ of size 1 at 0x6190000ce534 thread T0
    #0 0x55c017eefac7 in js::jit::ICScript::active() const js/src/jit/JitScript.h:191:32
    #1 0x55c017eefac7 in js::jit::ICScript::purgeStubs(JS::Zone*, js::jit::ICStubSpace&) js/src/jit/JitScript.cpp:521:7
    #2 0x55c017eef03a in js::jit::JitScript::purgeStubs(JSScript*, js::jit::ICStubSpace&)::$_0::operator()(js::jit::ICScript*) const js/src/jit/JitScript.cpp:500:39
    #3 0x55c017eef03a in void js::jit::InliningRoot::forEachInlinedScript<js::jit::JitScript::purgeStubs(JSScript*, js::jit::ICStubSpace&)::$_0>(js::jit::JitScript::purgeStubs(JSScript*, js::jit::ICStubSpace&)::$_0 const&) const js/src/jit/TrialInlining.h:101:7
    #4 0x55c017eef03a in void js::jit::JitScript::forEachICScript<js::jit::JitScript::purgeStubs(JSScript*, js::jit::ICStubSpace&)::$_0>(js::jit::JitScript::purgeStubs(JSScript*, js::jit::ICStubSpace&)::$_0 const&) js/src/jit/JitScript.cpp:367:21
    #5 0x55c017eef03a in js::jit::JitScript::purgeStubs(JSScript*, js::jit::ICStubSpace&) js/src/jit/JitScript.cpp:499:3
    #6 0x55c016e22b8f in JS::Zone::forceDiscardJitCode(JS::GCContext*, JS::Zone::DiscardOptions const&)::$_1::operator()(js::jit::JitScript*) const js/src/gc/Zone.cpp:461:20
    #7 0x55c016e22b8f in void js::jit::JitZone::forEachJitScript<(js::jit::JitScriptFilter)1, JS::Zone::forceDiscardJitCode(JS::GCContext*, JS::Zone::DiscardOptions const&)::$_1>(JS::Zone::forceDiscardJitCode(JS::GCContext*, JS::Zone::DiscardOptions const&)::$_1&&) js/src/jit/JitZone.h:259:9
    #8 0x55c016e22b8f in JS::Zone::forceDiscardJitCode(JS::GCContext*, JS::Zone::DiscardOptions const&) js/src/gc/Zone.cpp:421:14
    #9 0x55c016d6dfb4 in js::gc::GCRuntime::sweepJitDataOnMainThread(JS::GCContext*) js/src/gc/Sweeping.cpp:1368:15
    #10 0x55c016d71770 in js::gc::GCRuntime::beginSweepingSweepGroup(JS::GCContext*, js::SliceBudget&) js/src/gc/Sweeping.cpp:1604:7
    #11 0x55c016e00314 in sweepaction::SweepActionSequence::run(js::gc::SweepAction::Args&) js/src/gc/Sweeping.cpp:2161:23
    #12 0x55c016de8166 in sweepaction::SweepActionForEach<js::gc::SweepGroupsIter, JSRuntime*>::run(js::gc::SweepAction::Args&) js/src/gc/Sweeping.cpp:2196:19
    #13 0x55c016d7ec3c in js::gc::GCRuntime::performSweepActions(js::SliceBudget&) js/src/gc/Sweeping.cpp:2344:53
    #14 0x55c016b838bc in js::gc::GCRuntime::incrementalSlice(js::SliceBudget&, JS::GCReason, bool) js/src/gc/GC.cpp:3733:11
    #15 0x55c016b8c578 in js::gc::GCRuntime::gcCycle(bool, js::SliceBudget const&, JS::GCReason) js/src/gc/GC.cpp:4244:3
    #16 0x55c016b9066a in js::gc::GCRuntime::collect(bool, js::SliceBudget const&, JS::GCReason) js/src/gc/GC.cpp:4435:9
    #17 0x55c016b09615 in js::gc::GCRuntime::runDebugGC() js/src/gc/GC.cpp:4881:5
    #18 0x55c016b9941d in bool js::gc::CellAllocator::PreAllocChecks<(js::AllowGC)1>(JSContext*, js::gc::AllocKind) js/src/gc/Allocator.cpp:256:11
    #19 0x55c01505e2bc in void* js::gc::CellAllocator::AllocNurseryOrTenuredCell<(JS::TraceKind)0, (js::AllowGC)1>(JSContext*, js::gc::AllocKind, unsigned long, js::gc::Heap, js::gc::AllocSite*) js/src/gc/Allocator-inl.h:114:8
    #20 0x55c01505e024 in js::NativeObject* js::gc::CellAllocator::NewObject<js::NativeObject, (js::AllowGC)1>(JSContext*, js::gc::AllocKind, js::gc::Heap, JSClass const*, js::gc::AllocSite*) js/src/gc/Allocator-inl.h:94:16
    #21 0x55c01505c7b3 in js::NativeObject* js::gc::CellAllocator::NewCell<js::NativeObject, (js::AllowGC)1, js::gc::AllocKind&, js::gc::Heap&, JSClass const*&, js::gc::AllocSite*&>(JSContext*, js::gc::AllocKind&, js::gc::Heap&, JSClass const*&, js::gc::AllocSite*&) js/src/gc/Allocator-inl.h:35:12
    #22 0x55c01505c7b3 in js::NativeObject* JSContext::newCell<js::NativeObject, (js::AllowGC)1, js::gc::AllocKind&, js::gc::Heap&, JSClass const*&, js::gc::AllocSite*&>(js::gc::AllocKind&, js::gc::Heap&, JSClass const*&, js::gc::AllocSite*&) js/src/vm/JSContext-inl.h:405:10
    #23 0x55c01505c7b3 in js::NativeObject::create(JSContext*, js::gc::AllocKind, js::gc::Heap, JS::Handle<js::SharedShape*>, js::gc::AllocSite*) js/src/vm/NativeObject-inl.h:495:28
    #24 0x55c015730953 in NewObject(JSContext*, JSClass const*, JS::Handle<js::TaggedProto>, js::gc::AllocKind, js::NewObjectKind, js::EnumFlags<js::ObjectFlag>) js/src/vm/JSObject.cpp:763:23
    #25 0x55c015b1c3a0 in js::NativeObject* js::NewObjectWithGivenTaggedProto<(js::NewObjectKind)1>(JSContext*, JSClass const*, JS::Handle<js::TaggedProto>, js::EnumFlags<js::ObjectFlag>) js/src/vm/JSObject-inl.h:369:10
    #26 0x55c015b1c3a0 in js::SavedFrame* js::detail::NewObjectWithGivenTaggedProtoForKind<js::SavedFrame, (js::NewObjectKind)1>(JSContext*, JS::Handle<js::TaggedProto>) js/src/vm/JSObject-inl.h:378:19
    #27 0x55c015b1c3a0 in js::SavedFrame* js::NewTenuredObjectWithGivenProto<js::SavedFrame>(JSContext*, JS::Handle<JSObject*>) js/src/vm/JSObject-inl.h:414:10
    #28 0x55c015b1c3a0 in js::SavedFrame::create(JSContext*) js/src/vm/SavedStacks.cpp:587:10
    #29 0x55c015b38556 in js::SavedStacks::createFrameFromLookup(JSContext*, JS::Handle<js::SavedFrame::Lookup>) js/src/vm/SavedStacks.cpp:1815:33
    #30 0x55c015b37da5 in js::SavedStacks::getOrCreateSavedFrame(JSContext*, JS::Handle<js::SavedFrame::Lookup>) js/src/vm/SavedStacks.cpp:1801:33
    #31 0x55c015b2fd0a in js::SavedStacks::insertFrames(JSContext*, JS::MutableHandle<js::SavedFrame*>, mozilla::Variant<JS::AllFrames, JS::MaxFrames, JS::FirstSubsumedFrame>&&) js/src/vm/SavedStacks.cpp:1638:15
    #32 0x55c015b2c725 in js::SavedStacks::saveCurrentStack(JSContext*, JS::MutableHandle<js::SavedFrame*>, mozilla::Variant<JS::AllFrames, JS::MaxFrames, JS::FirstSubsumedFrame>&&) js/src/vm/SavedStacks.cpp:1326:10
    #33 0x55c0161698db in JS::CaptureCurrentStack(JSContext*, JS::MutableHandle<JSObject*>, mozilla::Variant<JS::AllFrames, JS::MaxFrames, JS::FirstSubsumedFrame>&&) js/src/jsapi.cpp:4914:29
    #34 0x55c0161745a3 in js::CaptureStack(JSContext*, JS::MutableHandle<JSObject*>) js/src/jsexn.cpp:229:10
    #35 0x55c0161745a3 in js::ErrorToException(JSContext*, JSErrorReport*, JSErrorFormatString const* (*)(void*, unsigned int), void*) js/src/jsexn.cpp:346:8
    #36 0x55c0155a6021 in ReportError(JSContext*, JSErrorReport*, JSErrorFormatString const* (*)(void*, unsigned int), void*) js/src/vm/ErrorReporting.cpp:173:10
    #37 0x55c0155a6021 in js::ReportErrorNumberVA(JSContext*, js::IsWarning, JSErrorFormatString const* (*)(void*, unsigned int), void*, unsigned int, js::ErrorArgumentsType, __va_list_tag*) js/src/vm/ErrorReporting.cpp:487:8
    #38 0x55c01611b252 in JS_ReportErrorNumberASCIIVA(JSContext*, JSErrorFormatString const* (*)(void*, unsigned int), void*, unsigned int, __va_list_tag*) js/src/jsapi.cpp:3761:3
    #39 0x55c01611b252 in JS_ReportErrorNumberASCII(JSContext*, JSErrorFormatString const* (*)(void*, unsigned int), void*, unsigned int, ...) js/src/jsapi.cpp:3751:3
    #40 0x55c015f39806 in js::ThrowIfNotConstructing(JSContext*, JS::CallArgs const&, char const*) js/src/vm/NativeObject-inl.h:867:3
    #41 0x55c015f39806 in js::WeakMapObject::construct(JSContext*, unsigned int, JS::Value*) js/src/builtin/WeakMapObject.cpp:256:8
    #42 0x33da6732f5b5  (<unknown module>)

0x6190000ce534 is located 180 bytes inside of 952-byte region [0x6190000ce480,0x6190000ce838)
freed by thread T0 here:
    #0 0x55c014d78556 in free /builds/worker/fetches/llvm-project/compiler-rt/lib/asan/asan_malloc_linux.cpp:52:3
    #1 0x55c01736c938 in js_free(void*) obj-asan-crash/dist/include/js/Utility.h:418:3
    #2 0x55c01736c938 in void js_delete<js::jit::ICScript>(js::jit::ICScript const*) obj-asan-crash/dist/include/js/Utility.h:566:5
    #3 0x55c01736c938 in JS::DeletePolicy<js::jit::ICScript>::operator()(js::jit::ICScript const*) obj-asan-crash/dist/include/js/Utility.h:638:35
    #4 0x55c01736c938 in mozilla::UniquePtr<js::jit::ICScript, JS::DeletePolicy<js::jit::ICScript>>::reset(js::jit::ICScript*) obj-asan-crash/dist/include/mozilla/UniquePtr.h:301:7
    #5 0x55c01736c938 in mozilla::UniquePtr<js::jit::ICScript, JS::DeletePolicy<js::jit::ICScript>>::~UniquePtr() obj-asan-crash/dist/include/mozilla/UniquePtr.h:249:18
    #6 0x55c01736c938 in mozilla::detail::VectorImpl<mozilla::UniquePtr<js::jit::ICScript, JS::DeletePolicy<js::jit::ICScript>>, 0ul, js::TempAllocPolicy, false>::destroy(mozilla::UniquePtr<js::jit::ICScript, JS::DeletePolicy<js::jit::ICScript>>*, mozilla::UniquePtr<js::jit::ICScript, JS::DeletePolicy<js::jit::ICScript>>*) obj-asan-crash/dist/include/mozilla/Vector.h:161:11
    #7 0x55c01736c938 in mozilla::Vector<mozilla::UniquePtr<js::jit::ICScript, JS::DeletePolicy<js::jit::ICScript>>, 0ul, js::TempAllocPolicy>::shrinkBy(unsigned long) obj-asan-crash/dist/include/mozilla/Vector.h:1138:3
    #8 0x55c017eeed55 in js::jit::JitScript::purgeInactiveICScripts() js/src/jit/JitScript.cpp:473:19
    #9 0x55c016e22b7c in JS::Zone::forceDiscardJitCode(JS::GCContext*, JS::Zone::DiscardOptions const&)::$_1::operator()(js::jit::JitScript*) const js/src/gc/Zone.cpp:460:20
    #10 0x55c016e22b7c in void js::jit::JitZone::forEachJitScript<(js::jit::JitScriptFilter)1, JS::Zone::forceDiscardJitCode(JS::GCContext*, JS::Zone::DiscardOptions const&)::$_1>(JS::Zone::forceDiscardJitCode(JS::GCContext*, JS::Zone::DiscardOptions const&)::$_1&&) js/src/jit/JitZone.h:259:9
    #11 0x55c016e22b7c in JS::Zone::forceDiscardJitCode(JS::GCContext*, JS::Zone::DiscardOptions const&) js/src/gc/Zone.cpp:421:14
    #12 0x55c016d6dfb4 in js::gc::GCRuntime::sweepJitDataOnMainThread(JS::GCContext*) js/src/gc/Sweeping.cpp:1368:15
    #13 0x55c016d71770 in js::gc::GCRuntime::beginSweepingSweepGroup(JS::GCContext*, js::SliceBudget&) js/src/gc/Sweeping.cpp:1604:7
    #14 0x55c016e00314 in sweepaction::SweepActionSequence::run(js::gc::SweepAction::Args&) js/src/gc/Sweeping.cpp:2161:23
    #15 0x55c016de8166 in sweepaction::SweepActionForEach<js::gc::SweepGroupsIter, JSRuntime*>::run(js::gc::SweepAction::Args&) js/src/gc/Sweeping.cpp:2196:19
    #16 0x55c016d7ec3c in js::gc::GCRuntime::performSweepActions(js::SliceBudget&) js/src/gc/Sweeping.cpp:2344:53
    #17 0x55c016b838bc in js::gc::GCRuntime::incrementalSlice(js::SliceBudget&, JS::GCReason, bool) js/src/gc/GC.cpp:3733:11
    #18 0x55c016b8c578 in js::gc::GCRuntime::gcCycle(bool, js::SliceBudget const&, JS::GCReason) js/src/gc/GC.cpp:4244:3
    #19 0x55c016b9066a in js::gc::GCRuntime::collect(bool, js::SliceBudget const&, JS::GCReason) js/src/gc/GC.cpp:4435:9
    #20 0x55c016b09615 in js::gc::GCRuntime::runDebugGC() js/src/gc/GC.cpp:4881:5
    #21 0x55c016b9941d in bool js::gc::CellAllocator::PreAllocChecks<(js::AllowGC)1>(JSContext*, js::gc::AllocKind) js/src/gc/Allocator.cpp:256:11
    #22 0x55c01505e2bc in void* js::gc::CellAllocator::AllocNurseryOrTenuredCell<(JS::TraceKind)0, (js::AllowGC)1>(JSContext*, js::gc::AllocKind, unsigned long, js::gc::Heap, js::gc::AllocSite*) js/src/gc/Allocator-inl.h:114:8
    #23 0x55c01505e024 in js::NativeObject* js::gc::CellAllocator::NewObject<js::NativeObject, (js::AllowGC)1>(JSContext*, js::gc::AllocKind, js::gc::Heap, JSClass const*, js::gc::AllocSite*) js/src/gc/Allocator-inl.h:94:16
    #24 0x55c01505c7b3 in js::NativeObject* js::gc::CellAllocator::NewCell<js::NativeObject, (js::AllowGC)1, js::gc::AllocKind&, js::gc::Heap&, JSClass const*&, js::gc::AllocSite*&>(JSContext*, js::gc::AllocKind&, js::gc::Heap&, JSClass const*&, js::gc::AllocSite*&) js/src/gc/Allocator-inl.h:35:12
    #25 0x55c01505c7b3 in js::NativeObject* JSContext::newCell<js::NativeObject, (js::AllowGC)1, js::gc::AllocKind&, js::gc::Heap&, JSClass const*&, js::gc::AllocSite*&>(js::gc::AllocKind&, js::gc::Heap&, JSClass const*&, js::gc::AllocSite*&) js/src/vm/JSContext-inl.h:405:10
    #26 0x55c01505c7b3 in js::NativeObject::create(JSContext*, js::gc::AllocKind, js::gc::Heap, JS::Handle<js::SharedShape*>, js::gc::AllocSite*) js/src/vm/NativeObject-inl.h:495:28
    #27 0x55c015730953 in NewObject(JSContext*, JSClass const*, JS::Handle<js::TaggedProto>, js::gc::AllocKind, js::NewObjectKind, js::EnumFlags<js::ObjectFlag>) js/src/vm/JSObject.cpp:763:23
    #28 0x55c015b1c3a0 in js::NativeObject* js::NewObjectWithGivenTaggedProto<(js::NewObjectKind)1>(JSContext*, JSClass const*, JS::Handle<js::TaggedProto>, js::EnumFlags<js::ObjectFlag>) js/src/vm/JSObject-inl.h:369:10
    #29 0x55c015b1c3a0 in js::SavedFrame* js::detail::NewObjectWithGivenTaggedProtoForKind<js::SavedFrame, (js::NewObjectKind)1>(JSContext*, JS::Handle<js::TaggedProto>) js/src/vm/JSObject-inl.h:378:19
    #30 0x55c015b1c3a0 in js::SavedFrame* js::NewTenuredObjectWithGivenProto<js::SavedFrame>(JSContext*, JS::Handle<JSObject*>) js/src/vm/JSObject-inl.h:414:10
    #31 0x55c015b1c3a0 in js::SavedFrame::create(JSContext*) js/src/vm/SavedStacks.cpp:587:10
    #32 0x55c015b38556 in js::SavedStacks::createFrameFromLookup(JSContext*, JS::Handle<js::SavedFrame::Lookup>) js/src/vm/SavedStacks.cpp:1815:33
    #33 0x55c015b37da5 in js::SavedStacks::getOrCreateSavedFrame(JSContext*, JS::Handle<js::SavedFrame::Lookup>) js/src/vm/SavedStacks.cpp:1801:33
    #34 0x55c015b2fd0a in js::SavedStacks::insertFrames(JSContext*, JS::MutableHandle<js::SavedFrame*>, mozilla::Variant<JS::AllFrames, JS::MaxFrames, JS::FirstSubsumedFrame>&&) js/src/vm/SavedStacks.cpp:1638:15
    #35 0x55c015b2c725 in js::SavedStacks::saveCurrentStack(JSContext*, JS::MutableHandle<js::SavedFrame*>, mozilla::Variant<JS::AllFrames, JS::MaxFrames, JS::FirstSubsumedFrame>&&) js/src/vm/SavedStacks.cpp:1326:10
    #36 0x55c0161698db in JS::CaptureCurrentStack(JSContext*, JS::MutableHandle<JSObject*>, mozilla::Variant<JS::AllFrames, JS::MaxFrames, JS::FirstSubsumedFrame>&&) js/src/jsapi.cpp:4914:29
    #37 0x55c0161745a3 in js::CaptureStack(JSContext*, JS::MutableHandle<JSObject*>) js/src/jsexn.cpp:229:10
    #38 0x55c0161745a3 in js::ErrorToException(JSContext*, JSErrorReport*, JSErrorFormatString const* (*)(void*, unsigned int), void*) js/src/jsexn.cpp:346:8
    #39 0x55c0155a6021 in ReportError(JSContext*, JSErrorReport*, JSErrorFormatString const* (*)(void*, unsigned int), void*) js/src/vm/ErrorReporting.cpp:173:10
    #40 0x55c0155a6021 in js::ReportErrorNumberVA(JSContext*, js::IsWarning, JSErrorFormatString const* (*)(void*, unsigned int), void*, unsigned int, js::ErrorArgumentsType, __va_list_tag*) js/src/vm/ErrorReporting.cpp:487:8
    #41 0x55c01611b252 in JS_ReportErrorNumberASCIIVA(JSContext*, JSErrorFormatString const* (*)(void*, unsigned int), void*, unsigned int, __va_list_tag*) js/src/jsapi.cpp:3761:3
    #42 0x55c01611b252 in JS_ReportErrorNumberASCII(JSContext*, JSErrorFormatString const* (*)(void*, unsigned int), void*, unsigned int, ...) js/src/jsapi.cpp:3751:3
    #43 0x55c015f39806 in js::ThrowIfNotConstructing(JSContext*, JS::CallArgs const&, char const*) js/src/vm/NativeObject-inl.h:867:3
    #44 0x55c015f39806 in js::WeakMapObject::construct(JSContext*, unsigned int, JS::Value*) js/src/builtin/WeakMapObject.cpp:256:8
    #45 0x33da6732f5b5  (<unknown module>)
    #46 0x33da67320cd7  (<unknown module>)

previously allocated by thread T0 here:
    #0 0x55c014d787fe in malloc /builds/worker/fetches/llvm-project/compiler-rt/lib/asan/asan_malloc_linux.cpp:69:3
    #1 0x55c014ed4f9a in js_arena_malloc(unsigned long, unsigned long) obj-asan-crash/dist/include/js/Utility.h:370:10
    #2 0x55c014ed4f9a in unsigned char* js_pod_arena_malloc<unsigned char>(unsigned long, unsigned long) obj-asan-crash/dist/include/js/Utility.h:586:26
    #3 0x55c014ed4f9a in unsigned char* js::MallocProvider<JSContext>::maybe_pod_arena_malloc<unsigned char>(unsigned long, unsigned long) js/src/vm/MallocProvider.h:57:12
    #4 0x55c014ed4f9a in unsigned char* js::MallocProvider<JSContext>::pod_arena_malloc<unsigned char>(unsigned long, unsigned long) js/src/vm/MallocProvider.h:109:12
    #5 0x55c0172d7051 in unsigned char* js::MallocProvider<JSContext>::pod_malloc<unsigned char>(unsigned long) js/src/vm/MallocProvider.h:127:12
    #6 0x55c0172d7051 in js::jit::TrialInliner::createInlinedICScript(JSFunction*, js::BytecodeLocation) js/src/jit/TrialInlining.cpp:683:21
    #7 0x55c0172d83f5 in js::jit::TrialInliner::maybeInlineCall(js::jit::ICEntry&, js::jit::ICFallbackStub*, js::BytecodeLocation) js/src/jit/TrialInlining.cpp:752:27
    #8 0x55c0172cf913 in js::jit::TrialInliner::tryInlining() js/src/jit/TrialInlining.cpp:884:14
    #9 0x55c0172ceac8 in js::jit::DoTrialInlining(JSContext*, js::jit::BaselineFrame*) js/src/jit/TrialInlining.cpp:103:18
    #10 0x33da672d8dd2  (<unknown module>)
    #11 0x33da6731f5c0  (<unknown module>)
    #12 0x33da673219f1  (<unknown module>)
    #13 0x33da67320cd7  (<unknown module>)
    #14 0x33da672cb7a4  (<unknown module>)
    #15 0x33da672cbd80  (<unknown module>)
    #16 0x55c017ea9e5f in EnterJit(JSContext*, js::RunState&, unsigned char*) js/src/jit/Jit.cpp:115:5
    #17 0x55c017ea9e5f in js::jit::MaybeEnterJit(JSContext*, js::RunState&) js/src/jit/Jit.cpp:261:10
    #18 0x55c015090875 in js::RunScript(JSContext*, js::RunState&) js/src/vm/Interpreter.cpp:441:32
    #19 0x55c01509277c in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct, js::CallReason) js/src/vm/Interpreter.cpp:605:13
    #20 0x55c0150955b8 in js::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, js::AnyInvokeArgs const&, JS::MutableHandle<JS::Value>, js::CallReason) js/src/vm/Interpreter.cpp:672:8
    #21 0x55c0155c6fc5 in js::Call(JSContext*, JS::Handle<JS::Value>, JSObject*, JS::MutableHandle<JS::Value>) js/src/vm/Interpreter.h:109:10
    #22 0x55c015756f67 in MaybeCallMethod(JSContext*, JS::Handle<JSObject*>, JS::Handle<JS::PropertyKey>, JS::MutableHandle<JS::Value>) js/src/vm/JSObject.cpp:2279:10
    #23 0x55c015755628 in JS::OrdinaryToPrimitive(JSContext*, JS::Handle<JSObject*>, JSType, JS::MutableHandle<JS::Value>) js/src/vm/JSObject.cpp:2386:10
    #24 0x55c015757d74 in js::ToPrimitiveSlow(JSContext*, JSType, JS::MutableHandle<JS::Value>) js/src/vm/JSObject.cpp:2440:10
    #25 0x55c0161f6cf9 in js::ToPrimitive(JSContext*, JSType, JS::MutableHandle<JS::Value>) js/src/vm/JSObject.h:772:10
    #26 0x55c0161f6cf9 in js::ToNumericSlow(JSContext*, JS::MutableHandle<JS::Value>) js/src/jsnum.cpp:2064:10
    #27 0x55c0170879fa in js::ToNumeric(JSContext*, JS::MutableHandle<JS::Value>) js/src/jsnum.h:259:10
    #28 0x55c0170879fa in js::jit::DoUnaryArithFallback(JSContext*, js::jit::BaselineFrame*, js::jit::ICFallbackStub*, JS::Handle<JS::Value>, JS::MutableHandle<JS::Value>) js/src/jit/BaselineIC.cpp:2167:12
    #29 0x33da672d90fa  (<unknown module>)
    #30 0x33da673211ac  (<unknown module>)
    #31 0x33da6731ce9c  (<unknown module>)
    #32 0x33da6731e960  (<unknown module>)
    #33 0x33da6731dcf0  (<unknown module>)
    #34 0x33da6731f726  (<unknown module>)
    #35 0x33da673219f1  (<unknown module>)
    #36 0x33da67320cd7  (<unknown module>)

SUMMARY: AddressSanitizer: heap-use-after-free js/src/jit/JitScript.h:191:32 in js::jit::ICScript::active() const
Shadow bytes around the buggy address:
  0x6190000ce280: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x6190000ce300: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x6190000ce380: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x6190000ce400: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x6190000ce480: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
=>0x6190000ce500: fd fd fd fd fd fd[fd]fd fd fd fd fd fd fd fd fd
  0x6190000ce580: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x6190000ce600: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x6190000ce680: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x6190000ce700: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x6190000ce780: 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
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==3626214==ABORTING
Group: firefox-core-security → core-security
Component: Untriaged → JavaScript Engine: JIT
Product: Firefox → Core
Group: core-security → javascript-core-security

Based on the moment this bug has been reported I would have guess for Fuse changes, but I could not find anything related to this read-after-free in the code pointed by ASAn stack traces.

Jan, any idea what might be going on?

Blocks: sm-jits
Severity: -- → S3
Flags: needinfo?(jdemooij)
Priority: -- → P2

Or possibly a duplicate of Bug 1870925 ?

(wrong bug)

This is a great catch. The bug is that in JitScript::purgeInactiveICScripts, we call purgeInactiveICScripts recursively on the ICScript graph, but this can miss scripts if we've removed an edge in this graph (for example if a call site became polymorphic).

For instance, if we inline A => B => C and we remove A => B from ICScript::inlinedChildren_, but A => B is still active, we don't clear the B => C edge and also won't purge these stubs. We will however discard C's ICScript. This can result in a UAF.

The fix is to use forEachICScript in JitScript::purgeInactiveICScripts, similar to what we do in purgeStubs.

Assignee: nobody → jdemooij
Status: NEW → ASSIGNED
Keywords: sec-high, regression
Regressed by: 1867193

Depends on D197603

Flags: needinfo?(jdemooij)

Set release status flags based on info from the regressing bug 1867193

Bug 1871618 looks like it might be a duplicate of this.

Comment on attachment 9370922 [details]
Bug 1871947 - Use forEachICScript in purgeInactiveICScripts. r?iain!

Security Approval Request

  • How easily could an exploit be constructed based on the patch?: Pretty difficult.
  • Do comments in the patch, the check-in comment, or tests included in the patch paint a bulls-eye on the security problem?: No
  • Which older supported branches are affected by this flaw?: 122+
  • If not all supported branches, which bug introduced the flaw?: Bug 1867193
  • Do you have backports for the affected branches?: Yes
  • If not, how different, hard to create, and risky will they be?: Patch should apply.
  • How likely is this patch to cause regressions; how much testing does it need?: Unlikely to cause regressions. Usual Nightly testing/fuzzing should be sufficient.
  • Is Android affected?: Yes
Attachment #9370922 - Flags: sec-approval?
Duplicate of this bug: 1871618

For bug bounty purposes: bug 1871618 is marked as duplicate, but was actually reported first.

The severity field for this bug is set to S3. However, the bug is flagged with the sec-high keyword.
:jandem, could you consider increasing the severity of this security bug?

For more information, please visit BugBot documentation.

Flags: needinfo?(jdemooij)

The bug is marked as tracked for firefox122 (beta) and tracked for firefox123 (nightly). However, the bug still has low severity.

:sdetar, could you please increase the severity for this tracked bug? If you disagree with the tracking decision, please talk with the release managers.

For more information, please visit BugBot documentation.

Flags: needinfo?(sdetar)
Severity: S3 → S2
Flags: needinfo?(jdemooij)
Flags: needinfo?(sdetar)

Comment on attachment 9370922 [details]
Bug 1871947 - Use forEachICScript in purgeInactiveICScripts. r?iain!

Approved to land

Attachment #9370922 - Flags: sec-approval? → sec-approval+
Whiteboard: [reminder-test 2024-03-05]
Group: javascript-core-security → core-security-release
Status: ASSIGNED → RESOLVED
Closed: 1 year ago
Flags: in-testsuite?
Resolution: --- → FIXED
Target Milestone: --- → 123 Branch

The patch landed in nightly and beta is affected.
:jandem, is this bug important enough to require an uplift?

  • If yes, please nominate the patch for beta approval.
  • If no, please set status-firefox122 to wontfix.

For more information, please visit BugBot documentation.

Flags: needinfo?(jdemooij)

Comment on attachment 9370922 [details]
Bug 1871947 - Use forEachICScript in purgeInactiveICScripts. r?iain!

Beta/Release Uplift Approval Request

  • User impact if declined: Security bug.
  • Is this code covered by automated tests?: Yes
  • Has the fix been verified in Nightly?: Yes
  • Needs manual test from QE?: No
  • If yes, steps to reproduce:
  • List of other uplifts needed: None
  • Risk to taking this patch: Low
  • Why is the change risky/not risky? (and alternatives if risky): Patch is small and straight-forward. Code is covered by many tests.
  • String changes made/needed: N/A
  • Is Android affected?: Yes
Flags: needinfo?(jdemooij)
Attachment #9370922 - Flags: approval-mozilla-beta?

Comment on attachment 9370922 [details]
Bug 1871947 - Use forEachICScript in purgeInactiveICScripts. r?iain!

Approved for 122.0b7

Attachment #9370922 - Flags: approval-mozilla-beta? → approval-mozilla-beta+
QA Whiteboard: [post-critsmash-triage]
Flags: qe-verify-
Blocks: 1871618
No longer duplicate of this bug: 1871618

Although this bug was not the first discovery of this bug and normally would fall outside the "split bounty" duplicate rule, we did want to award something because this small testcase made reproducing and pinpointing the problem faster.

Flags: in-testsuite? → in-testsuite+
Flags: sec-bounty+

a month ago, tjr placed a reminder on the bug using the whiteboard tag [reminder-test 2024-03-05] .

jandem, please refer to the original comment to better understand the reason for the reminder.

Flags: needinfo?(jdemooij)
Whiteboard: [reminder-test 2024-03-05]

Making Firefox 122 security bugs public. [bugspam filter string: Pilgarlic-Towers]

Group: core-security-release
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: