Sploitus

Exploit for CVE-2026-64788

kitploit Β· 2026-09-03

Exploit Code

MARKDOWN102 lines
## 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