Medium chrome Integer Overflow 📄 Reporter bug report 🔧 Commit mapped

Overview

Medium
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactInteger overflow in Fonts
DescriptionInteger overflow in Fonts
ComponentFonts
Bug ClassInteger Overflow
Tracker496302307
Fix commit4fc96139259e (harfbuzz) +5/-5
CISA KEVNot listed
CreditedGoogle
Disclosed2026-05-12

Files Changed

  • DEPS
  • third_party/harfbuzz-ng/README.chromium
  • third_party/harfbuzz-ng/src
From 8047bc4000b040350d0532e0e99e1c13f550e0a3 Mon Sep 17 00:00:00 2001
From: Dominik Röttsches <[email protected]>
Date: Fri, 27 Mar 2026 03:56:56 -0700
Subject: [PATCH] Roll src/third_party/harfbuzz-ng/src/ 6f4c5cec3..4fc961392 (27 commits)

Contains improvements for security issue reported in crbug.com/496302307.

https://chromium.googlesource.com/external/github.com/harfbuzz/harfbuzz.git/+log/6f4c5cec306d..4fc96139259e

$ git log 6f4c5cec3..4fc961392 --date=short --no-merges --format='%ad %ae %s'
2026-03-26 behdad [AGENTS.md] Allow Co-Authored-By
2026-03-26 behdad [vector] Use clear() instead of resize(0)/shrink(0) (#5876)
2026-03-26 behdad [raster] Guard direct SVG paint callbacks
2026-03-26 behdad [vector] Destruct items in clear() when vector is in error state
2026-03-26 behdad [gpos] Guard cursive attachment reversal
2026-03-26 behdad [raster] Increase max image buffer size
2026-03-25 behdad Remove two redundant conditionals
2026-03-24 behdad [glyf] Reject simple glyphs with too few points
2026-03-24 behdad [font] Fix typo in setting design coords (#5871)
2026-03-24 behdad [font] Avoid div-by-zero in parent scale
2026-03-24 behdad [font] Avoid creating a cycle in set_parent()
2026-03-24 behdad [zlib] Remove unused macro
2026-03-24 behdad Ignore -Warray-bounds
2026-03-23 behdad [vector] Fix clear() when vector is in error state
2026-03-23 behdad [raster] Use png_jmpbuf in PNG error callback (#5868)
2026-03-23 49699333+dependabot[bot] Bump hendrikmuhs/ccache-action from 1.2.20 to 1.2.21
2026-03-23 49699333+dependabot[bot] Bump github/codeql-action from 4.33.0 to 4.34.1
2026-03-22 behdad [buffer] Bounds-check in add_utf() (#5864)
2026-03-21 62257866+dejanyy [ot-font] Skip adjusting offsets when all origin values are zero (#5863)
2026-03-21 62257866+dejanyy Fix for issue #5847 (#5862)
2026-03-20 behdad Add a fuzzer test
2026-03-19 behdad Revert "[rust] Use design coords if available, to set on the Rust side"
2026-03-19 behdad [rust] Use design coords if available, to set on the Rust side
2026-03-19 behdad [vector] Reject errored SVG paint bodies
2026-03-19 behdad [vector] Fail closed on SVG paint body OOM
2026-03-19 behdad Add a fuzzer font
2026-03-19 behdad [docs] Note failing-malloc in fuzzing guidance

Created with:
  roll-dep src/third_party/harfbuzz-ng/src

[email protected],[email protected],[email protected],[email protected],[email protected]

Fixed: 496302307
Change-Id: Ifb38a46c9e129cf5701559e112032e77839405f7
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7705953
Reviewed-by: Steinar H Gunderson <[email protected]>
Commit-Queue: Dominik Röttsches <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1606081}
---

diff --git a/DEPS b/DEPS
index c140d42..b6a147aa4 100644
--- a/DEPS
+++ b/DEPS
@@ -363,7 +363,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling HarfBuzz
   # and whatever else without interference from each other.
-  'harfbuzz_revision': '6f4c5cec306d31e6822303f5ba248a14293d588e',
+  'harfbuzz_revision': '4fc96139259ebc35f40118e0382ac8037d928e5c',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Emoji Segmenter
   # and whatever else without interference from each other.
diff --git a/third_party/harfbuzz-ng/README.chromium b/third_party/harfbuzz-ng/README.chromium
index b1b4c66..976a591 100644
--- a/third_party/harfbuzz-ng/README.chromium
+++ b/third_party/harfbuzz-ng/README.chromium
@@ -1,10 +1,10 @@
 Name: harfbuzz-ng
 Short Name: harfbuzz-ng
 URL: http://harfbuzz.org
-Version: 13.2.1-0
+Version: 13.2.1-28
 CPEPrefix: cpe:/a:harfbuzz_project:harfbuzz:13.2.1
-Date: 2026-03-19
-Revision: 6f4c5cec306d31e6822303f5ba248a14293d588e
+Date: 2026-03-27
+Revision: 4fc96139259ebc35f40118e0382ac8037d928e5c
 Update Mechanism: Manual
 Security Critical: yes
 Shipped: yes
diff --git a/third_party/harfbuzz-ng/src b/third_party/harfbuzz-ng/src
index 6f4c5ce..4fc9613 160000
--- a/third_party/harfbuzz-ng/src
+++ b/third_party/harfbuzz-ng/src
@@ -1 +1 @@
-Subproject commit 6f4c5cec306d31e6822303f5ba248a14293d588e
+Subproject commit 4fc96139259ebc35f40118e0382ac8037d928e5c
Loading diff…

Original Bug Report

reported by [email protected]

Potential negation overflow in HarfBuzz reverse_cursive_minor_offset leading to OOB access

Project Fortify, an experimental security project, has identified the following potential security issue.

Overview: A negation overflow in HarfBuzz’s cursive attachment logic occurs when an attachment chain distance is exactly INT16_MIN (-32768). This bypasses truncation checks and leads to a massive out-of-bounds array access when the chain is reversed. On 32-bit platforms, this wraps to a predictable negative offset, potentially allowing reliable heap underflow writes and renderer RCE.

Affected files:

  • third_party/harfbuzz-ng/src/src/OT/Layout/GPOS/CursivePosFormat1.hh

Estimated timestamp from git blame: 2025-11-03

Summary

A potential vulnerability exists in HarfBuzz’s OpenType Layout engine (third_party/harfbuzz-ng/src/src/OT/Layout/GPOS/CursivePosFormat1.hh). A negation overflow can corrupt a glyph’s attachment chain, leading to out-of-bounds (OOB) memory accesses.

Because HarfBuzz processes untrusted web fonts inside the renderer process, and the affected array (hb_glyph_position_t *pos) is a raw C-style pointer unprotected by MiraclePtr (BackupRefPtr), this bug can be weaponized. On 64-bit systems, it causes a deterministic crash (Denial of Service). On 32-bit systems (like Chrome on 32-bit Android), integer wrapping turns this into a reliable heap underflow write, providing a strong primitive for Remote Code Execution (RCE).

Root Cause Analysis

The vulnerability stems from the handling of the 16-bit signed integer attach_chain().

  1. The Bypass: In CursivePosFormat1::apply, the distance between a parent and child glyph is calculated and stored. If a Left-to-Right layout attaches a parent at index 0 to a child at index 32768, the distance is 0 - 32768 = -32768. Because -32768 (INT16_MIN) perfectly fits into the signed 16-bit attach_chain() field, it survives the truncation guard check (pos[child].attach_chain() != (int) parent - (int) child) at line 234.
  2. The Negation Overflow: When a subsequent Right-to-Left lookup forces HarfBuzz to reverse the attachment tree, it calls reverse_cursive_minor_offset(). At line 75, it attempts to invert the chain direction: pos[j].attach_chain() = -chain;. Since chain is -32768, -chain becomes 32768. Assigning 32768 to the int16_t field overflows the maximum positive value (32767), wrapping back to -32768.
  3. The OOB Access: The chain is now corrupted. When the engine traverses this chain again, it calculates the next index at line 62: unsigned int j = (int) i + chain;. If i = 0 and chain = -32768, j becomes -32768, which casts to the unsigned integer 4294934528. This massive index is then used for recursive reads and writes, such as pos[j].attach_chain() = -chain.

Platform Specific Impact

  • 64-bit Platforms: The array element size is 20 bytes. 4294934528 * 20 bytes results in an offset of approximately 85.8 GB. Accessing this address deterministically hits unmapped memory, crashing the renderer (DoS).
  • 32-bit Platforms: The pointer arithmetic (4294934528 * 20) is constrained to 32 bits. Mathematically, 0xFFFF8000 * 0x14 wraps to 0xFFF60000. Interpreted as a signed 32-bit offset, this is exactly -655360 bytes. This creates a highly predictable 640 KB heap underflow.

Suggested Attacker Steps

(Note: These are potential steps based on static analysis, as our setup does not run live exploit code.)

  1. Create a web page embedding a malicious OpenType font and a text string that generates a HarfBuzz buffer of at least 32,769 glyphs.
  2. Groom the 32-bit renderer heap such that attacker-controlled data is placed exactly 640 KB before the target HarfBuzz buffer allocation. Ensure this memory contains specific bytes to pass the early-return check (type & ATTACH_TYPE_CURSIVE).
  3. Trigger a Left-to-Right CursivePosFormat1 lookup linking glyph 0 and glyph 32768 to plant the -32768 chain value.
  4. Trigger a Right-to-Left CursivePosFormat1 lookup to reverse the chain, triggering the negation overflow and corrupting the chain.
  5. Trigger another lookup to traverse the corrupted chain. The engine will perform an OOB read at the groomed -640 KB offset, followed by OOB writes (e.g., writing 0 and negated offsets) to that same location.
  6. Use these OOB write primitives to corrupt adjacent object metadata or vtables, leading to renderer RCE.

Suggested Fix

  1. Reject INT16_MIN: In CursivePosFormat1::apply, explicitly reject assignments where the calculated distance is -32768 (since its negation cannot be represented in 16 bits).
  2. Bounds Checking: Add an explicit bounds check inside reverse_cursive_minor_offset() right after computing j = (int) i + chain to verify that j < buffer->len before performing any recursive calls or array accesses. (Similar to the checks in propagate_attachment_offsets()).

Evaluated with Chrome root at commit: a3f5fcb392f2902650ca2b71820e7e418787e18b


Results so far have been promising, but there can be wrong deductions. If this proves to be a false positive, please close as WAI; data from false positives will be used to improve accuracy over time. Please feel free to reach out to me if you have concerns or feedback.

View on issue tracker