Full Report
XNU kernel and some IOKIT modules have been plagued by race condition issues. Many of these issues have been discussed, including one from Ian Beer. On the surface, these drivers either lack a locking mechanism altogether or use the wrong locks for the type. Because of this concurrent access of data types makes it easy to cause memory corruption. The code in question callsrelease() on the kernel queue and then sets it to NULL. There is no lock provided on this code though. If another thread can access the kernel queue after it's been released but before it's set to NULL, then bad things can happen. What exactly can happen? In the post by Ian Beer that was previously linked, he was able to overwrite a VTable pointer with this same type of bug. The release() and NULL are very close to each other (literally a line apart). The PoC has a loop that tries to hit this. I'm curious how long this would take? Seems like a tough window to hit. The author has a good takeaway: "Sometimes vendors just fix the immediate problem and bug, and don’t investigate carefully about the root cause and search for additional bugs that share the same pattern." If you see an interesting bug, there may be other variants of the same bug waiting to be discovered.
Analysis Summary
# Vulnerability: XNU/IOKit Kernel Race Condition leading to Memory Corruption
## CVE Details
- CVE ID: CVE-2016-1824 (This CVE is associated with the specific report regarding IOHIDFamily, though the description is a general pattern observed in IOKit).
- CVSS Score: Not explicitly provided in the text, but described as leading to memory corruption, implying High severity. A similar IOKit kernel race condition is typically rated CVSSv3 Base Score of 7.8 (High) or higher if it leads to local privilege escalation.
- CWE: CWE-362 (Race Condition)
## Affected Systems
- Products: XNU kernel, specific IOKIT modules, and notably the `IOHIDFamily`.
- Versions: Preceding versions of OS X 10.11.5 and iOS 9.3.2.
- Configurations: Requires root privileges to trigger the most dangerous exploitation path described.
## Vulnerability Description
The vulnerability lies within a kernel module (specifically `IOHIDSystem/IOHIDUserClient::destroyEventQueue` in IOHIDFamily is discussed) that manages kernel event queues. The flawed code path releases a kernel queue object (`kernelQueue->release();`) followed immediately by setting the pointer to NULL (`kernelQueue = NULL;`).
This operation lacks proper synchronization (locking). If a concurrent execution thread accesses `kernelQueue` after it has been released but *before* it is set to NULL, a Use-After-Free (UAF) condition occurs. This can lead to memory corruption. Based on referenced external work (Ian Beer's finding), exploiting this specific pattern can allow an attacker to overwrite critical function pointers, such as a VTable pointer, potentially leading to arbitrary code execution within the kernel context (Local Privilege Escalation).
## Exploitation
- Status: PoC available (A crash PoC demonstrating the multi-threaded race attempt is provided in the source article). Not explicitly stated as exploited in the wild, but demonstrated achievable with root context.
- Complexity: Medium to High. While the race window is tight (two lines apart), a PoC demonstrates high-frequency looping to hit the condition. Exploiting for reliable LPE, as demonstrated by Beer, requires significant skill.
- Attack Vector: Local (Requires user processes to already have root access to interact with the affected user client method, though many kernel vulnerabilities are exploitable from lower privilege levels).
## Impact
- Confidentiality: High (If exploited for LPE, kernel memory contents can be read).
- Integrity: High (If exploited for LPE via VTable overwrite, kernel code execution can modify system state).
- Availability: High (Successful exploitation, even if only a crash occurs, results in a Kernel Panic/Denial of Service).
## Remediation
### Patches
- OS X 10.11.5
- iOS 9.3.2
### Workarounds
- No specific temporary workarounds were mentioned, as the fix involves ensuring proper synchronization (locking) around the `release()` and assignment sequence.
## Detection
- Indicators of Compromise: Unexplained kernel panics originating from IOKit or related kernel subsystems.
- Detection methods and tools: Analyzing kernel trace logs or memory dumps for evidence of improper memory deallocation sequences or manipulation of kernel object pointers in IOKit dispatch routines.
## References
- Vendor Advisories: Apple Security Updates HT206567 (OS X 10.11.5) and HT206568 (iOS 9.3.2).
- Relevant links - defanged:
- The author's primary blog post: hxxps://marcograss.github.io/
- Linked similar issue by Ian Beer: hxxps://bugs.chromium.org/p/project-zero/issues/detail?id=620
- Link to outdated open source code: hxxp://opensource.apple.com/source/IOHIDFamily/IOHIDFamily-701.20.10/