
# CVE-2026-64788 개념 증명 iOS 26.6의 IOGPUFamily 커널 확장에서 발생하는 use-after-free 취약점에 대한 개념 증명으로, Metal 텍스처 생성과 힙 스프레이를 통한 익스플로잇을 시연합니다.
구성 요소: IOGPUFamily 커널 확장 (com.apple.iokit.IOGPUFamily)
영향: iOS / iPadOS 26.6 (23G71) 및 이전 버전
수정 버전: iOS / iPadOS 26.6.1 (23G83)
유형: IOGPUDevice::create_resource_iosurface의 사용-후-해제(Use-After-Free)
영향: 커널 메모리 손상; A14(iPhone 12)에서 UAF 역참조 확인됨
발견자: f00l (@PPPF00L), 3ndy1 (@_3ndy1), Minghao Lin (@Y1nkoc), 云散花折, Arjanit Isufi
(Apple 보안 권고 — iOS 26.6.1 기준)
IOGPUDevice::create_resource_iosurface는 IOGPUSysMemory 객체(약 0x100바이트, kalloc.256 영역)를 할당하고 이를 디바이스의 IOSurface 리소스 테이블에 등록합니다. 반환 전에 ADDS width+height → b.hs를 통해 차원 오버플로 검사가 실행됩니다. 오버플로 경로는 객체를 해제하지 않고 오류 반환으로 분기하여, 해제된 메모리를 가리키는 활성 항목이 리소스 테이블에 남게 됩니다.
create_resource_iosurface:
kalloc(0x100) → obj ; IOGPUSysMemory 할당됨
table[new_id] = obj ; 참조와 함께 등록됨
ADDS w_result, w_width, w_height
b.hs error_path ; ← 오버플로: 여기로 점프
error_path:
; 객체가 해제되지 않음, 테이블 항목이 지워지지 않음
return kIOReturnInvalid
오래된 테이블 항목은 동일한 리소스 ID가 재사용되거나 디바이스가 닫힐 때까지 유지됩니다.
IOGPUDevice::set_resource_purgeable(id)는 get_resource_by_id()를 통해 오래된 ID를 조회하고, 매달린(dangling) 항목을 찾아 비가상적으로 접근합니다:
PoC는 Metal의 newTextureWithDescriptor:iosurface:plane:을 조작된 오버플로 차원과 함께 사용하여 UAF를 트리거합니다. UAF 역참조 이전:
kalloc.256 슬롯을 채움[+0x10]=0, [+0x24]=0, [+0x28]=0으로 설정 → Call2와 Call3는 안전하게 건너뜀트리거 감지: 존재하지 않는 리소스에 대한 set_resource_purgeable은 0xe00002c2를 반환합니다. UAF + 스프레이가 슬롯을 회수한 후, 동일한 호출은 0xe0002be(리소스 발견, Call1 실행)를 반환 — 오래된 항목이 스프레이 데이터로 처리되고 있음을 확인합니다.
iOS 26의 영역 격리(zone sequestration)는 해제된 IOGPUSysMemory 객체를 타입-안정 영역 자유 목록에 다시 배치합니다. [obj+0x10](IOMemoryDescriptor)과 [obj+0x18](IOGPUDevice) 모두 외부 보유 카운트를 유지하며 객체가 해제된 후에도 활성 상태로 남습니다. 결과적으로 completeMemory()는 항상 유효한 ivar 데이터에서 실행됩니다 — UAF 역참조는 확인되지만 iOS 26에서는 이 경로만으로는 커널 r/w 프리미티브가 차단되며, 영역 격리를 깨기 위한 2차 프리미티브가 필요합니다.
clang -arch arm64 -framework Metal -framework IOSurface \
-framework IOKit -framework Foundation \
-o poc poc/poc_iogpu_uaf.m
또는 Xcode에서 열고 유효한 서명 팀을 설정한 후 디바이스에서 실행합니다.
| 날짜 | 이벤트 |
|---|---|
| 2026-08-17 | 수정 사항이 포함된 iOS 26.6.1 출시 |
| 2026-08-17 | Apple 보안 권고에 크레딧 게시 |
| 오프셋 | 연산 | 설명 |
|---|
+0x010c | ldaddl w9(-4), w8, [obj+0x24] | [obj+0x24]의 원자적 감소; 이전 값 → w8 |
+0x0128 | cbz w8, skip; ldr x1, [obj+0x28] | 이전 [+0x24] != 0인 경우: [obj+0x28]을 IOGPUMemory::setAllocation의 인자로 로드 |
+0x0134 | ldr x0, [obj+0x10] | [obj+0x10]을 IOCommandGate 인자로 로드; 0이면 cbz → skip |