
CVE-2026-43805 IOKit IODMACommand रेस विश्लेषण और प्रूफ ऑफ कॉन्सेप्ट
Apple IOKit के IODMACommand::PerformOperation_Impl में गायब स्थिति लॉक को
macOS 26.5/26.6 कर्नेल बाइनरी diff के माध्यम से खोजा गया विश्लेषण है। कमजोर बिल्ड में,
PerformOperation तैयारी स्थिति और मेमोरी डिस्क्रिप्टर का उपयोग करते समय
CompleteDMA उसी स्थिति को रिलीज़ कर सकता है। 26.6 पैच उस fDextLock को
PerformOperation_Impl पर भी लागू करता है जिसे दोनों पथ पहले से साझा करते थे।
सत्यापन स्थिति
बाइनरी diff, कॉल लक्ष्य, सार्वजनिक XNU स्रोत मैपिंग और नियतात्मक रेस मॉडल का सत्यापन किया गया है। रिपॉज़िटरी का नेटिव DriverKit ट्रिगर Linux/WSL वातावरण में लिखा गया है और अभी तक Xcode बिल्ड तथा कमजोर/पैच्ड macOS A/B निष्पादन नहीं कर पाया है। इसलिए यह रिपॉज़िटरी वर्तमान में वास्तविक कर्नेल पैनिक या नियंत्रणीय kernel write देखे जाने का दावा नहीं करती।
Apple ने इस समस्या को IOKit की race condition के रूप में वर्गीकृत किया है, और बताया है कि स्थानीय ऐप अप्रत्याशित सिस्टम शटडाउन या कर्नेल मेमोरी राइट का कारण बन सकता है। रिपोर्टर 이재영 हैं। Apple macOS Tahoe 26.6 सुरक्षा सूचना, Apple iOS/iPadOS 26.6 सुरक्षा सूचना
| उत्पाद | पहला संशोधित संस्करण | विश्लेषण में उपयोग किया गया कमजोर/संशोधित युग्म |
|---|---|---|
| iOS / iPadOS | 26.6 | iPhone 11: 26.5.2 (23F84) → 26.6 (23G71) |
| macOS Tahoe | 26.6 | KDK 26.5 (25F71) → KDK 26.6 (25G70) |
| macOS Sequoia | 15.7.8 | सूचना से केवल संशोधित संस्करण की पुष्टि |
| macOS Sonoma | 14.8.8 | सूचना से केवल संशोधित संस्करण की पुष्टि |
| watchOS | 26.6 | सूचना से केवल संशोधित संस्करण की पुष्टि |
Sequoia और Sonoma के संशोधित संस्करण क्रमशः Apple 15.7.8 सूचना और Apple 14.8.8 सूचना, watchOS की जानकारी Apple 26.6 सूचना में देखी जा सकती है।
2026-09-27 को CVE ID और PoC, exploit, GitHub, IOKit, रिपोर्टर के नाम को मिलाकर
खोजा गया, लेकिन कोई सार्वजनिक पुनरुत्पादन कोड या कारण विश्लेषण नहीं मिला। यह वाक्य खोज के
समय का अवलोकन है और इसका अर्थ यह नहीं है कि सार्वजनिक PoC कभी अस्तित्व में नहीं होगा।
संशोधित संस्करण के अनुरूप XNU स्रोत सार्वजनिक नहीं होने के कारण स्रोत कमिट diff के बजाय
KDK कर्नेल की तुलना की गई। कमजोर पक्ष Apple द्वारा सार्वजनिक किए गए
xnu-12377.121.6 से
ठीक मेल खाता है, लेकिन विश्लेषण तिथि तक संशोधित पक्ष का xnu-12377.161.13 टैग उपलब्ध नहीं था।
KDK Apple द्वारा प्रदान किए जाने वाले कर्नेल सिंबल·डीबग आर्टिफैक्ट हैं और Apple भी संस्करण
के अनुरूप KDK का उपयोग करने की सलाह देता है। Apple KDK गाइड
तुलना में उपयोग की गई फ़ाइलें रिपॉज़िटरी में शामिल नहीं हैं।
| श्रेणी | फ़ाइल | SHA-256 |
|---|---|---|
| कमजोर KDK DMG | Kernel_Debug_Kit_26.5_build_25F71.dmg | 90ed319cd1ba6e23d1eefcee89fa1b10743f4cf60b85208ae52aa9f45543c7aa |
| संशोधित KDK DMG | Kernel_Debug_Kit_26.6_build_25G70.dmg | edaa0b3d431b43ba7dda2f0e82314b19d5476ba4089a7d8c1de18c49b3ad168b |
| कमजोर x86_64 कर्नेल | XNU 12377.121.6~2 | f4dcaa7e59ae59f3d945c2332862772596b71e9823cc202983ba4f9d897b5bec |
| संशोधित x86_64 कर्नेल | XNU 12377.161.13~4 | 754db65cb15599183ccebfaa2e4909f673de5d7da42ba4293256cb1184587efd |
| कमजोर iOS kernelcache | XNU 12377.122.8~1 | 7bd856548a2d170a5f8c962e9a5740290e5a4ba9a6ac39c96c927d4dd400d890 |
| संशोधित iOS kernelcache | XNU 12377.162.13~2 | 680fa3925641e2b81541c8455fc6d8d432acad9f059ac44bb48324791049c9d6 |
tools/diff_macho_symbols.py Mach-O सिंबल और निष्पादन
सेक्शन को पढ़ता है, C++ नामों को पुनर्स्थापित करता है, फिर ब्रांच·कॉल लक्ष्य और RIP सापेक्ष
पते को सामान्यीकृत करके प्रति-फ़ंक्शन निर्देशों की तुलना करता है। IOKit नाम वाले 19 परिवर्तित
फ़ंक्शनों में से नैदानिक पंक्ति संख्या परिवर्तनों को छोड़कर
IODMACommand::PerformOperation_Impl का नियंत्रण प्रवाह परिवर्तन सूचना के
"improved state handling" से मेल खाता है।
IODMACommand::PerformOperation_Impl(...)
vulnerable: 0xffffff8000a39080, 512 bytes
fixed: 0xffffff8000a3b860, 544 bytes
normalized similarity: 0.621429
संशोधित कर्नेल में निम्नलिखित कॉल नए जुड़ते हैं।
mov rax, [r14 + 0x70] ; IODMACommand::reserved
mov rdi, [rax + 0xc0] ; IODMACommandInternal::fDextLock
call IOLockLock
; fActive 확인 및 readBytes/writeBytes 작업
mov rax, [r14 + 0x70]
mov rdi, [rax + 0xc0]
call IOLockUnlock
कमजोर सार्वजनिक स्रोत को देखें तो
PrepareForDMA_Impl और
CompleteDMA_Impl
पहले से ही fDextLock लेते हैं। दूसरी ओर
PerformOperation_Impl
fActive की जाँच करने के बाद उसी लॉक के बिना fMemory, readBytes, writeBytes का उपयोग करता है।
sequenceDiagram
participant A as Worker A: PerformOperation
participant C as IODMACommand state
participant B as Worker B: CompleteDMA
A->>C: fActive == true 확인
A->>A: 임시 버퍼 할당/준비
B->>C: fDextLock 획득
B->>C: complete(), fActive 감소
B->>C: clearMemoryDescriptor(), fMemory 해제
B-->>C: fDextLock 해제
A->>C: readBytes/writeBytes에서 fMemory 사용
Note over A,C: 상태 검사와 사용 사이 TOCTOU
PerformOperation_Impl की जाँच और उपयोग के बीच यदि CompleteDMA_Impl निष्पादित हो जाए
तो शुरू में जाँची गई तैयारी स्थिति अब मान्य नहीं रहती। fMemory
OSSharedPtr<IOMemoryDescriptor> है, लेकिन यह पथ पूरे ऑपरेशन की सुरक्षा के लिए अलग
संदर्भ या लॉक प्राप्त नहीं करता। परिणामस्वरूप रिलीज़ या प्रतिस्थापित DMA मेमोरी स्थिति का
उपयोग जारी रह सकता है।
पैच के बाद तीनों DMA RPC समान लॉक से स्थिति संक्रमणों को क्रमबद्ध करते हैं।
flowchart LR
P[PrepareForDMA] -->|fDextLock| S[(fActive / fMemory)]
O[PerformOperation] -->|fDextLock 추가| S
C[CompleteDMA] -->|fDextLock| S
Apple सूचना संभावित प्रभाव के रूप में kernel-memory write निर्दिष्ट करती है, लेकिन केवल बाइनरी diff से स्थिर राइट पता·मान नियंत्रण तक प्रमाणित नहीं होता। यहाँ जो निश्चित किया जा सकता है वह है जीवनकाल/तैयारी स्थिति रेस और उसे रोकने वाला लॉक जोड़ना।
poc/model/race_model.cpp कर्नेल API को कॉल किए बिना
समस्याग्रस्त इंटरलीविंग को पुनरुत्पादित करता है। कमजोर पथ में स्थिति जाँच के तुरंत बाद
lifecycle थ्रेड को मेमोरी रिलीज़ करने के लिए बाध्य करता है, और संशोधित पथ में जाँचता है कि
समान लॉक रिलीज़ को विलंबित करता है या नहीं।
make model
सत्यापित आउटपुट:
vulnerable path: stale memory access = observed
fixed path: stale memory access = not observed
यह मॉडल पैच सिद्धांत को सत्यापित करने वाला सहायक PoC है और Apple कर्नेल कमजोरी का वास्तविक क्रैश परिणाम नहीं है।
poc/apple-driverkit-sample Apple के आधिकारिक
DriverKit user-client नमूने पर
आधारित है। जोड़ा गया selector 6 दो स्वतंत्र DriverKit dispatch queue में निम्नलिखित को
दोहराता है।
Worker A: IODMACommand::PerformOperation(Zero, ...)
Worker B: IODMACommand::CompleteDMA()
IODMACommand::PrepareForDMA(...)
PerformOperation(Zero) बड़ा अस्थायी बफ़र तैयार करने के बाद DMA मेमोरी में लिखता है,
इसलिए fActive जाँच और वास्तविक writeBytes के बीच की रेस विंडो को चौड़ा करता है।
डिफ़ॉल्ट 1 MiB, 10,000 बार है और ऐप के SwiftRunDMACommandRace() से समायोजित किया जा
सकता है।