# CVE-2020-0938: Windows Font Driver Type 1 BlendDesignPositions stack corruption

Unbounded num_master loop in Windows font driver's SetBlendDesignPositions writes past a 16-entry stack array, enabling kernel stack corruption and ROP.

- Payout: Real-world hack
- Severity: high
- Program: Microsoft Windows
- Credited: Mateusz Jurczyk, Project Zero (Originally posted on [Project Zero blog](https://googleprojectzero.blogspot.com/p/rca.html) 2021-01-12)
- Disclosed: 2020-03-23
- CVE: CVE-2020-0938
- Write-up quality: 8/10
- Original: https://github.com/googleprojectzero/0days-in-the-wild/blob/main/0day-RCAs/2020/CVE-2020-0938.md
- Library page: https://bugbountylibrary.com/r/p0%3ACVE-2020-0938
- Tags: domain:desktop impact:privesc impact:rce kind:incident platform:project-zero sev:high tech:windows technique:fuzzing technique:regression technique:source-review vuln:dos vuln:memory-corruption

**Target:** Type 1 PostScript font parser (atmfd.dll / fontdrvhost.exe)
**Root cause:** The first for() loop increments num_master with no upper bound while writing into Fixed16_16 values[16][15], so crafted BlendDesignPositions arrays write out-of-bounds on the stack.
**Steps:**
1. Craft a Type 1 font containing a BlendDesignPositions object with more than 16 bracketed arrays, e.g. `/BlendDesignPositions [[][][][][][][][][][][][][][][][][][][][][][][0 0 0 0 16705.25490 -0.00001]]`
2. Each GetOpenFixedArray reads 0-15 fixed-point values, allowing selective non-continuous writes at chosen stack offsets
3. Load the font on an unpatched Windows 8.1 x64 host
4. Observe return address overwritten with `0xffffffff41414141` (encoded as `16705.25490 -0.00001`)
**How found:** Author considers semi-smart fuzzing (PostScript generator with object names scraped from atmfd.dll/fontdrvhost.exe, or injecting objects into existing fonts) and manual audit of PostScript object handlers most likely; also notes binary diffing against Adobe CoolType where the bug was already fixed.
**Exploitation:** Chained with CVE-2020-1020 (write-what-where) to place a second-stage payload in RWX kernel memory at a known address, then used this stack corruption to overwrite a return address higher in the call chain and jump to the payload. Not exploited on Windows 10.
**Escalation:** Kernel-mode stack corruption bypassing /GS on the vulnerable function by targeting a return address further up the call chain; combined with a separate write primitive for full kernel RCE.
**Insight:** Textual PostScript objects (Multiple Master extension) in Type 1 fonts were a blind spot while CharString/OpenType parsing got fuzzed; scrape handler names from the font driver binary and inject those objects into valid fonts, and diff Microsoft's fork against Adobe CoolType for missing fixes.
