Medium firefox Logic Error 🔧 Commit mapped

Overview

Medium
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
Impactmoderate
DescriptionMemory safety bug fixed in Firefox 152
ComponentGraphics
Bug ClassLogic Error
Tracker2037290
Fix commitc9f0db7ce573 (firefox) +100/-5
CISA KEVNot listed
CreditedZijie Zhao
Disclosed2026-06-16

Changed Functions

FunctionChangeNotes
if
gfx/cairo/cairo/src/cairo-cff-subset.c
modified
if
gfx/cairo/patches/0033-Bug-2037290-cff-subset-offset-checks.patch
modified

Files Changed

  • gfx/cairo/cairo/src/cairo-cff-subset.c
  • gfx/cairo/patches/0033-Bug-2037290-cff-subset-offset-checks.patch
diff --git a/gfx/cairo/cairo/src/cairo-cff-subset.c b/gfx/cairo/cairo/src/cairo-cff-subset.c
index 6c01ed4ef87..6e3a4340c4e 100644
--- a/gfx/cairo/cairo/src/cairo-cff-subset.c
+++ b/gfx/cairo/cairo/src/cairo-cff-subset.c
@@ -1086,6 +1086,10 @@ cairo_cff_font_read_cid_fontdict (cairo_cff_font_t *font, unsigned char *ptr)
         }
         operand = decode_integer (operand, &size);
         decode_integer (operand, &offset);
+        if (unlikely (offset < 0 || (unsigned long)offset > font->data_length)) {
+            status = CAIRO_INT_STATUS_UNSUPPORTED;
+            goto fail;
+        }
         status = cff_dict_init (&font->fd_private_dict[i]);
 	if (unlikely (status))
             goto fail;
@@ -1205,6 +1209,8 @@ cairo_cff_font_read_top_dict (cairo_cff_font_t *font)
     operand = cff_dict_get_operands (font->top_dict, CHARSTRINGS_OP, &size);
     decode_integer (operand, &offset);
     p = font->data + offset;
+    if (unlikely (p < font->data || p > font->data_end))
+        return CAIRO_INT_STATUS_UNSUPPORTED;
     status = cff_index_read (&font->charstrings_index, &p, font->data_end);
     if (unlikely (status))
         goto fail;
@@ -1217,7 +1223,7 @@ cairo_cff_font_read_top_dict (cairo_cff_font_t *font)
 
 	 decode_integer (operand, &offset);
 	 font->charset = font->data + offset;
-	 if (font->charset >= font->data_end)
+	 if (unlikely (font->charset < font->data || font->charset >= font->data_end))
 	      return CAIRO_INT_STATUS_UNSUPPORTED;
     }
 
@@ -1227,27 +1233,36 @@ cairo_cff_font_read_top_dict (cairo_cff_font_t *font)
     if (font->is_cid) {
         operand = cff_dict_get_operands (font->top_dict, FDSELECT_OP, &size);
         decode_integer (operand, &offset);
-        status = cairo_cff_font_read_fdselect (font, font->data + offset);
+        p = font->data + offset;
+        if (unlikely (p < font->data || p > font->data_end))
+            return CAIRO_INT_STATUS_UNSUPPORTED;
+        status = cairo_cff_font_read_fdselect (font, p);
 	if (unlikely (status))
 	    goto fail;
 
         operand = cff_dict_get_operands (font->top_dict, FDARRAY_OP, &size);
         decode_integer (operand, &offset);
-        status = cairo_cff_font_read_cid_fontdict (font, font->data + offset);
+        p = font->data + offset;
+        if (unlikely (p < font->data || p > font->data_end))
+            return CAIRO_INT_STATUS_UNSUPPORTED;
+        status = cairo_cff_font_read_cid_fontdict (font, p);
 	if (unlikely (status))
 	    goto fail;
     } else {
         operand = cff_dict_get_operands (font->top_dict, PRIVATE_OP, &size);
         operand = decode_integer (operand, &size);
         decode_integer (operand, &offset);
-	status = cairo_cff_font_read_private_dict (font,
+        p = font->data + offset;
+        if (unlikely (p < font->data || p > font->data_end))
+            return CAIRO_INT_STATUS_UNSUPPORTED;
+        status = cairo_cff_font_read_private_dict (font,
                                                    font->private_dict,
 						   &font->local_sub_index,
 						   &font->local_sub_bias,
 						   &font->local_subs_used,
                                                    &font->default_width,
                                                    &font->nominal_width,
-						   font->data + offset,
+						   p,
 						   size);
 	if (unlikely (status))
 	    goto fail;
diff --git a/gfx/cairo/patches/0033-Bug-2037290-cff-subset-offset-checks.patch b/gfx/cairo/patches/0033-Bug-2037290-cff-subset-offset-checks.patch
new file mode 100644
index 00000000000..b8ac128f086
--- /dev/null
+++ b/gfx/cairo/patches/0033-Bug-2037290-cff-subset-offset-checks.patch
@@ -0,0 +1,80 @@
+commit 10d78e49f5d39fe5ef4925a271e721bb7eef22d3
+Author: Jonathan Kew <[email protected]>
+Date:   Wed May 6 13:21:19 2026 +0100
+
+    Bug 2037290 - Check more offsets during cairo CFF subsetting.
+
+diff --git a/gfx/cairo/cairo/src/cairo-cff-subset.c b/gfx/cairo/cairo/src/cairo-cff-subset.c
+index 6c01ed4ef876..6e3a4340c4ec 100644
+--- a/gfx/cairo/cairo/src/cairo-cff-subset.c
++++ b/gfx/cairo/cairo/src/cairo-cff-subset.c
+@@ -1086,6 +1086,10 @@ cairo_cff_font_read_cid_fontdict (cairo_cff_font_t *font, unsigned char *ptr)
+         }
+         operand = decode_integer (operand, &size);
+         decode_integer (operand, &offset);
++        if (unlikely (offset < 0 || (unsigned long)offset > font->data_length)) {
++            status = CAIRO_INT_STATUS_UNSUPPORTED;
++            goto fail;
++        }
+         status = cff_dict_init (&font->fd_private_dict[i]);
+ 	if (unlikely (status))
+             goto fail;
+@@ -1205,6 +1209,8 @@ cairo_cff_font_read_top_dict (cairo_cff_font_t *font)
+     operand = cff_dict_get_operands (font->top_dict, CHARSTRINGS_OP, &size);
+     decode_integer (operand, &offset);
+     p = font->data + offset;
++    if (unlikely (p < font->data || p > font->data_end))
++        return CAIRO_INT_STATUS_UNSUPPORTED;
+     status = cff_index_read (&font->charstrings_index, &p, font->data_end);
+     if (unlikely (status))
+         goto fail;
+@@ -1217,7 +1223,7 @@ cairo_cff_font_read_top_dict (cairo_cff_font_t *font)
+ 
+ 	 decode_integer (operand, &offset);
+ 	 font->charset = font->data + offset;
+-	 if (font->charset >= font->data_end)
++	 if (unlikely (font->charset < font->data || font->charset >= font->data_end))
+ 	      return CAIRO_INT_STATUS_UNSUPPORTED;
+     }
+ 
+@@ -1227,27 +1233,36 @@ cairo_cff_font_read_top_dict (cairo_cff_font_t *font)
+     if (font->is_cid) {
+         operand = cff_dict_get_operands (font->top_dict, FDSELECT_OP, &size);
+         decode_integer (operand, &offset);
+-        status = cairo_cff_font_read_fdselect (font, font->data + offset);
++        p = font->data + offset;
++        if (unlikely (p < font->data || p > font->data_end))
++            return CAIRO_INT_STATUS_UNSUPPORTED;
++        status = cairo_cff_font_read_fdselect (font, p);
+ 	if (unlikely (status))
+ 	    goto fail;
+ 
+         operand = cff_dict_get_operands (font->top_dict, FDARRAY_OP, &size);
+         decode_integer (operand, &offset);
+-        status = cairo_cff_font_read_cid_fontdict (font, font->data + offset);
++        p = font->data + offset;
++        if (unlikely (p < font->data || p > font->data_end))
++            return CAIRO_INT_STATUS_UNSUPPORTED;
++        status = cairo_cff_font_read_cid_fontdict (font, p);
+ 	if (unlikely (status))
+ 	    goto fail;
+     } else {
+         operand = cff_dict_get_operands (font->top_dict, PRIVATE_OP, &size);
+         operand = decode_integer (operand, &size);
+         decode_integer (operand, &offset);
+-	status = cairo_cff_font_read_private_dict (font,
++        p = font->data + offset;
++        if (unlikely (p < font->data || p > font->data_end))
++            return CAIRO_INT_STATUS_UNSUPPORTED;
++        status = cairo_cff_font_read_private_dict (font,
+                                                    font->private_dict,
+ 						   &font->local_sub_index,
+ 						   &font->local_sub_bias,
+ 						   &font->local_subs_used,
+                                                    &font->default_width,
+                                                    &font->nominal_width,
+-						   font->data + offset,
++						   p,
+ 						   size);
+ 	if (unlikely (status))
+ 	    goto fail;
Loading diff…