High firefox UAF 🔧 Commit mapped

Overview

High
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
Impacthigh
DescriptionStarting with Firefox 142, it was possible for a compromised child process to trigger a use-after-free in the GPU or browser process using WebGPU-related IPC calls. This may have been usable to escape the child process sandbox.
ComponentDOM
Bug ClassUAF
Tracker1993113
Fix commit132a4cb3cf93 (firefox) +11/-10
CISA KEVNot listed
CreditedOskar L
Disclosed2025-10-28

Changed Functions

FunctionChangeNotes
if
dom/webgpu/ipc/WebGPUParent.cpp
modified

Files Changed

  • dom/webgpu/ipc/WebGPUParent.cpp
  • dom/webgpu/ipc/WebGPUParent.h
diff --git a/dom/webgpu/ipc/WebGPUParent.cpp b/dom/webgpu/ipc/WebGPUParent.cpp
index 83d73031ce7..f7ffdb32d96 100644
--- a/dom/webgpu/ipc/WebGPUParent.cpp
+++ b/dom/webgpu/ipc/WebGPUParent.cpp
@@ -216,11 +216,11 @@ extern void wgpu_server_set_buffer_map_data(
     uintptr_t aShmemIndex) {
   auto* parent = static_cast<WebGPUParent*>(aParent);
 
-  auto mapping = std::move(parent->mTempMappings.ElementAt(aShmemIndex));
-  MOZ_ASSERT(mapping.isSome());
+  auto mapping = parent->mTempMappings.ElementAt(aShmemIndex);
+  MOZ_ASSERT(mapping);
 
   auto data = WebGPUParent::BufferMapData{
-      std::move(*mapping), aHasMapFlags, aMappedOffset, aMappedSize, aDeviceId,
+      mapping, aHasMapFlags, aMappedOffset, aMappedSize, aDeviceId,
   };
 
   parent->mSharedMemoryMap.insert({aBufferId, std::move(data)});
@@ -737,9 +737,9 @@ void WebGPUParent::MapCallback(uint8_t* aUserData,
 
       MOZ_RELEASE_ASSERT(!error.GetError());
 
-      MOZ_RELEASE_ASSERT(mapData->mShmem.Size() >= offset + size);
+      MOZ_RELEASE_ASSERT(mapData->mShmem->Size() >= offset + size);
       if (src.ptr != nullptr && src.length >= size) {
-        auto dst = mapData->mShmem.DataAsSpan<uint8_t>().Subspan(offset, size);
+        auto dst = mapData->mShmem->DataAsSpan<uint8_t>().Subspan(offset, size);
         memcpy(dst.data(), src.ptr, size);
       }
     }
@@ -774,11 +774,11 @@ void WebGPUParent::BufferUnmap(RawId aDeviceId, RawId aBufferId, bool aFlush) {
     ForwardError(getRangeError);
 
     if (mapped.ptr != nullptr && mapped.length >= size) {
-      auto shmSize = mapData->mShmem.Size();
+      auto shmSize = mapData->mShmem->Size();
       MOZ_RELEASE_ASSERT(offset <= shmSize);
       MOZ_RELEASE_ASSERT(size <= shmSize - offset);
 
-      auto src = mapData->mShmem.DataAsSpan<uint8_t>().Subspan(offset, size);
+      auto src = mapData->mShmem->DataAsSpan<uint8_t>().Subspan(offset, size);
       memcpy(mapped.ptr, src.data(), size);
     }
 
@@ -1584,7 +1584,8 @@ ipc::IPCResult WebGPUParent::RecvMessages(
 
     // `aShmem` may be an invalid handle, however this will simply result in an
     // invalid mapping with 0 size, which we use safely.
-    mTempMappings.AppendElement(Some(std::move(mapping)));
+    mTempMappings.AppendElement(
+        std::make_shared<ipc::SharedMemoryMapping>(std::move(mapping)));
   }
 
   ffi::WGPUFfiSlice_ByteBuf data_buffers{ToFFI(aDataBuffers.Elements()),
diff --git a/dom/webgpu/ipc/WebGPUParent.h b/dom/webgpu/ipc/WebGPUParent.h
index ba1faa4497f..2e3a60ae1b0 100644
--- a/dom/webgpu/ipc/WebGPUParent.h
+++ b/dom/webgpu/ipc/WebGPUParent.h
@@ -135,7 +135,7 @@ class WebGPUParent final : public PWebGPUParent, public SupportsWeakPtr {
   void ActorDestroy(ActorDestroyReason aWhy) override;
 
   struct BufferMapData {
-    ipc::SharedMemoryMapping mShmem;
+    std::shared_ptr<ipc::SharedMemoryMapping> mShmem;
     // True if buffer's usage has MAP_READ or MAP_WRITE set.
     bool mHasMapFlags;
     uint64_t mMappedOffset;
@@ -219,7 +219,7 @@ class WebGPUParent final : public PWebGPUParent, public SupportsWeakPtr {
 
   void ReportError(RawId aDeviceId, GPUErrorFilter, const nsCString& message);
 
-  nsTArray<Maybe<ipc::shared_memory::MutableMapping>> mTempMappings;
+  nsTArray<std::shared_ptr<ipc::SharedMemoryMapping>> mTempMappings;
 
   /// A map from wgpu buffer ids to data about their shared memory segments.
   /// Includes entries about mappedAtCreation, MAP_READ and MAP_WRITE buffers,
Loading diff…