Closed Bug 1974309 Opened 10 months ago Closed 10 months ago

AddressSanitizer: heap-use-after-free [@ _M_set_node] with READ of size 8 from WebGPUChild::ClearAllPendingPromises()

Categories

(Core :: Graphics: WebGPU, defect)

x86_64
Linux
defect

Tracking

()

RESOLVED FIXED
142 Branch
Tracking Status
firefox-esr115 --- unaffected
firefox-esr128 --- unaffected
firefox-esr140 --- unaffected
firefox140 --- unaffected
firefox141 --- unaffected
firefox142 --- fixed

People

(Reporter: jkratzer, Assigned: teoxoy)

References

(Blocks 1 open bug, Regression)

Details

(Keywords: csectype-uaf, regression, sec-high, Whiteboard: [bugmon:confirm])

Attachments

(1 file)

Found while fuzzing mozilla-central rev b6b97a2645ba (built with: --enable-address-sanitizer --enable-fuzzing).

I don't currently have a reproducible testcase for this issue.

AddressSanitizer: heap-use-after-free [@ _M_set_node] with READ of size 8

    =================================================================
    ==322095==ERROR: AddressSanitizer: heap-use-after-free on address 0x5120003cf410 at pc 0x7fffda51c532 bp 0x7fffffffc990 sp 0x7fffffffc988
    READ of size 8 at 0x5120003cf410 thread T0 (Isolated Web Co)
        #0 0x7fffda51c531 in _M_set_node /builds/worker/fetches/sysroot-x86_64-linux-gnu/usr/lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/stl_deque.h:258:13
        #1 0x7fffda51c531 in operator++ /builds/worker/fetches/sysroot-x86_64-linux-gnu/usr/lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/stl_deque.h:174:6
        #2 0x7fffda51c531 in mozilla::webgpu::WebGPUChild::ClearAllPendingPromises() /gecko/dom/webgpu/ipc/WebGPUChild.cpp:460:32
        #3 0x7fffda51d907 in mozilla::webgpu::WebGPUChild::ActorDestroy(mozilla::ipc::IProtocol::ActorDestroyReason) /gecko/dom/webgpu/ipc/WebGPUChild.cpp:447:3
        #4 0x7fffd53d588d in mozilla::ipc::IProtocol::ActorDisconnected(mozilla::ipc::IProtocol::ActorDestroyReason)::$_0::operator()(mozilla::ipc::IProtocol*, mozilla::ipc::IProtocol::ActorDestroyReason) const /gecko/ipc/glue/ProtocolUtils.cpp:584:12
        #5 0x7fffd53d425e in mozilla::ipc::IProtocol::ActorDisconnected(mozilla::ipc::IProtocol::ActorDestroyReason) /gecko/ipc/glue/ProtocolUtils.cpp:605:5
        #6 0x7fffd53b3157 in OnChannelClose /builds/worker/workspace/obj-build/dist/include/mozilla/ipc/ProtocolUtils.h:529:5
        #7 0x7fffd53b3157 in mozilla::ipc::MessageChannel::NotifyChannelClosed(mozilla::ReleasableMonitorAutoLock&) /gecko/ipc/glue/MessageChannel.cpp:2191:14
        #8 0x7fffd53b3bfb in mozilla::ipc::MessageChannel::Close() /gecko/ipc/glue/MessageChannel.cpp:2163:7
        #9 0x7fffd6d6eab8 in Destroy /gecko/gfx/ipc/CanvasManagerChild.cpp:69:3
        #10 0x7fffd6d6eab8 in Shutdown /gecko/gfx/ipc/CanvasManagerChild.cpp:76:16
        #11 0x7fffd6d6eab8 in mozilla::gfx::CanvasShutdownManager::Destroy() /gecko/gfx/ipc/CanvasShutdownManager.cpp:40:3
        #12 0x7fffd6d6ed4b in mozilla::gfx::CanvasShutdownManager::Shutdown() /gecko/gfx/ipc/CanvasShutdownManager.cpp:56:12
        #13 0x7fffd6b6cad3 in gfxPlatform::ShutdownLayersIPC() /gecko/gfx/thebes/gfxPlatform.cpp:1367:5
        #14 0x7fffd3d83add in mozilla::ShutdownXPCOM(nsIServiceManager*) /gecko/xpcom/build/XPCOMInit.cpp:640:5
        #15 0x7fffe04268cd in XRE_InitChildProcess(int, char**, XREChildData const*) /gecko/toolkit/xre/nsEmbedFunctions.cpp:594:16
        #16 0x5555556fbee1 in main /gecko/browser/app/nsBrowserApp.cpp:397:22
        #17 0x7ffff7a51d8f in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
        #18 0x7ffff7a51e3f in __libc_start_main csu/../csu/libc-start.c:392:3
        #19 0x55555561bc88 in _start (/home/worker/builds/m-c-20250626034703-fuzzing-asan-opt/firefox+0xc7c88) (BuildId: 8606f913227183b4685e7c4fda5a2a9485f1aa72)
    
    0x5120003cf410 is located 208 bytes inside of 304-byte region [0x5120003cf340,0x5120003cf470)
    freed by thread T0 (Isolated Web Co) here:
        #0 0x5555556b92e6 in free /builds/worker/fetches/llvm-project/compiler-rt/lib/asan/asan_malloc_linux.cpp:52:3
        #1 0x7fffda4e833c in operator delete /builds/worker/workspace/obj-build/dist/include/mozilla/cxxalloc.h:64:10
        #2 0x7fffda4e833c in deallocate /builds/worker/fetches/sysroot-x86_64-linux-gnu/usr/lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/ext/new_allocator.h:125:2
        #3 0x7fffda4e833c in deallocate /builds/worker/fetches/sysroot-x86_64-linux-gnu/usr/lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/alloc_traits.h:462:13
        #4 0x7fffda4e833c in _M_deallocate_map /builds/worker/fetches/sysroot-x86_64-linux-gnu/usr/lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/stl_deque.h:624:2
        #5 0x7fffda4e833c in std::deque<mozilla::webgpu::WebGPUChild::PendingRequestDevicePromise, std::allocator<mozilla::webgpu::WebGPUChild::PendingRequestDevicePromise>>::_M_reallocate_map(unsigned long, bool) /builds/worker/fetches/sysroot-x86_64-linux-gnu/usr/lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/deque.tcc:952:4
        #6 0x7fffda4e7c22 in _M_reserve_map_at_back /builds/worker/fetches/sysroot-x86_64-linux-gnu/usr/lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/stl_deque.h:2163:4
        #7 0x7fffda4e7c22 in void std::deque<mozilla::webgpu::WebGPUChild::PendingRequestDevicePromise, std::allocator<mozilla::webgpu::WebGPUChild::PendingRequestDevicePromise>>::_M_push_back_aux<mozilla::webgpu::WebGPUChild::PendingRequestDevicePromise>(mozilla::webgpu::WebGPUChild::PendingRequestDevicePromise&&) /builds/worker/fetches/sysroot-x86_64-linux-gnu/usr/lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/deque.tcc:487:2
        #8 0x7fffda4e7a85 in mozilla::webgpu::WebGPUChild::PendingRequestDevicePromise& std::deque<mozilla::webgpu::WebGPUChild::PendingRequestDevicePromise, std::allocator<mozilla::webgpu::WebGPUChild::PendingRequestDevicePromise>>::emplace_back<mozilla::webgpu::WebGPUChild::PendingRequestDevicePromise>(mozilla::webgpu::WebGPUChild::PendingRequestDevicePromise&&) /builds/worker/fetches/sysroot-x86_64-linux-gnu/usr/lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/deque.tcc:174:4
        #9 0x7fffda4b780b in push_back /builds/worker/fetches/sysroot-x86_64-linux-gnu/usr/lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/stl_deque.h:1568:9
        #10 0x7fffda4b780b in operator() /gecko/dom/webgpu/Adapter.cpp:664:44
        #11 0x7fffda4b780b in mozilla::webgpu::Adapter::RequestDevice(mozilla::dom::GPUDeviceDescriptor const&, mozilla::ErrorResult&) /gecko/dom/webgpu/Adapter.cpp:519:3
        #12 0x7fffd908d46d in requestDevice /builds/worker/workspace/obj-build/dom/bindings/./WebGPUBinding.cpp:12726:60
        #13 0x7fffd908d46d in mozilla::dom::GPUAdapter_Binding::requestDevice_promiseWrapper(JSContext*, JS::Handle<JSObject*>, void*, JSJitMethodCallArgs const&) /builds/worker/workspace/obj-build/dom/bindings/./WebGPUBinding.cpp:12740:13
        #14 0x7fffd99d6692 in bool mozilla::dom::binding_detail::GenericMethod<mozilla::dom::binding_detail::NormalThisPolicy, mozilla::dom::binding_detail::ConvertExceptionsToPromises>(JSContext*, unsigned int, JS::Value*) /gecko/dom/bindings/BindingUtils.cpp:3306:13
        #15 0x3d85d8627e3c  ([anon:js-executable-memory]+0xe3c)
        #16 0x3d85d85817c2  ([anon:js-executable-memory]+0xa7c2)
        #17 0x3d85d85774e5  ([anon:js-executable-memory]+0x4e5)
        #18 0x7fffe22199e4 in EnterJit /gecko/js/src/jit/Jit.cpp:114:5
        #19 0x7fffe22199e4 in js::jit::MaybeEnterJit(JSContext*, js::RunState&) /gecko/js/src/jit/Jit.cpp:260:10
        #20 0x7fffe06e5049 in js::RunScript(JSContext*, js::RunState&) /gecko/js/src/vm/Interpreter.cpp:461:32
        #21 0x7fffe06e668d in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct, js::CallReason) /gecko/js/src/vm/Interpreter.cpp:629:13
        #22 0x7fffe06e8391 in InternalCall /gecko/js/src/vm/Interpreter.cpp:664:10
        #23 0x7fffe06e8391 in js::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, js::AnyInvokeArgs const&, JS::MutableHandle<JS::Value>, js::CallReason) /gecko/js/src/vm/Interpreter.cpp:696:8
        #24 0x7fffe06ea0ba in js::CallGetter(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, JS::MutableHandle<JS::Value>) /gecko/js/src/vm/Interpreter.cpp:818:10
        #25 0x7fffe0ae648a in CallGetter(JSContext*, JS::Handle<js::NativeObject*>, JS::Handle<JS::Value>, JS::Handle<JS::PropertyKey>, js::PropertyInfoBase<unsigned int>, JS::MutableHandle<JS::Value>) /gecko/js/src/vm/NativeObject.cpp:2125:12
        #26 0x7fffe0ac7c9d in GetExistingProperty<(js::AllowGC)1> /gecko/js/src/vm/NativeObject.cpp:2153:12
        #27 0x7fffe0ac7c9d in NativeGetPropertyInline<(js::AllowGC)1> /gecko/js/src/vm/NativeObject.cpp:2296:14
        #28 0x7fffe0ac7c9d in js::NativeGetProperty(JSContext*, JS::Handle<js::NativeObject*>, JS::Handle<JS::Value>, JS::Handle<JS::PropertyKey>, JS::MutableHandle<JS::Value>) /gecko/js/src/vm/NativeObject.cpp:2326:10
        #29 0x7fffe0a5c5a7 in GetProperty /gecko/js/src/vm/ObjectOperations-inl.h:113:10
        #30 0x7fffe0a5c5a7 in GetProperty /gecko/js/src/vm/ObjectOperations-inl.h:120:10
        #31 0x7fffe0a5c5a7 in GetThenValue(JSContext*, JS::Handle<JSObject*>, JS::Handle<JS::Value>, JS::MutableHandle<JS::Value>, bool*, bool*, bool*) /gecko/js/src/builtin/Promise.cpp:1323:8
        #32 0x7fffe0a5d164 in js::ResolvePromiseInternal(JSContext*, JS::Handle<JSObject*>, JS::Handle<JS::Value>) /gecko/js/src/builtin/Promise.cpp:1400:17
        #33 0x7fffe0a7165d in CallDefaultPromiseResolveFunction /gecko/js/src/builtin/Promise.cpp:6752:10
        #34 0x7fffe0a7165d in js::PromiseObject::resolve(JSContext*, JS::Handle<js::PromiseObject*>, JS::Handle<JS::Value>) /gecko/js/src/builtin/Promise.cpp:6764:12
        #35 0x7fffe0eb1c03 in ResolveOrRejectPromise(JSContext*, JS::Handle<JSObject*>, JS::Handle<JS::Value>, bool) /gecko/js/src/jsapi.cpp:2983:19
        #36 0x7fffddbf3ce2 in mozilla::dom::Promise::MaybeResolve(JSContext*, JS::Handle<JS::Value>) /gecko/dom/promise/Promise.cpp:432:14
        #37 0x7fffda53adfb in void mozilla::dom::Promise::MaybeSomething<RefPtr<mozilla::webgpu::Device>&>(RefPtr<mozilla::webgpu::Device>&, void (mozilla::dom::Promise::*)(JSContext*, JS::Handle<JS::Value>)) /builds/worker/workspace/obj-build/dist/include/mozilla/dom/Promise.h:454:5
        #38 0x7fffda51b35c in MaybeResolve<RefPtr<mozilla::webgpu::Device> &> /builds/worker/workspace/obj-build/dist/include/mozilla/dom/Promise.h:95:5
        #39 0x7fffda51b35c in mozilla::webgpu::WebGPUChild::ClearAllPendingPromises() /gecko/dom/webgpu/ipc/WebGPUChild.cpp:467:32
        #40 0x7fffda51d907 in mozilla::webgpu::WebGPUChild::ActorDestroy(mozilla::ipc::IProtocol::ActorDestroyReason) /gecko/dom/webgpu/ipc/WebGPUChild.cpp:447:3
        #41 0x7fffd53d588d in mozilla::ipc::IProtocol::ActorDisconnected(mozilla::ipc::IProtocol::ActorDestroyReason)::$_0::operator()(mozilla::ipc::IProtocol*, mozilla::ipc::IProtocol::ActorDestroyReason) const /gecko/ipc/glue/ProtocolUtils.cpp:584:12
        #42 0x7fffd53d425e in mozilla::ipc::IProtocol::ActorDisconnected(mozilla::ipc::IProtocol::ActorDestroyReason) /gecko/ipc/glue/ProtocolUtils.cpp:605:5
        #43 0x7fffd53b3157 in OnChannelClose /builds/worker/workspace/obj-build/dist/include/mozilla/ipc/ProtocolUtils.h:529:5
        #44 0x7fffd53b3157 in mozilla::ipc::MessageChannel::NotifyChannelClosed(mozilla::ReleasableMonitorAutoLock&) /gecko/ipc/glue/MessageChannel.cpp:2191:14
        #45 0x7fffd53b3bfb in mozilla::ipc::MessageChannel::Close() /gecko/ipc/glue/MessageChannel.cpp:2163:7
        #46 0x7fffd6d6eab8 in Destroy /gecko/gfx/ipc/CanvasManagerChild.cpp:69:3
        #47 0x7fffd6d6eab8 in Shutdown /gecko/gfx/ipc/CanvasManagerChild.cpp:76:16
        #48 0x7fffd6d6eab8 in mozilla::gfx::CanvasShutdownManager::Destroy() /gecko/gfx/ipc/CanvasShutdownManager.cpp:40:3
    
    previously allocated by thread T0 (Isolated Web Co) here:
        #0 0x5555556b957f in malloc /builds/worker/fetches/llvm-project/compiler-rt/lib/asan/asan_malloc_linux.cpp:68:3
        #1 0x555555700af5 in moz_xmalloc /gecko/memory/mozalloc/mozalloc.cpp:52:15
        #2 0x7fffda4e8242 in operator new /builds/worker/workspace/obj-build/dist/include/mozilla/cxxalloc.h:33:10
        #3 0x7fffda4e8242 in allocate /builds/worker/fetches/sysroot-x86_64-linux-gnu/usr/lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/ext/new_allocator.h:111:27
        #4 0x7fffda4e8242 in allocate /builds/worker/fetches/sysroot-x86_64-linux-gnu/usr/lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/alloc_traits.h:436:20
        #5 0x7fffda4e8242 in _M_allocate_map /builds/worker/fetches/sysroot-x86_64-linux-gnu/usr/lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/stl_deque.h:617:9
        #6 0x7fffda4e8242 in std::deque<mozilla::webgpu::WebGPUChild::PendingRequestDevicePromise, std::allocator<mozilla::webgpu::WebGPUChild::PendingRequestDevicePromise>>::_M_reallocate_map(unsigned long, bool) /builds/worker/fetches/sysroot-x86_64-linux-gnu/usr/lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/deque.tcc:946:35
        #7 0x7fffda4e7c22 in _M_reserve_map_at_back /builds/worker/fetches/sysroot-x86_64-linux-gnu/usr/lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/stl_deque.h:2163:4
        #8 0x7fffda4e7c22 in void std::deque<mozilla::webgpu::WebGPUChild::PendingRequestDevicePromise, std::allocator<mozilla::webgpu::WebGPUChild::PendingRequestDevicePromise>>::_M_push_back_aux<mozilla::webgpu::WebGPUChild::PendingRequestDevicePromise>(mozilla::webgpu::WebGPUChild::PendingRequestDevicePromise&&) /builds/worker/fetches/sysroot-x86_64-linux-gnu/usr/lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/deque.tcc:487:2
        #9 0x7fffda4e7a85 in mozilla::webgpu::WebGPUChild::PendingRequestDevicePromise& std::deque<mozilla::webgpu::WebGPUChild::PendingRequestDevicePromise, std::allocator<mozilla::webgpu::WebGPUChild::PendingRequestDevicePromise>>::emplace_back<mozilla::webgpu::WebGPUChild::PendingRequestDevicePromise>(mozilla::webgpu::WebGPUChild::PendingRequestDevicePromise&&) /builds/worker/fetches/sysroot-x86_64-linux-gnu/usr/lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/deque.tcc:174:4
        #10 0x7fffda4b780b in push_back /builds/worker/fetches/sysroot-x86_64-linux-gnu/usr/lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/stl_deque.h:1568:9
        #11 0x7fffda4b780b in operator() /gecko/dom/webgpu/Adapter.cpp:664:44
        #12 0x7fffda4b780b in mozilla::webgpu::Adapter::RequestDevice(mozilla::dom::GPUDeviceDescriptor const&, mozilla::ErrorResult&) /gecko/dom/webgpu/Adapter.cpp:519:3
        #13 0x7fffd908d46d in requestDevice /builds/worker/workspace/obj-build/dom/bindings/./WebGPUBinding.cpp:12726:60
        #14 0x7fffd908d46d in mozilla::dom::GPUAdapter_Binding::requestDevice_promiseWrapper(JSContext*, JS::Handle<JSObject*>, void*, JSJitMethodCallArgs const&) /builds/worker/workspace/obj-build/dom/bindings/./WebGPUBinding.cpp:12740:13
        #15 0x7fffd99d6692 in bool mozilla::dom::binding_detail::GenericMethod<mozilla::dom::binding_detail::NormalThisPolicy, mozilla::dom::binding_detail::ConvertExceptionsToPromises>(JSContext*, unsigned int, JS::Value*) /gecko/dom/bindings/BindingUtils.cpp:3306:13
        #16 0x3d85d85c750c  ([anon:js-executable-memory]+0x50c)
        #17 0x3d85d85817c2  ([anon:js-executable-memory]+0xa7c2)
        #18 0x3d85d85774e5  ([anon:js-executable-memory]+0x4e5)
        #19 0x7fffe22199e4 in EnterJit /gecko/js/src/jit/Jit.cpp:114:5
        #20 0x7fffe22199e4 in js::jit::MaybeEnterJit(JSContext*, js::RunState&) /gecko/js/src/jit/Jit.cpp:260:10
        #21 0x7fffe06e5049 in js::RunScript(JSContext*, js::RunState&) /gecko/js/src/vm/Interpreter.cpp:461:32
        #22 0x7fffe06e668d in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct, js::CallReason) /gecko/js/src/vm/Interpreter.cpp:629:13
        #23 0x7fffe06e8391 in InternalCall /gecko/js/src/vm/Interpreter.cpp:664:10
        #24 0x7fffe06e8391 in js::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, js::AnyInvokeArgs const&, JS::MutableHandle<JS::Value>, js::CallReason) /gecko/js/src/vm/Interpreter.cpp:696:8
        #25 0x7fffe06ea0ba in js::CallGetter(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, JS::MutableHandle<JS::Value>) /gecko/js/src/vm/Interpreter.cpp:818:10
        #26 0x7fffe0ae648a in CallGetter(JSContext*, JS::Handle<js::NativeObject*>, JS::Handle<JS::Value>, JS::Handle<JS::PropertyKey>, js::PropertyInfoBase<unsigned int>, JS::MutableHandle<JS::Value>) /gecko/js/src/vm/NativeObject.cpp:2125:12
        #27 0x7fffe0ac7c9d in GetExistingProperty<(js::AllowGC)1> /gecko/js/src/vm/NativeObject.cpp:2153:12
        #28 0x7fffe0ac7c9d in NativeGetPropertyInline<(js::AllowGC)1> /gecko/js/src/vm/NativeObject.cpp:2296:14
        #29 0x7fffe0ac7c9d in js::NativeGetProperty(JSContext*, JS::Handle<js::NativeObject*>, JS::Handle<JS::Value>, JS::Handle<JS::PropertyKey>, JS::MutableHandle<JS::Value>) /gecko/js/src/vm/NativeObject.cpp:2326:10
        #30 0x7fffe0a5c5a7 in GetProperty /gecko/js/src/vm/ObjectOperations-inl.h:113:10
        #31 0x7fffe0a5c5a7 in GetProperty /gecko/js/src/vm/ObjectOperations-inl.h:120:10
        #32 0x7fffe0a5c5a7 in GetThenValue(JSContext*, JS::Handle<JSObject*>, JS::Handle<JS::Value>, JS::MutableHandle<JS::Value>, bool*, bool*, bool*) /gecko/js/src/builtin/Promise.cpp:1323:8
        #33 0x7fffe0a5d164 in js::ResolvePromiseInternal(JSContext*, JS::Handle<JSObject*>, JS::Handle<JS::Value>) /gecko/js/src/builtin/Promise.cpp:1400:17
        #34 0x7fffe0a8cb7b in ResolvePromiseFunction(JSContext*, unsigned int, JS::Value*) /gecko/js/src/builtin/Promise.cpp:1520:8
        #35 0x7fffe06e6517 in CallJSNative /gecko/js/src/vm/Interpreter.cpp:501:13
        #36 0x7fffe06e6517 in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct, js::CallReason) /gecko/js/src/vm/Interpreter.cpp:597:12
        #37 0x7fffe06e8391 in InternalCall /gecko/js/src/vm/Interpreter.cpp:664:10
        #38 0x7fffe06e8391 in js::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, js::AnyInvokeArgs const&, JS::MutableHandle<JS::Value>, js::CallReason) /gecko/js/src/vm/Interpreter.cpp:696:8
        #39 0x7fffe0a87e31 in Call /gecko/js/src/vm/Interpreter.h:120:10
        #40 0x7fffe0a87e31 in PromiseReactionJob(JSContext*, unsigned int, JS::Value*) /gecko/js/src/builtin/Promise.cpp:2419:10
        #41 0x7fffe06e6517 in CallJSNative /gecko/js/src/vm/Interpreter.cpp:501:13
        #42 0x7fffe06e6517 in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct, js::CallReason) /gecko/js/src/vm/Interpreter.cpp:597:12
        #43 0x7fffe06e8391 in InternalCall /gecko/js/src/vm/Interpreter.cpp:664:10
        #44 0x7fffe06e8391 in js::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, js::AnyInvokeArgs const&, JS::MutableHandle<JS::Value>, js::CallReason) /gecko/js/src/vm/Interpreter.cpp:696:8
        #45 0x7fffe082a96a in JS::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, JS::HandleValueArray const&, JS::MutableHandle<JS::Value>) /gecko/js/src/vm/CallAndConstruct.cpp:119:10
        #46 0x7fffd3b10f35 in mozilla::PromiseJobRunnable::Call() /gecko/xpcom/base/CycleCollectedJSContext.cpp:214:10
        #47 0x7fffd3b10397 in mozilla::PromiseJobRunnable::Run(mozilla::AutoSlowOperation&) /gecko/xpcom/base/CycleCollectedJSContext.cpp:237:7
        #48 0x7fffd3aea171 in mozilla::CycleCollectedJSContext::PerformMicroTaskCheckPoint(bool) /gecko/xpcom/base/CycleCollectedJSContext.cpp:872:17
    
    SUMMARY: AddressSanitizer: heap-use-after-free /gecko/dom/webgpu/ipc/WebGPUChild.cpp:460:32 in mozilla::webgpu::WebGPUChild::ClearAllPendingPromises()
    Shadow bytes around the buggy address:
      0x5120003cf180: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
      0x5120003cf200: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
      0x5120003cf280: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
      0x5120003cf300: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd
      0x5120003cf380: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
    =>0x5120003cf400: fd fd[fd]fd fd fd fd fd fd fd fd fd fd fd fa fa
      0x5120003cf480: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
      0x5120003cf500: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
      0x5120003cf580: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
      0x5120003cf600: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00
      0x5120003cf680: 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
      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
    ==322095==ABORTING
Group: core-security → gfx-core-security

This looks like iterator invalidation in mozilla::webgpu::WebGPUChild::ClearAllPendingPromises(). That function iterates over pending promises:

for (auto& pending_promise : mPendingRequestDevicePromises) {

You can see in both the use and the free have this method in the stack. From the free stack, it looks like we resolve one of the pending promises, which runs JS, which calls Adapter::RequestDevice(), which mutates mPendingRequestDevicePromises, invalidating our iteration.

It looks like WebGPUChild::ClearAllPendingPromises() was added recently so I'll mark this as a regression.

Keywords: regression
Regressed by: 1968122

Needless to say, I'd expect there's a similar potential problem for every one of these other loops in ClearAllPendingPromises which are resolving promises.

:teoxoy, since you are the author of the regressor, bug 1968122, could you take a look? Also, could you set the severity field?

For more information, please visit BugBot documentation.

Flags: needinfo?(ttanasoaia)
Assignee: nobody → ttanasoaia
Status: NEW → ASSIGNED
Flags: needinfo?(ttanasoaia)

I tried to build a repro for this without success using variations of:

for (let i = 0; i < 10; i++) {
    navigator.gpu.requestAdapter().then(a => a.requestDevice().then(d => d.lost.then(lr => {
        for (let i = 0; i < 100; i++) {
            a.requestDevice()
        }
    })))
}

+ killing the GPU process.

The patch should fix the issue but would someone from the fuzzing team be able to try the patch?

Flags: needinfo?(jkratzer)

I won't be requesting sec-approval since the code in question has only been shipped in Nightly 142.

Summary: AddressSanitizer: heap-use-after-free [@ _M_set_node] with READ of size 8 → AddressSanitizer: heap-use-after-free [@ _M_set_node] with READ of size 8 from WebGPUChild::ClearAllPendingPromises()

(In reply to Teodor Tanasoaia [:teoxoy] from comment #5)

The patch should fix the issue but would someone from the fuzzing team be able to try the patch?

I'm not sure I can be of much help. The fuzzers have only reported this once and I haven't been able to get a proof-of-concept working myself either.

Flags: needinfo?(jkratzer)
Pushed by ttanasoaia@mozilla.com: https://github.com/mozilla-firefox/firefox/commit/a91ed47a845c https://hg.mozilla.org/integration/autoland/rev/b331577c597a Pop pending promises off of queues in `ClearAllPendingPromises`. r=webgpu-reviewers,nical
Group: gfx-core-security → core-security-release
Status: ASSIGNED → RESOLVED
Closed: 10 months ago
Resolution: --- → FIXED
Target Milestone: --- → 142 Branch
QA Whiteboard: [sec] [qa-triage-done-c143/b142]
Flags: qe-verify-
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: