High firefox OOB 🔧 Commit mapped

Overview

High
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
Impacthigh
DescriptionA compromised web process was able to trigger out of bounds reads and writes in a more privileged process using manipulated WebGL textures.
ComponentDOM
Bug ClassOOB
Tracker1989127
Fix commitc933f3b42d7a (firefox) +17/-8
CISA KEVNot listed
CreditedOskar L
Disclosed2025-10-14

Changed Functions

FunctionChangeNotes
if
dom/canvas/TexUnpackBlob.cpp
modified

Files Changed

  • dom/canvas/TexUnpackBlob.cpp
diff --git a/dom/canvas/TexUnpackBlob.cpp b/dom/canvas/TexUnpackBlob.cpp
index 12803558bd9..79b5288c662 100644
--- a/dom/canvas/TexUnpackBlob.cpp
+++ b/dom/canvas/TexUnpackBlob.cpp
@@ -393,7 +393,7 @@ bool TexUnpackBlob::ConvertIfNeeded(
 
   const auto& unpacking = mDesc.unpacking;
 
-  if (!rowLength || !rowCount) return true;
+  if (!rowLength || !rowCount || srcStride <= 0 || dstStride <= 0) return true;
 
   const auto srcIsPremult = (mDesc.srcAlphaType == gfxAlphaType::Premult);
   auto dstIsPremult = unpacking.premultiplyAlpha;
@@ -1084,9 +1084,20 @@ bool TexUnpackSurface::TexOrSubImage(bool isSubImage, bool needsRespec,
       const auto& data = sdb.data();
       MOZ_ASSERT(data.type() == layers::MemoryOrShmem::TShmem);
       const auto& shmem = data.get_Shmem();
-      surf = gfx::Factory::CreateWrappingDataSourceSurface(
-          shmem.get<uint8_t>(), layers::ImageDataSerializer::GetRGBStride(rgb),
+      size_t shmemSize = shmem.Size<uint8_t>();
+      int32_t stride = layers::ImageDataSerializer::GetRGBStride(rgb);
+      if (stride <= 0) {
+        gfxCriticalError() << "TexUnpackSurface failed to get rgb stride";
+        return false;
+      }
+      size_t bufSize = layers::ImageDataSerializer::ComputeRGBBufferSize(
           rgb.size(), rgb.format());
+      if (!bufSize || bufSize > shmemSize) {
+        gfxCriticalError() << "TexUnpackSurface failed to get rgb buffer size";
+        return false;
+      }
+      surf = gfx::Factory::CreateWrappingDataSourceSurface(
+          shmem.get<uint8_t>(), stride, rgb.size(), rgb.format());
     } else if (SDIsNullRemoteDecoder(sd)) {
       const auto& sdrd = sd.get_SurfaceDescriptorGPUVideo()
                              .get_SurfaceDescriptorRemoteDecoder();
@@ -1166,12 +1177,10 @@ bool TexUnpackSurface::TexOrSubImage(bool isSubImage, bool needsRespec,
   // -
 
   const auto dstFormat = FormatForPackingInfo(dstPI);
-  const auto dstBpp = BytesPerPixel(dstPI);
+  const size_t dstBpp = BytesPerPixel(dstPI);
   const size_t dstUsedBytesPerRow = dstBpp * surf->GetSize().width;
-  auto dstStride = dstUsedBytesPerRow;
-  if (dstFormat == srcFormat) {
-    dstStride = srcStride;  // Try to match.
-  }
+  size_t dstStride = dstFormat == srcFormat ? srcStride  // Try To match
+                                            : dstUsedBytesPerRow;
 
   // -
 
Loading diff…