# CVE-2019-7286: iOS use-after-free in cfprefsd

Use-after-free in cfprefsd multi-message XPC handler let a sandboxed WebContent renderer escape the sandbox via XPC heap spray and ROP.

- 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-7286
- Write-up quality: 8/10
- Original: https://github.com/googleprojectzero/0days-in-the-wild/blob/main/0day-RCAs/2019/CVE-2019-7286.md
- Library page: https://bugbountylibrary.com/r/p0%3ACVE-2019-7286
- Tags: domain:desktop domain:mobile impact:privesc impact:rce kind:incident platform:project-zero sev:high tech:ios technique:chained technique:source-review vuln:memory-corruption vuln:privilege-escalation vuln:sandbox-escape

**Target:** com.apple.cfprefsd.daemon XPC service multi-message handler
**Root cause:** Multi-message handler stores raw sub-message pointers in a stack array, but reply_handler blocks overwrite some slots with retained reply pointers; handlers that don't send replies leave raw pointers, and xpc_release drops a reference never obtained, causing UaF.
**Steps:**
1. Send a multi-message XPC request to com.apple.cfprefsd.daemon bundling sub-messages where some handlers invoke the reply_handler block and some do not
2. Mixed stack buffer ends up with retained reply pointers and raw sub-message pointers
3. xpc_release called on each entry drops extra reference on raw pointers -> UaF
4. Heap spray XPC heap with fake Objective-C object with fake selector cache
5. Invoke method on fake object to trigger ROP payload
**How found:** Google TAG discovered a cache of in-the-wild iOS exploit chains; CVE-2019-7286 and CVE-2019-7287 were the remaining 0-days. Author notes manual audit would find it since dual use of stack buffer is a weird primitive; generic XPC fuzzer might find it but needs well-formed XPC objects with right dictionaries.
**Exploitation:** Shellcode in sandboxed WebContent renderer sends crafted multi-message XPC to cfprefsd; XPC heap spray places fake ObjC object with fake selector cache; method invocation triggers ROP; ROP opens IOKit userclient mach port and sends it back to renderer to exploit kernel bug CVE-2019-7287.
**Escalation:** Chained sandbox escape (CVE-2019-7286) with kernel UaF (CVE-2019-7287) for full chain from renderer to kernel.
**Insight:** Audit XPC multi-message handlers for stack buffers holding raw pointers that get conditionally replaced with retained pointers; handlers that skip reply_handler leave raw pointers that xpc_release then over-releases.
