# CVE-2020-15999: FreeType Heap Buffer Overflow in Load_SBit_Png

FreeType's Load_SBit_Png truncates embedded PNG width/height to 16 bits for buffer allocation but passes full 32-bit values to libpng, causing heap overflow exploited as a Chrome zero-day.

- Payout: Real-world hack
- Severity: high
- Program: Google Chrome/ Freetype
- Credited: Sergei Glazunov, Project Zero (Originally posted on [Project Zero blog](https://googleprojectzero.blogspot.com/p/rca.html) 2021-02-04)
- Disclosed: 2020-10-19
- CVE: CVE-2020-15999
- Write-up quality: 7/10
- Original: https://github.com/googleprojectzero/0days-in-the-wild/blob/main/0day-RCAs/2020/CVE-2020-15999.md
- Library page: https://bugbountylibrary.com/r/p0%3ACVE-2020-15999
- Tags: domain:browser domain:desktop impact:privesc impact:rce kind:incident platform:project-zero sev:high tech:chromium technique:chained technique:source-review vuln:memory-corruption

**Target:** FreeType Load_SBit_Png embedded PNG bitmap handling in Chrome
**Root cause:** Load_SBit_Png truncates image width/height to 16-bit integers when computing the bitmap buffer size, but passes the original 32-bit dimensions to libpng, so dimensions >65535 overflow the allocated buffer.
**Steps:**
1. Craft a font embedding a PNG with width and/or height greater than 65535.
2. Load the font in FreeType so Load_SBit_Png computes buffer size from truncated 16-bit dimensions.
3. libpng writes the full 32-bit-sized bitmap into the undersized buffer, overflowing the heap (ASAN crash PoC attached to PZ issue 2103).
**How found:** Text states it is straightforward to find via manual code review, and possibly discovered through variant analysis of Project Zero issue 168.
**Exploitation:** Used as a renderer exploit in two in-the-wild chains: paired with Windows kernel EoP CVE-2020-17087 and with Chrome heap overflow CVE-2020-16010 on Android; detailed exploit flow still under analysis.
**Escalation:** Chained with a kernel privilege-escalation bug on Windows and a Chrome browser-process heap overflow on Android to achieve full compromise.
**Insight:** Audit size computations at trust boundaries between a library and its dependencies: when one component truncates dimensions for allocation but forwards original values to a downstream parser (FreeType vs libpng), the mismatch yields an overflow.
