Firefox · Graphics
CVE-2026-12305
Logic Error in Graphics
Overview
Medium
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Changed Functions
| Function | Change | Notes |
|---|---|---|
ifgfx/cairo/cairo/src/cairo-cff-subset.c |
modified | |
ifgfx/cairo/patches/0033-Bug-2037290-cff-subset-offset-checks.patch |
modified |
Files Changed
gfx/cairo/cairo/src/cairo-cff-subset.cgfx/cairo/patches/0033-Bug-2037290-cff-subset-offset-checks.patch
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 <jkew@mozilla.com>
+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…
References
On This Page