High firefox Sandbox Escape 🔧 Commit mapped

Overview

High
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
Impacthigh
DescriptionSandbox escape due to incorrect boundary conditions in the Graphics: WebGPU component
ComponentDOM
Bug ClassSandbox Escape
Tracker1994441
Fix commit73966626d36e (firefox) +119/-137
CISA KEVNot listed
CreditedJamie Nicol
Disclosed2025-11-11

Changed Functions

FunctionChangeNotes
if
dom/webgpu/ExternalTexture.cpp
modified
switch
dom/webgpu/ExternalTexture.cpp
modified

Files Changed

  • dom/webgpu/ExternalTexture.cpp
  • dom/webgpu/ExternalTexture.h
  • gfx/layers/composite/TextureHost.cpp
  • gfx/layers/composite/TextureHost.h
  • gfx/layers/d3d11/TextureD3D11.cpp
  • gfx/layers/d3d11/TextureD3D11.h
  • gfx/layers/opengl/MacIOSurfaceTextureHostOGL.cpp
  • gfx/layers/opengl/MacIOSurfaceTextureHostOGL.h
  • gfx/webrender_bindings/RenderD3D11TextureHost.cpp
  • gfx/webrender_bindings/RenderD3D11TextureHost.h
diff --git a/dom/webgpu/ExternalTexture.cpp b/dom/webgpu/ExternalTexture.cpp
index 84b269ec1a7..ca4f83c2dfc 100644
--- a/dom/webgpu/ExternalTexture.cpp
+++ b/dom/webgpu/ExternalTexture.cpp
@@ -28,9 +28,11 @@
 #ifdef XP_WIN
 #  include "mozilla/layers/CompositeProcessD3D11FencesHolderMap.h"
 #  include "mozilla/layers/GpuProcessD3D11TextureMap.h"
+#  include "mozilla/layers/TextureD3D11.h"
 #endif
 #ifdef XP_MACOSX
 #  include "mozilla/gfx/MacIOSurface.h"
+#  include "mozilla/layers/MacIOSurfaceTextureHostOGL.h"
 #endif
 
 namespace mozilla::webgpu {
@@ -446,6 +448,12 @@ ExternalTextureSourceHost::ExternalTextureSourceHost(
 
       const auto videoBridge =
           layers::VideoBridgeParent::GetSingleton(remoteDecoderDesc.source());
+      if (!videoBridge) {
+        gfxCriticalErrorOnce() << "Failed to get VideoBridge";
+        aParent->ReportError(aDeviceId, dom::GPUErrorFilter::Internal,
+                             "Failed to get VideoBridge"_ns);
+        return CreateError();
+      }
       const RefPtr<layers::TextureHost> textureHost =
           videoBridge->LookupTexture(aParent->mContentId,
                                      remoteDecoderDesc.handle());
@@ -455,61 +463,30 @@ ExternalTextureSourceHost::ExternalTextureSourceHost(
                              "Failed to lookup remote decoder texture"_ns);
         return CreateError();
       }
-      const layers::RemoteDecoderVideoSubDescriptor& subDesc =
-          remoteDecoderDesc.subdesc();
-
-      switch (subDesc.type()) {
-        case layers::RemoteDecoderVideoSubDescriptor::Tnull_t: {
-          const RefPtr<layers::BufferTextureHost> bufferHost =
-              textureHost->AsBufferTextureHost();
-          if (!bufferHost) {
-            gfxCriticalNoteOnce << "Unexpected TextureHost type";
-            aParent->ReportError(aDeviceId, dom::GPUErrorFilter::Internal,
-                                 "Unexpected TextureHost type"_ns);
-            return CreateError();
-          }
-          return CreateFromBufferDesc(
-              aParent, aDeviceId, aQueueId, aDesc,
-              bufferHost->GetBufferDescriptor(),
-              Span(bufferHost->GetBuffer(), bufferHost->GetBufferSize()));
-        } break;
-
-        case layers::RemoteDecoderVideoSubDescriptor::TSurfaceDescriptorD3D10: {
-          const layers::SurfaceDescriptorD3D10& d3d10Desc =
-              subDesc.get_SurfaceDescriptorD3D10();
-          return CreateFromD3D10Desc(aParent, aDeviceId, aQueueId, aDesc,
-                                     d3d10Desc, textureHost->GetFormat());
-        } break;
-
-        case layers::RemoteDecoderVideoSubDescriptor::
-            TSurfaceDescriptorDXGIYCbCr: {
-          const layers::SurfaceDescriptorDXGIYCbCr& dxgiDesc =
-              subDesc.get_SurfaceDescriptorDXGIYCbCr();
-          return CreateFromDXGIYCbCrDesc(aParent, aDeviceId, aQueueId, aDesc,
-                                         dxgiDesc);
-        } break;
-
-        case layers::RemoteDecoderVideoSubDescriptor::
-            TSurfaceDescriptorMacIOSurface: {
-          return CreateFromMacIOSurfaceDesc(
-              aParent, aDeviceId, aDesc,
-              subDesc.get_SurfaceDescriptorMacIOSurface());
-        } break;
-
-        case layers::RemoteDecoderVideoSubDescriptor::T__None:
-        case layers::RemoteDecoderVideoSubDescriptor::TSurfaceDescriptorDMABuf:
-        case layers::RemoteDecoderVideoSubDescriptor::
-            TSurfaceDescriptorDcompSurface: {
-          gfxCriticalErrorOnce()
-              << "Unexpected RemoteDecoderVideoSubDescriptor type: "
-              << subDesc.type();
-          aParent->ReportError(
-              aDeviceId, dom::GPUErrorFilter::Internal,
-              nsPrintfCString(
-                  "Unexpected RemoteDecoderVideoSubDescriptor type: %d",
-                  subDesc.type()));
-          return CreateError();
-        } break;
+
+      if (const auto* bufferHost = textureHost->AsBufferTextureHost()) {
+        return CreateFromBufferDesc(
+            aParent, aDeviceId, aQueueId, aDesc,
+            bufferHost->GetBufferDescriptor(),
+            Span(bufferHost->GetBuffer(), bufferHost->GetBufferSize()));
+      } else if (const auto* dxgiHost = textureHost->AsDXGITextureHostD3D11()) {
+        return CreateFromDXGITextureHost(aParent, aDeviceId, aQueueId, aDesc,
+                                         dxgiHost);
+      } else if (const auto* dxgiYCbCrHost =
+                     textureHost->AsDXGIYCbCrTextureHostD3D11()) {
+        return CreateFromDXGIYCbCrTextureHost(aParent, aDeviceId, aQueueId,
+                                              aDesc, dxgiYCbCrHost);
+      } else if (const auto* ioSurfHost =
+                     textureHost->AsMacIOSurfaceTextureHost()) {
+        return CreateFromMacIOSurfaceTextureHost(aParent, aDeviceId, aDesc,
+                                                 ioSurfHost);
+      } else {
+        gfxCriticalErrorOnce()
+            << "Unexpected SurfaceDescriptorGPUVideo TextureHost type";
+        aParent->ReportError(
+            aDeviceId, dom::GPUErrorFilter::Internal,
+            "Unexpected SurfaceDescriptorGPUVideo TextureHost type"_ns);
+        return CreateError();
       }
     } break;
     default:
@@ -527,9 +504,9 @@ ExternalTextureSourceHost::ExternalTextureSourceHost(
 ExternalTextureSourceHost::CreateFromBufferDesc(
     WebGPUParent* aParent, RawId aDeviceId, RawId aQueueId,
     const ExternalTextureSourceDescriptor& aDesc,
-    const layers::BufferDescriptor& aSd, Span<uint8_t> aBuffer) {
+    const layers::BufferDescriptor& aBufferDesc, Span<uint8_t> aBuffer) {
   const gfx::SurfaceFormat format =
-      layers::ImageDataSerializer::FormatFromBufferDescriptor(aSd);
+      layers::ImageDataSerializer::FormatFromBufferDescriptor(aBufferDesc);
   // Creates a texture and view for a single plane, and writes the provided data
   // to the texture.
   auto createPlane = [aParent, aDeviceId, aQueueId](
@@ -601,9 +578,9 @@ ExternalTextureSourceHost::CreateFromBufferDesc(
   AutoTArray<RawId, 3> usedTextureIds;
   AutoTArray<RawId, 3> usedViewIds;
   gfx::YUVRangedColorSpace colorSpace;
-  switch (aSd.type()) {
+  switch (aBufferDesc.type()) {
     case layers::BufferDescriptor::TRGBDescriptor: {
-      const layers::RGBDescriptor& rgbDesc = aSd.get_RGBDescriptor();
+      const layers::RGBDescriptor& rgbDesc = aBufferDesc.get_RGBDescriptor();
       ffi::WGPUTextureFormat planeFormat;
       switch (rgbDesc.format()) {
         case gfx::SurfaceFormat::B8G8R8A8:
@@ -631,11 +608,12 @@ ExternalTextureSourceHost::CreateFromBufferDesc(
       colorSpace = gfx::YUVRangedColorSpace::GbrIdentity;
     } break;
     case layers::BufferDescriptor::TYCbCrDescriptor: {
-      const layers::YCbCrDescriptor& yCbCrDesc = aSd.get_YCbCrDescriptor();
+      const layers::YCbCrDescriptor& yCbCrDesc =
+          aBufferDesc.get_YCbCrDescriptor();
       const gfx::IntSize ySize =
-          layers::ImageDataSerializer::SizeFromBufferDescriptor(aSd);
+          layers::ImageDataSerializer::SizeFromBufferDescriptor(aBufferDesc);
       const gfx::IntSize cbCrSize =
-          layers::ImageDataSerializer::GetCroppedCbCrSize(aSd);
+          layers::ImageDataSerializer::GetCroppedCbCrSize(aBufferDesc);
 
       ffi::WGPUTextureFormat planeFormat;
       switch (yCbCrDesc.colorDepth()) {
@@ -690,20 +668,20 @@ ExternalTextureSourceHost::CreateError() {
 }
 
 /* static */ ExternalTextureSourceHost
-ExternalTextureSourceHost::CreateFromD3D10Desc(
+ExternalTextureSourceHost::CreateFromDXGITextureHost(
     WebGPUParent* aParent, RawId aDeviceId, RawId aQueueId,
     const ExternalTextureSourceDescriptor& aDesc,
-    const layers::SurfaceDescriptorD3D10& aSd, gfx::SurfaceFormat aFormat) {
+    const layers::DXGITextureHostD3D11* aTextureHost) {
 #ifdef XP_WIN
-  const auto& gpuProcessTextureId = aSd.gpuProcessTextureId();
   Maybe<HANDLE> handle;
-  if (gpuProcessTextureId) {
+  if (aTextureHost->mGpuProcessTextureId) {
     auto* textureMap = layers::GpuProcessD3D11TextureMap::Get();
     if (textureMap) {
-      handle = textureMap->GetSharedHandle(gpuProcessTextureId.ref());
+      handle =
+          textureMap->GetSharedHandle(aTextureHost->mGpuProcessTextureId.ref());
     }
-  } else if (aSd.handle()) {
-    handle.emplace(aSd.handle()->GetHandle());
+  } else if (aTextureHost->mHandle) {
+    handle.emplace(aTextureHost->mHandle->GetHandle());
   }
 
   if (!handle) {
@@ -714,12 +692,13 @@ ExternalTextureSourceHost::CreateFromD3D10Desc(
   }
 
   const gfx::YUVRangedColorSpace colorSpace = gfx::ToYUVRangedColorSpace(
-      gfx::ToYUVColorSpace(aSd.colorSpace()), aSd.colorRange());
+      gfx::ToYUVColorSpace(aTextureHost->mColorSpace),
+      aTextureHost->mColorRange);
 
   ffi::WGPUTextureFormat textureFormat;
   AutoTArray<std::pair<ffi::WGPUTextureFormat, ffi::WGPUTextureAspect>, 2>
       viewFormatAndAspects;
-  switch (aFormat) {
+  switch (aTextureHost->mFormat) {
     case gfx::SurfaceFormat::R8G8B8A8:
     case gfx::SurfaceFormat::R8G8B8X8:
       textureFormat = {ffi::WGPUTextureFormat_Rgba8Unorm};
@@ -751,10 +730,12 @@ ExternalTextureSourceHost::CreateFromD3D10Desc(
Loading diff…