# CVE-2019-7287: iOS Buffer Overflow in ProvInfoIOKitUserClient

Attacker-controlled memmove size in ProvInfoIOKitUserClient::ucEncryptSUInfo causes kernel heap overflow, giving arbitrary kernel read/write and codesigning bypass.

- Payout: Real-world hack
- Severity: high
- Program: Apple iOS
- Credited: Ian Beer, Project Zero (Originally posted on [Project Zero blog](https://googleprojectzero.blogspot.com/p/rca.html) 2020-07-27)
- Disclosed: 2019-02-07
- CVE: CVE-2019-7287
- Write-up quality: 7/10
- Original: https://github.com/googleprojectzero/0days-in-the-wild/blob/main/0day-RCAs/2019/CVE-2019-7287.md
- Library page: https://bugbountylibrary.com/r/p0%3ACVE-2019-7287
- Tags: domain:mobile domain:oss impact:privesc impact:rce kind:incident platform:project-zero sev:high tech:ios technique:chained technique:source-review vuln:memory-corruption

**Target:** IOKit user client external method (ProvInfoIOKitUserClient::ucEncryptSUInfo)
**Root cause:** The size argument to memmove is read from attacker-controlled struct_in[0x7d4] and never validated, so a large value overflows the kernel heap buffer at struct_out.
**Steps:**
1. Obtain send right to ProvInfoIOKitUserClient mach port (requires CVE-2019-7286 since not reachable from WebContent sandbox).
2. Craft input struct with exact expected input/output sizes.
3. Set 4-byte size field at offset 0x7d4 to a large attacker-chosen value.
4. Invoke external method ucEncryptSUInfo; memmove copies attacker-controlled length from struct_in[4] into struct_out[4], corrupting adjacent kernel heap.
**How found:** Google TAG discovered a cache of in-the-wild iOS exploit chains; CVE-2019-7286 and CVE-2019-7287 were the only remaining 0-days. Root cause identified by auditing IOKit external method entrypoints for attacker-trusted values.
**Exploitation:** TAG's in-the-wild chain used the heap corruption to construct an arbitrary kernel memory read/write primitive, then defeated codesigning and launched an unsigned, unsandboxed userspace implant from /tmp.
**Escalation:** Chained with CVE-2019-7286 to gain the user client send right from the renderer sandbox, then escalated from kernel heap corruption to arbitrary kernel R/W and codesign bypass.
**Insight:** Audit IOKit external method entrypoints for length/size fields taken directly from the input struct and passed to memmove/memcpy; the output buffer size is statically known, so a _chk variant would catch it.
