High firefox Integer Overflow 🔧 Commit mapped

Overview

High
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
Impacthigh
DescriptionSandbox escape due to integer overflow in the Graphics component
ComponentGraphics
Bug ClassInteger Overflow
Tracker2005014
Fix commit0a26ec0888ca (firefox) +16/-9
CISA KEVNot listed
CreditedOskar L
Disclosed2026-01-13

Changed Functions

FunctionChangeNotes
for
gfx/2d/DrawTargetCairo.cpp
modified
if
gfx/2d/DrawTargetCairo.cpp
modified

Files Changed

  • gfx/2d/DrawTargetCairo.cpp
diff --git a/gfx/2d/DrawTargetCairo.cpp b/gfx/2d/DrawTargetCairo.cpp
index b44e57c93ea..578684df26b 100644
--- a/gfx/2d/DrawTargetCairo.cpp
+++ b/gfx/2d/DrawTargetCairo.cpp
@@ -216,15 +216,22 @@ static cairo_surface_t* CopyToImageSurface(unsigned char* aData,
   }
 
   unsigned char* surfData = cairo_image_surface_get_data(surf);
-  int surfStride = cairo_image_surface_get_stride(surf);
-  int32_t pixelWidth = BytesPerPixel(aFormat);
+  size_t surfStride = cairo_image_surface_get_stride(surf);
+  size_t pixelWidth = BytesPerPixel(aFormat);
+  size_t rowDataWidth = size_t(aRectWidth) * pixelWidth;
+  if (rowDataWidth > surfStride || rowDataWidth > size_t(aStride)) {
+    cairo_surface_destroy(surf);
+    return nullptr;
+  }
 
-  unsigned char* source = aData + aRect.Y() * aStride + aRect.X() * pixelWidth;
+  const unsigned char* sourceRow = aData + size_t(aRect.Y()) * size_t(aStride) +
+                                   size_t(aRect.X()) * pixelWidth;
+  unsigned char* destRow = surfData;
 
-  MOZ_ASSERT(aStride >= aRectWidth * pixelWidth);
   for (int32_t y = 0; y < aRectHeight; ++y) {
-    memcpy(surfData + y * surfStride, source + y * aStride,
-           aRectWidth * pixelWidth);
+    memcpy(destRow, sourceRow, rowDataWidth);
+    sourceRow += aStride;
+    destRow += surfStride;
   }
   cairo_surface_mark_dirty(surf);
   return surf;
@@ -250,12 +257,12 @@ static cairo_surface_t* GetAsImageSurface(cairo_surface_t* aSurface) {
 static cairo_surface_t* CreateSubImageForData(unsigned char* aData,
                                               const IntRect& aRect, int aStride,
                                               SurfaceFormat aFormat) {
-  if (!aData) {
+  if (!aData || aStride < 0) {
     gfxWarning() << "DrawTargetCairo.CreateSubImageForData null aData";
     return nullptr;
   }
-  unsigned char* data =
-      aData + aRect.Y() * aStride + aRect.X() * BytesPerPixel(aFormat);
+  unsigned char* data = aData + size_t(aRect.Y()) * size_t(aStride) +
+                        size_t(aRect.X()) * size_t(BytesPerPixel(aFormat));
 
   cairo_surface_t* image = cairo_image_surface_create_for_data(
       data, GfxFormatToCairoFormat(aFormat), aRect.Width(), aRect.Height(),
Loading diff…