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: Canvas2D component
ComponentDOM
Bug ClassInteger Overflow
Tracker1987246
Fix commitd94dd896837c (firefox) +38/-18
CISA KEVNot listed
CreditedOskar L
Disclosed2025-09-30

Changed Functions

FunctionChangeNotes
if
dom/canvas/FilterNodeWebgl.cpp
modified

Files Changed

  • dom/canvas/FilterNodeWebgl.cpp
  • dom/canvas/FilterNodeWebgl.h
diff --git a/dom/canvas/FilterNodeWebgl.cpp b/dom/canvas/FilterNodeWebgl.cpp
index 67c569b07f0..b0fc39a22a3 100644
--- a/dom/canvas/FilterNodeWebgl.cpp
+++ b/dom/canvas/FilterNodeWebgl.cpp
@@ -6,6 +6,8 @@
 
 #include "FilterNodeWebgl.h"
 
+#include <limits>
+
 #include "DrawTargetWebglInternal.h"
 #include "SourceSurfaceWebgl.h"
 #include "mozilla/gfx/Blur.h"
@@ -42,32 +44,45 @@ already_AddRefed<FilterNodeWebgl> FilterNodeWebgl::Create(FilterType aType) {
   return filter.forget();
 }
 
-void FilterNodeWebgl::ReserveInputIndex(uint32_t aIndex) {
-  if (mInputSurfaces.size() <= aIndex) {
-    mInputSurfaces.resize(aIndex + 1);
+bool FilterNodeWebgl::ReserveInputIndex(uint32_t aIndex) {
+  size_t inputIndex = aIndex;
+  if (std::numeric_limits<size_t>::max() - inputIndex < 1) {
+    return false;
+  }
+  if (mInputSurfaces.size() <= inputIndex) {
+    mInputSurfaces.resize(inputIndex + 1);
   }
-  if (mInputFilters.size() <= aIndex) {
-    mInputFilters.resize(aIndex + 1);
+  if (mInputFilters.size() <= inputIndex) {
+    mInputFilters.resize(inputIndex + 1);
   }
+  return true;
 }
 
-void FilterNodeWebgl::SetInputAccel(uint32_t aIndex, SourceSurface* aSurface) {
-  ReserveInputIndex(aIndex);
-  mInputSurfaces[aIndex] = aSurface;
-  mInputFilters[aIndex] = nullptr;
+bool FilterNodeWebgl::SetInputAccel(uint32_t aIndex, SourceSurface* aSurface) {
+  if (ReserveInputIndex(aIndex)) {
+    mInputSurfaces[aIndex] = aSurface;
+    mInputFilters[aIndex] = nullptr;
+    return true;
+  }
+  return false;
 }
 
-void FilterNodeWebgl::SetInputSoftware(uint32_t aIndex,
+bool FilterNodeWebgl::SetInputSoftware(uint32_t aIndex,
                                        SourceSurface* aSurface) {
   if (mSoftwareFilter) {
     mSoftwareFilter->SetInput(aIndex, aSurface);
   }
   mInputMask |= (1 << aIndex);
+  return true;
 }
 
 void FilterNodeWebgl::SetInput(uint32_t aIndex, SourceSurface* aSurface) {
-  SetInputAccel(aIndex, aSurface);
-  SetInputSoftware(aIndex, aSurface);
+  int32_t inputIndex = InputIndex(aIndex);
+  if (inputIndex < 0 || !SetInputAccel(inputIndex, aSurface) ||
+      !SetInputSoftware(inputIndex, aSurface)) {
+    gfxDevCrash(LogReason::FilterInputSet) << "Invalid set " << inputIndex;
+    return;
+  }
 }
 
 void FilterNodeWebgl::SetInput(uint32_t aIndex, FilterNode* aFilter) {
@@ -76,10 +91,15 @@ void FilterNodeWebgl::SetInput(uint32_t aIndex, FilterNode* aFilter) {
     return;
   }
 
-  ReserveInputIndex(aIndex);
+  int32_t inputIndex = InputIndex(aIndex);
+  if (inputIndex < 0 || !ReserveInputIndex(inputIndex)) {
+    gfxDevCrash(LogReason::FilterInputSet) << "Invalid set " << inputIndex;
+    return;
+  }
+
   auto* webglFilter = static_cast<FilterNodeWebgl*>(aFilter);
-  mInputFilters[aIndex] = webglFilter;
-  mInputSurfaces[aIndex] = nullptr;
+  mInputFilters[inputIndex] = webglFilter;
+  mInputSurfaces[inputIndex] = nullptr;
   if (mSoftwareFilter) {
     MOZ_ASSERT(!webglFilter || webglFilter->mSoftwareFilter);
     mSoftwareFilter->SetInput(
diff --git a/dom/canvas/FilterNodeWebgl.h b/dom/canvas/FilterNodeWebgl.h
index 3eb23283cdd..d6885a51ccb 100644
--- a/dom/canvas/FilterNodeWebgl.h
+++ b/dom/canvas/FilterNodeWebgl.h
@@ -28,9 +28,9 @@ class FilterNodeWebgl : public FilterNode {
 
   FilterBackend GetBackendType() override { return FILTER_BACKEND_WEBGL; }
 
-  void ReserveInputIndex(uint32_t aIndex);
-  void SetInputAccel(uint32_t aIndex, SourceSurface* aSurface);
-  void SetInputSoftware(uint32_t aIndex, SourceSurface* aSurface);
+  bool ReserveInputIndex(uint32_t aIndex);
+  bool SetInputAccel(uint32_t aIndex, SourceSurface* aSurface);
+  bool SetInputSoftware(uint32_t aIndex, SourceSurface* aSurface);
   void SetInput(uint32_t aIndex, SourceSurface* aSurface) override;
   void SetInput(uint32_t aIndex, FilterNode* aFilter) override;
   void SetAttribute(uint32_t aIndex, bool) override;
Loading diff…