Closed Bug 1799753 Opened 2 years ago Closed 1 year ago

Hit MOZ_CRASH(called `Option::unwrap()` on a `None` value) at gfx/wgpu_bindings/src/client.rs:50

Categories

(Core :: Graphics: WebGPU, defect)

x86_64
Linux
defect

Tracking

()

VERIFIED FIXED
111 Branch
Tracking Status
firefox-esr102 --- unaffected
firefox109 --- disabled
firefox110 --- disabled
firefox111 --- verified

People

(Reporter: jkratzer, Assigned: jimb)

References

(Blocks 2 open bugs)

Details

(Keywords: testcase, Whiteboard: [bugmon:bisected,confirmed][fuzzblocker])

Attachments

(3 files)

Testcase found while fuzzing mozilla-central rev 2db9822e6dd3 (built with: --enable-address-sanitizer --enable-fuzzing).

Testcase can be reproduced using the following commands:

$ pip install fuzzfetch grizzly-framework
$ python -m fuzzfetch --build 2db9822e6dd3 --asan --fuzzing -n firefox
$ python -m grizzly.replay ./firefox/firefox testcase.html
Hit MOZ_CRASH(called `Option::unwrap()` on a `None` value) at gfx/wgpu_bindings/src/client.rs:50

    =================================================================
    ==213258==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000001 (pc 0x7f8836672c58 bp 0x7fff42845f70 sp 0x7fff42845f60 T0)
    ==213258==The signal is caused by a WRITE memory access.
    ==213258==Hint: address points to the zero page.
        #0 0x7f8836672c58 in MOZ_Crash /builds/worker/workspace/obj-build/dist/include/mozilla/Assertions.h:261:3
        #1 0x7f8836672c58 in RustMozCrash /mozglue/static/rust/wrappers.cpp:18:3
        #2 0x7f8836672b1b in mozglue_static::panic_hook::h5e6e941c0b6f7b06 /mozglue/static/rust/lib.rs:91:9
        #3 0x7f88366717e5 in core::ops::function::Fn::call::hd40b7d5858ce3fbf /builds/worker/fetches/rust/library/core/src/ops/function.rs:77:5
        #4 0x7f8839dd89e3 in std::panicking::rust_panic_with_hook::hf741e7da97ac32b1 (/home/jkratzer/builds/m-c-20221031214452-fuzzing-asan-opt/libxul.so+0x21fc69e3) (BuildId: e17b340f4735785fc01387a1afe47b7d3bd691c1)
        #5 0x7f8839e02ee8 in std::panicking::begin_panic_handler::_$u7b$$u7b$closure$u7d$$u7d$::h9699bbb97ca082c0 std.fd78a544-cgu.8
        #6 0x7f8839e02d03 in std::sys_common::backtrace::__rust_end_short_backtrace::hd983e22c717e2a19 crtstuff.c
        #7 0x7f8839dd8521 in rust_begin_unwind (/home/jkratzer/builds/m-c-20221031214452-fuzzing-asan-opt/libxul.so+0x21fc6521) (BuildId: e17b340f4735785fc01387a1afe47b7d3bd691c1)
        #8 0x7f8821b9ecf2 in core::panicking::panic_fmt::hfaf555757b631db9 (/home/jkratzer/builds/m-c-20221031214452-fuzzing-asan-opt/libxul.so+0x9d8ccf2) (BuildId: e17b340f4735785fc01387a1afe47b7d3bd691c1)
        #9 0x7f8821b9ebbc in core::panicking::panic::he75d6407e3070370 (/home/jkratzer/builds/m-c-20221031214452-fuzzing-asan-opt/libxul.so+0x9d8cbbc) (BuildId: e17b340f4735785fc01387a1afe47b7d3bd691c1)
        #10 0x7f8833000886 in core::option::Option$LT$T$GT$::unwrap::hbe7c1326f9ece18b /builds/worker/fetches/rust/library/core/src/option.rs:775:21
        #11 0x7f8833000886 in wgpu_bindings::client::ProgrammableStageDescriptor::to_wgpu::hb82d44223e36be8e /gfx/wgpu_bindings/src/client.rs:50:26
        #12 0x7f8833000886 in wgpu_client_create_compute_pipeline /gfx/wgpu_bindings/src/client.rs:945:16
        #13 0x7f8828559687 in mozilla::webgpu::WebGPUChild::DeviceCreateComputePipelineImpl(mozilla::webgpu::PipelineCreationContext*, mozilla::dom::GPUComputePipelineDescriptor const&, mozilla::ipc::ByteBuf*) /dom/webgpu/ipc/WebGPUChild.cpp:744:14
        #14 0x7f8828559cd0 in mozilla::webgpu::WebGPUChild::DeviceCreateComputePipeline(mozilla::webgpu::PipelineCreationContext*, mozilla::dom::GPUComputePipelineDescriptor const&) /dom/webgpu/ipc/WebGPUChild.cpp:760:20
        #15 0x7f88285256cb in mozilla::webgpu::Device::CreateComputePipeline(mozilla::dom::GPUComputePipelineDescriptor const&) /dom/webgpu/Device.cpp:216:19
        #16 0x7f882742280d in mozilla::dom::GPUDevice_Binding::createComputePipeline(JSContext*, JS::Handle<JSObject*>, void*, JSJitMethodCallArgs const&) /builds/worker/workspace/obj-build/dom/bindings/WebGPUBinding.cpp:19441:85
        #17 0x7f8827d4fe0f in bool mozilla::dom::binding_detail::GenericMethod<mozilla::dom::binding_detail::NormalThisPolicy, mozilla::dom::binding_detail::ThrowExceptions>(JSContext*, unsigned int, JS::Value*) /dom/bindings/BindingUtils.cpp:3287:13
        #18 0x7f883263d8d3 in CallJSNative /js/src/vm/Interpreter.cpp:459:13
        #19 0x7f883263d8d3 in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct, js::CallReason) /js/src/vm/Interpreter.cpp:547:12
        #20 0x7f883262c207 in InternalCall /js/src/vm/Interpreter.cpp:614:10
        #21 0x7f883262c207 in CallFromStack /js/src/vm/Interpreter.cpp:619:10
        #22 0x7f883262c207 in Interpret(JSContext*, js::RunState&) /js/src/vm/Interpreter.cpp:3375:16
        #23 0x7f883261177e in js::RunScript(JSContext*, js::RunState&) /js/src/vm/Interpreter.cpp:431:13
        #24 0x7f883263d9f5 in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct, js::CallReason) /js/src/vm/Interpreter.cpp:579:13
        #25 0x7f883263f49e in InternalCall /js/src/vm/Interpreter.cpp:614:10
        #26 0x7f883263f49e 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:646:8
        #27 0x7f8830fb3714 in js::CallSelfHostedFunction(JSContext*, JS::Handle<js::PropertyName*>, JS::Handle<JS::Value>, js::AnyInvokeArgs const&, JS::MutableHandle<JS::Value>) /js/src/vm/SelfHosting.cpp:1488:10
        #28 0x7f8830bfff41 in AsyncFunctionResume(JSContext*, JS::Handle<js::AsyncFunctionGeneratorObject*>, ResumeKind, JS::Handle<JS::Value>) /js/src/vm/AsyncFunction.cpp:154:8
        #29 0x7f8830edc67e in AsyncFunctionPromiseReactionJob(JSContext*, JS::Handle<PromiseReactionRecord*>) /js/src/builtin/Promise.cpp:2111:12
        #30 0x7f8830eda474 in PromiseReactionJob(JSContext*, unsigned int, JS::Value*) /js/src/builtin/Promise.cpp:2174:12
        #31 0x7f883263d8d3 in CallJSNative /js/src/vm/Interpreter.cpp:459:13
        #32 0x7f883263d8d3 in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct, js::CallReason) /js/src/vm/Interpreter.cpp:547:12
        #33 0x7f883263f49e in InternalCall /js/src/vm/Interpreter.cpp:614:10
        #34 0x7f883263f49e 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:646:8
        #35 0x7f8830c3c2c5 in JS::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, JS::HandleValueArray const&, JS::MutableHandle<JS::Value>) /js/src/vm/CallAndConstruct.cpp:117:10
        #36 0x7f8826aa534c in mozilla::dom::PromiseJobCallback::Call(mozilla::dom::BindingCallContext&, JS::Handle<JS::Value>, mozilla::ErrorResult&) /builds/worker/workspace/obj-build/dom/bindings/PromiseBinding.cpp:83:8
        #37 0x7f88227f1dd7 in Call /builds/worker/workspace/obj-build/dist/include/mozilla/dom/PromiseBinding.h:198:12
        #38 0x7f88227f1dd7 in Call /builds/worker/workspace/obj-build/dist/include/mozilla/dom/PromiseBinding.h:211:12
        #39 0x7f88227f1dd7 in mozilla::PromiseJobRunnable::Run(mozilla::AutoSlowOperation&) /xpcom/base/CycleCollectedJSContext.cpp:213:18
        #40 0x7f88227d24d7 in mozilla::CycleCollectedJSContext::PerformMicroTaskCheckPoint(bool) /xpcom/base/CycleCollectedJSContext.cpp:676:17
        #41 0x7f88227d352f in mozilla::CycleCollectedJSContext::AfterProcessTask(unsigned int) /xpcom/base/CycleCollectedJSContext.cpp:463:3
        #42 0x7f88244c0790 in XPCJSContext::AfterProcessTask(unsigned int) /js/xpconnect/src/XPCJSContext.cpp:1480:28
        #43 0x7f8822a138b8 in nsThread::ProcessNextEvent(bool, bool*) /xpcom/threads/nsThread.cpp:1241:24
        #44 0x7f8822a1de14 in NS_ProcessNextEvent(nsIThread*, bool) /xpcom/threads/nsThreadUtils.cpp:465:10
        #45 0x7f88241d41e4 in mozilla::ipc::MessagePump::Run(base::MessagePump::Delegate*) /ipc/glue/MessagePump.cpp:107:5
        #46 0x7f8824050ed1 in RunInternal /ipc/chromium/src/base/message_loop.cc:381:10
        #47 0x7f8824050ed1 in RunHandler /ipc/chromium/src/base/message_loop.cc:374:3
        #48 0x7f8824050ed1 in MessageLoop::Run() /ipc/chromium/src/base/message_loop.cc:356:3
        #49 0x7f882b5551d7 in nsBaseAppShell::Run() /widget/nsBaseAppShell.cpp:150:27
        #50 0x7f8830765c37 in XRE_RunAppShell() /toolkit/xre/nsEmbedFunctions.cpp:884:20
        #51 0x7f8824050ed1 in RunInternal /ipc/chromium/src/base/message_loop.cc:381:10
        #52 0x7f8824050ed1 in RunHandler /ipc/chromium/src/base/message_loop.cc:374:3
        #53 0x7f8824050ed1 in MessageLoop::Run() /ipc/chromium/src/base/message_loop.cc:356:3
        #54 0x7f8830764d23 in XRE_InitChildProcess(int, char**, XREChildData const*) /toolkit/xre/nsEmbedFunctions.cpp:743:34
        #55 0x5555dd71c6b5 in content_process_main(mozilla::Bootstrap*, int, char**) /browser/app/../../ipc/contentproc/plugin-container.cpp:57:28
        #56 0x5555dd71cb07 in main /browser/app/nsBrowserApp.cpp:357:18
        #57 0x7f884b0e2d8f in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
        #58 0x7f884b0e2e3f in __libc_start_main csu/../csu/libc-start.c:392:3
        #59 0x5555dd65ca19 in _start (/home/jkratzer/builds/m-c-20221031214452-fuzzing-asan-opt/firefox+0x7aa19) (BuildId: a3b6dbd004682c6755802e59474064f859bfb56b)
    
    AddressSanitizer can not provide additional info.
    SUMMARY: AddressSanitizer: SEGV /builds/worker/workspace/obj-build/dist/include/mozilla/Assertions.h:261:3 in MOZ_Crash
    ==213258==ABORTING
Attached file Testcase

Verified bug as reproducible on mozilla-central 20221108213602-ca4db8d37ef9.
Unable to bisect testcase (Testcase reproduces on start build!):

Start: 333f08065c8c5470603b9d50b4dd45f8da8bfff5 (20211110092453)
End: 2db9822e6dd36ebcb94adbfa54031b471988fa1e (20221031214452)
BuildFlags: BuildFlags(asan=True, tsan=False, debug=False, fuzzing=True, coverage=False, valgrind=False, no_opt=False, fuzzilli=False, nyx=False)

Whiteboard: [bugmon:confirm] → [bugmon:bisected,confirmed]

The severity field is not set for this bug.
:jimb, could you have a look please?

For more information, please visit auto_nag documentation.

Flags: needinfo?(jimb)
Flags: in-testsuite?

These has been a spike in results over the last day, marking as a fuzzblocker for now.

Whiteboard: [bugmon:bisected,confirmed] → [bugmon:bisected,confirmed][fuzzblocker]
Flags: needinfo?(jimb)

WebGPUChild::DeviceCreateComputePipelineImpl uses LossyCopyUTF16toASCII to convert the entry point name to an nsCString. For historical reasons, the ASCII in that function name actually means Latin1: the result can contain arbitrary bytes.

wgpu_bindings::client::ProgrammableStageDescriptor::to_wgpu then passes the entry point name to cow_label, which checks if those bytes are UTF-8. If they are not, it returns None, which causes the panic.

Unfortunately, LossyCopyUTF16toASCII leaves garbage in the buffer if the string can't be converted to Latin-1. That means that if you happen to get a null byte in there soon enough that it doesn't fail to be UTF-8, then the crash doesn't reproduce. On my system, I just get entry point names like "N\u{18}*", and I get a nice error in the console.

Attached file better testcase

Here's a testcase that doesn't depend on uninitialized memory contents: it's got a UTF-8 entry point name that, when converted to a JavaScript string and passed through LossyCopyUTF16toASCII, reliably produces a Latin-1 string that is not UTF-8.

In WebGPU, entry point names and labels from types like
GPUComputePipelineDescriptor eventually get turned into Rust &str values.

The prior code used LossyCopyUTF16ToASCII to produce nsCStrings from the
nsStrings received from the WebIDL bindings, and then passed the resulting
bytes to Rust std::ffi::CStr::to_str. Unfortunately, that "ASCII" actually
means Latin-1, so if the entry point named happened to be representable in
Latin-1 that happened not to be valid UTF-8, wgpu_bindings::cow_label would
return None, leading to a panic when unwrapped by
wgpu_bindings::client::ProgrammableStageDescriptor::to_wgpu.

The fix: just call CopyUTF16ToUTF8 instead. This should always produce bytes
that CStr::to_str can consume. The WebIDL for WebGPU uses USVString for
entry point names and labels, so these values should never contain unpaired
surrogate code points, meaning that conversion should always succeed.

Assignee: nobody → jimb
Status: NEW → ASSIGNED
Pushed by jblandy@mozilla.com:
https://hg.mozilla.org/integration/autoland/rev/2aa60483b352
Use CopyUTF16toUTF8 for strings destined for `cow_label`. r=ErichDonGubler
Status: ASSIGNED → RESOLVED
Closed: 1 year ago
Resolution: --- → FIXED
Target Milestone: --- → 111 Branch

Verified bug as fixed on rev mozilla-central 20230128211106-f4f63f0138fe.
Removing bugmon keyword as no further action possible. Please review the bug and re-add the keyword for further analysis.

Status: RESOLVED → VERIFIED
Keywords: bugmon

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

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

For more information, please visit auto_nag documentation.

Flags: needinfo?(jimb)
See Also: → 1771250
See Also: → 1813111
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: