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: Apple IOHIDFamily Kernel Race Condition
## CVE Details
- **CVE ID:** CVE-2016-1824
- **CVSS Score:** 7.8 (High) - *Based on typical NVD scoring for local privilege escalation via kernel flaws.*
- **CWE:** CWE-362 (Concurrent Execution using Shared Resource with Improper Synchronization - 'Race Condition')
## Affected Systems
- **Products:** Apple iOS, macOS (formerly OS X), watchOS, and tvOS.
- **Versions:**
- macOS (OS X) versions prior to 10.11.5
- iOS versions prior to 9.3.2
- **Configurations:** The vulnerability exists in the `IOHIDFamily` kernel extension, specifically within the `IOHIDEventSystemUserClient` class. Exploitation requires the ability to call `IOConnectCallMethod` on the affected service.
## Vulnerability Description
A race condition exists in the `IOHIDEventSystemUserClient::destroyEventQueue` function. The code performs a `release()` operation on the `kernelQueue` pointer and subsequently sets that pointer to `NULL`. However, these operations are not protected by a locking mechanism (such as a mutex or spinlock).
If a second thread attempts to access or destroy the same `kernelQueue` after the first thread has called `release()` but before it has set the pointer to `NULL`, the second thread will attempt to operate on a freed object. This results in a Use-After-Free (UAF) condition.
## Exploitation
- **Status:** PoC available.
- **Complexity:** High (Requires precise timing to hit the race window between two adjacent lines of code).
- **Attack Vector:** Local (Must be executed from a usermode program with sufficient privileges, often root).
## Impact
- **Confidentiality:** High (Potential to read kernel memory).
- **Integrity:** High (Potential for memory corruption and overwriting of VTable pointers to redirect kernel execution).
- **Availability:** High (Can lead to immediate kernel panic and system crash).
## Remediation
### Patches
Apple released updates on May 16, 2016, to address this flaw by improving locking and state management.
- **macOS:** OS X El Capitan v10.11.5
- **iOS:** iOS 9.3.2
### Workarounds
No practical workarounds exist for this kernel-level flaw other than applying the official security updates. Restricting access to IOKit interfaces can reduce the attack surface.
## Detection
- **Indicators of Compromise:** System logs may show kernel panics with backtraces pointing to `IOHIDFamily` or `IOHIDEventSystemUserClient::destroyEventQueue`.
- **Detection methods and tools:** Monitoring for rapid, repeated calls to `destroyEventQueue` from a single process may indicate a race condition attempt.
## References
- **Vendor Advisory (macOS):** [https://support.apple.com/en-hk/HT206567]
- **Vendor Advisory (iOS):** [https://support.apple.com/en-hk/HT206568]
- **Technical Analysis:** [https://marcograss.github.io/]
- **Related Research (Ian Beer):** [https://bugs.chromium.org/p/project-zero/issues/detail?id=620]