CVE-2026-8577
Overview
Files Changed
DEPSthird_party/harfbuzz-ng/README.chromiumthird_party/harfbuzz-ng/src
Patch
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
Original Bug Report
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().
- 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 index0to a child at index32768, the distance is0 - 32768 = -32768. Because-32768(INT16_MIN) perfectly fits into the signed 16-bitattach_chain()field, it survives the truncation guard check (pos[child].attach_chain() != (int) parent - (int) child) at line 234. - 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;. Sincechainis-32768,-chainbecomes32768. Assigning32768to theint16_tfield overflows the maximum positive value (32767), wrapping back to-32768. - 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;. Ifi = 0andchain = -32768,jbecomes-32768, which casts to the unsigned integer4294934528. This massive index is then used for recursive reads and writes, such aspos[j].attach_chain() = -chain.
Platform Specific Impact
- 64-bit Platforms: The array element size is 20 bytes.
4294934528 * 20bytes 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 * 0x14wraps to0xFFF60000. Interpreted as a signed 32-bit offset, this is exactly-655360bytes. This creates a highly predictable640 KBheap underflow.
Suggested Attacker Steps
(Note: These are potential steps based on static analysis, as our setup does not run live exploit code.)
- Create a web page embedding a malicious OpenType font and a text string that generates a HarfBuzz buffer of at least 32,769 glyphs.
- 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). - Trigger a Left-to-Right
CursivePosFormat1lookup linking glyph0and glyph32768to plant the-32768chain value. - Trigger a Right-to-Left
CursivePosFormat1lookup to reverse the chain, triggering the negation overflow and corrupting the chain. - Trigger another lookup to traverse the corrupted chain. The engine will perform an OOB read at the groomed
-640 KBoffset, followed by OOB writes (e.g., writing0and negated offsets) to that same location. - Use these OOB write primitives to corrupt adjacent object metadata or vtables, leading to renderer RCE.
Suggested Fix
- Reject INT16_MIN: In
CursivePosFormat1::apply, explicitly reject assignments where the calculated distance is-32768(since its negation cannot be represented in 16 bits). - Bounds Checking: Add an explicit bounds check inside
reverse_cursive_minor_offset()right after computingj = (int) i + chainto verify thatj < buffer->lenbefore performing any recursive calls or array accesses. (Similar to the checks inpropagate_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.