## https://sploitus.com/exploit?id=KITPLOIT:TOOLS-GITHUB-BYTEV0RTEX-CVE-2026-64788
# CVE-2026-64788 β IOGPUFamily Use-After-Free
**Component:** IOGPUFamily kernel extension (`com.apple.iokit.IOGPUFamily`)
**Affected:** iOS / iPadOS 26.6 (23G71) and earlier
**Fixed in:** iOS / iPadOS 26.6.1 (23G83)
**Type:** Use-After-Free in `IOGPUDevice::create_resource_iosurface`
**Impact:** Kernel memory corruption; UAF dereference confirmed on A14 (iPhone 12)
* * *
## Credits
Discovered by: **f00l (@PPPF00L)** , **3ndy1 (@_3ndy1)** , **Minghao Lin (@Y1nkoc)** , **δΊζ£θ±ζ** , **Arjanit Isufi**
(per Apple Security Advisory β iOS 26.6.1)
* * *
## Root Cause
`IOGPUDevice::create_resource_iosurface` allocates an `IOGPUSysMemory` object (~0x100 bytes, `kalloc.256` zone) and registers it in the device's IOSurface resource table. Before returning, a dimension overflow check fires via `ADDS width+height β b.hs`. The overflow path branches to an error return **without releasing the object** , leaving a live entry in the resource table that points to freed memory.
root@kitploit:~
create_resource_iosurface:
kalloc(0x100) β obj ; IOGPUSysMemory allocated
table[new_id] = obj ; registered with a reference
ADDS w_result, w_width, w_height
b.hs error_path ; β overflow: jumps here
error_path:
; object NOT released, table entry NOT cleared
return kIOReturnInvalid
The stale table entry persists until the same resource ID is reused or the device is closed.
* * *
## UAF Dereference
`IOGPUDevice::set_resource_purgeable(id)` looks up the stale ID via `get_resource_by_id()`, finds the dangling entry, and accesses it non-virtually:
* * *
## PoC Behaviour
The PoC triggers the UAF using Metal's `newTextureWithDescriptor:iosurface:plane:` with crafted overflow dimensions. Before the UAF dereference:
* **300Γ MTLBuffer(0x100, StorageModeShared)** sprayed to fill the freed `kalloc.256` slot
* Spray data sets `[+0x10]=0`, `[+0x24]=0`, `[+0x28]=0` β Call2 and Call3 are safely skipped
* UAF dereference proceeds on attacker-controlled heap memory
**Trigger detection:** `set_resource_purgeable` on a nonexistent resource returns `0xe00002c2`. After the UAF + spray reclaims the slot, the same call returns `0xe0002be` (resource found, Call1 fired) β confirming the stale entry is being processed with our spray data.
* * *
## iOS 26 Exploitation Notes
Zone sequestration in iOS 26 places freed `IOGPUSysMemory` objects back into a type-stable zone free list. Both `[obj+0x10]` (IOMemoryDescriptor) and `[obj+0x18]` (IOGPUDevice) hold external retain counts and remain live after the object is freed. As a result, `completeMemory()` always executes on valid ivar data β the UAF dereference is confirmed but **a kernel r/w primitive via this path alone is blocked on iOS 26** without a secondary primitive to break zone sequestration.
* * *
## Requirements
* iOS 26.6 (23G71) or earlier
* Apple A-series GPU (tested: A14 Bionic, iPhone 12)
* No entitlements required β reachable from any Metal-capable sandboxed app
* * *
## Build
root@kitploit:~
clang -arch arm64 -framework Metal -framework IOSurface \
-framework IOKit -framework Foundation \
-o poc poc/poc_iogpu_uaf.m
Or open in Xcode, set a valid signing team, and run on device.
* * *
## Timeline
Date| Event
---|---
2026-08-17| iOS 26.6.1 released with fix
2026-08-17| Apple credits published in security advisory
* * *
## References
* Apple Security Advisory β iOS 26.6.1
* Full Disclosure post