High firefox Logic Error 🔧 Commit mapped

Overview

High
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Impacthigh
DescriptionUse-after-free in the SVG component
ComponentImageLib
Bug ClassLogic Error
Tracker2080102
Fix commit3a6acbe1080b (firefox) +12/-6
CISA KEVNot listed
CreditedMozilla
Disclosed2026-10-27

Changed Functions

FunctionChangeNotes
if
image/AutoRestoreSVGState.h
modified

Files Changed

  • image/AutoRestoreSVGState.h
  • image/SVGDocumentWrapper.cpp
diff --git a/image/AutoRestoreSVGState.h b/image/AutoRestoreSVGState.h
index c5b4fb851b8..b3b63acd813 100644
--- a/image/AutoRestoreSVGState.h
+++ b/image/AutoRestoreSVGState.h
@@ -32,12 +32,15 @@ class MOZ_STACK_CLASS AutoRestoreSVGState final {
       : mIsDrawing(aSVGDocumentWrapper->mIsDrawing),
         // Apply any 'preserveAspectRatio' override (if specified) to the root
         // element:
-        mPAR(aSVGContext, aSVGDocumentWrapper->GetSVGRootElement()),
-        // Set the animation time:
-        mTime(aSVGDocumentWrapper->GetSVGRootElement(), aAnimationTime) {
+        mPAR(aSVGContext, aSVGDocumentWrapper->GetSVGRootElement()) {
     MOZ_ASSERT(!mIsDrawing.SavedValue());
     MOZ_ASSERT(aSVGDocumentWrapper->GetDocument());
 
+    // Setting the animation time flushes the document, so the re-entrancy
+    // guard has to be in place first.
+    aSVGDocumentWrapper->mIsDrawing = true;
+    mTime.emplace(aSVGDocumentWrapper->GetSVGRootElement(), aAnimationTime);
+
     if (auto* pc = aSVGDocumentWrapper->GetDocument()->GetPresContext()) {
       pc->SetLinkParametersOverride(aSVGContext.GetLinkParameters());
 
@@ -51,8 +54,6 @@ class MOZ_STACK_CLASS AutoRestoreSVGState final {
       }());
     }
 
-    aSVGDocumentWrapper->mIsDrawing = true;
-
     // Set context paint (if specified) on the document:
     if (aContextPaint) {
       MOZ_ASSERT(aSVGContext.GetContextPaint());
@@ -64,7 +65,7 @@ class MOZ_STACK_CLASS AutoRestoreSVGState final {
  private:
   AutoRestore<bool> mIsDrawing;
   AutoPreserveAspectRatioOverride mPAR;
-  AutoSVGTimeSetRestore mTime;
+  Maybe<AutoSVGTimeSetRestore> mTime;
   Maybe<AutoSetRestoreSVGContextPaint> mContextPaint;
 };
 
diff --git a/image/SVGDocumentWrapper.cpp b/image/SVGDocumentWrapper.cpp
index d034272488c..8fcb9ffe08d 100644
--- a/image/SVGDocumentWrapper.cpp
+++ b/image/SVGDocumentWrapper.cpp
@@ -4,6 +4,7 @@
 
 #include "SVGDocumentWrapper.h"
 
+#include "mozilla/AutoRestore.h"
 #include "mozilla/Components.h"
 #include "mozilla/PresShell.h"
 #include "mozilla/SMILAnimationController.h"
@@ -197,6 +198,10 @@ void SVGDocumentWrapper::SetCurrentTime(float aTime) {
 }
 
 void SVGDocumentWrapper::TickRefreshDriver() {
+  // The tick flushes our document, so nested draws of it must be refused.
+  AutoRestore<bool> isDrawing(mIsDrawing);
+  mIsDrawing = true;
+
   if (RefPtr<PresShell> presShell = mViewer->GetPresShell()) {
     if (RefPtr<nsPresContext> presContext = presShell->GetPresContext()) {
       if (RefPtr<nsRefreshDriver> driver = presContext->RefreshDriver()) {
Loading diff…