
CVE-2026-64788 PoC — IOGPUFamily उपयोग-के-बाद-मुक्त (iOS 26.6 / 23G71)
घटक: 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 बाइट्स, ज़ोन) आवंटित करता है और इसे डिवाइस की IOSurface संसाधन तालिका में पंजीकृत करता है। लौटने से पहले, के माध्यम से एक आयाम ओवरफ्लो जांच सक्रिय होती है। ओवरफ्लो पथ त्रुटि रिटर्न की ओर शाखा करता है, जिससे संसाधन तालिका में एक सक्रिय प्रविष्टि रह जाती है जो मुक्त मेमोरी की ओर इंगित करती है।
kalloc.256ADDS width+height → b.hscreate_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 को खोजता है, लटकती प्रविष्टि ढूंढता है, और उसे गैर-वर्चुअल रूप से एक्सेस करता है:
| ऑफसेट | संचालन | विवरण |
|---|---|---|
+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 |
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 प्रिमिटिव अवरुद्ध है जब तक ज़ोन पृथक्करण को तोड़ने के लिए कोई द्वितीयक प्रिमिटिव न हो।
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 ने सुरक्षा सलाह में श्रेय प्रकाशित किया |