crazymind90/CVE-2026-XNU-AIO-KEVENT-UAF

GitHub: crazymind90/CVE-2026-XNU-AIO-KEVENT-UAF

iOS 26.2 XNU 内核 AIO kevent 释放后使用漏洞 PoC,演示从沙箱内无权限触发内核双重释放的利用技术。

Stars: 1 | Forks: 2

# XNU AIO Kevent 释放后使用 (Use-After-Free) (CVE-2026-XXXX) **应用沙箱内触发内核恐慌。无需权限。无需用户交互。** | | | |---|---| | **受影响版本** | iOS 26.2 及更早版本 (xnu-12377.62.10) | | **已修复版本** | iOS 26.3 (xnu-12377.81.4) | | **文件** | `bsd/kern/kern_aio.c` (修改了 141 行) | | **影响** | 应用沙箱内触发内核恐慌 / 双重释放 (double-free) | | **权限 (Entitlements)** | 无 | | **沙箱** | 是 — 从标准应用上下文触发 | | **测试设备** | iPhone 11 Pro (A13), iOS 26.2 (23C55) | | **成功率** | 采用 CPU 亲和性 LIFO 重用技术时约 70% | ## 漏洞详情 `bsd/kern/kern_aio.c` 中存在三个漏洞: 1. **缺少引用计数** — `filt_aioattach()` 将 AIO 条目指针存储到 knote hook 中,**但未调用** `aio_entry_ref()`。该 knote 持有一个未受保护的悬空指针。 2. **入队后注册** — `lio_listio()` 和 `aio_queue_async_request()` 在调用 `aio_try_enqueue_work_locked()` **之后**才调用 `aio_register_kevent()`。AIO 可能在注册发生之前就已完成并被释放。 3. **缺少引用释放** — `filt_aiodetach()` 未调用 `aio_entry_unref()`,导致引用泄漏。 ### iOS 26.3 中的修复 - 在 `filt_aioattach()` 中添加了 `aio_entry_ref()` - 在 `filt_aiodetach()` 中添加了 `aio_entry_unref()` - 将 `aio_register_kevent()` 移至 `aio_try_enqueue_work_locked()` **之前** - 新增 `AIO_KEVENT_REGISTERED` 标志和 `aio_unregister_kevent()` 清理路径 ## 竞态条件 ``` Thread A (lio_listio) Thread B (racer) Kernel Worker | | | |- enqueue AIO entry | | |- wake worker | | | | |- complete I/O | | |- move to doneq | | |- KNOTE() | | | | |- aio_return() | | |- entry FREED | | | | |- aio_register_kevent() | [UAF: entry freed] | `- knote hook = DANGLING | | | | Thread C (kevent64) | |- filt_aioprocess() | | |- reads errorval/returnval from reclaimed entry | | |- TAILQ_REMOVE (unlinks reclaimed entry) | | |- aio_entry_unref() --> DOUBLE FREE | ``` ## CPU 亲和性 LIFO 重用技术 若不进行重用,`filt_aioprocess()` 会从已释放(已清零)的槽位读取数据,此时 `procp=0`,导致在 `FAR=0x58` 处发生不可控的 NULL 指针解引用 (NULL deref) 恐慌。 修复方案:竞争线程在**同一线程**上执行 `aio_return`(释放)和 `aio_read`(重用)。Per-CPU zone magazine 使用 LIFO(后进先出)顺序 —— 释放后的首次分配会重用完全相同的槽位。线程亲和性提示将竞争线程和主线程置于同一 CPU 上。 这确保了被重用的 AIO 条目会占用已释放的槽位,并包含有效的内核数据(`procp`、`errorval`、`returnval`),从而实现约 70% 的可靠性。 **改进前** (跨 CPU,约 20% 成功率,约 70% 恐慌率): ``` Racer CPU: free(slot) → slot in CPU-A magazine Main CPU: reclaim → allocates from CPU-B magazine → MISSES freed slot kevent64: reads zeroed slot → procp=0 → PANIC ``` **改进后** (同 CPU LIFO,约 70% 成功率): ``` Racer CPU: free(slot) → reclaim → same CPU magazine → LIFO reuses slot kevent64: reads valid reclaimed entry → DOUBLE-FREE (no panic) ``` ## 确认结果 ``` [AIO-UAF] === XNU AIO Kevent UAF (CVE-2026-XXXX) === [AIO-UAF] fd=3 pid=569 uid=501 [AIO-UAF] attempt 0 [AIO-UAF] *** DOUBLE-FREE ACHIEVED *** [AIO-UAF] ident = 0x1020554e0 [AIO-UAF] data = 0x0 [AIO-UAF] udata = 0xaa [AIO-UAF] ext[0] = 0x0 (errorval) [AIO-UAF] ext[1] = 0x1000 (returnval) [AIO-UAF] === uid=501 gid=501 === ``` - 每次均为首次尝试即成功 - 连续 5 次链式双重释放 (double-free) 循环,未发生任何恐慌 - `ext[1]` 可通过 `aio_nbytes` 控制(已确认:0x64, 0x65, 0x66, 0x67, 0x68) - iOS 26.3:干净,无恐慌(修复已确认) ## 利用原语 `filt_aioprocess()` 从被重用的条目中读取数据,并提供: | 字段 | 偏移量 | 泄漏途径 | 原语 | |-------|--------|-----------|-----------| | `errorval` | +0x28 | `kev.ext[0]` | 32 位读取 | | `returnval` | +0x20 | `kev.ext[1]` | 64 位读取 | | `procp` | +0x40 | `aio_proc_lock()` | 任意锁 | | `aio_proc_link` | +0x10 | `TAILQ_REMOVE` | `*(tqe_prev) = tqe_next` | | `refcount` | +0x2C | `aio_entry_unref()` | 双重释放 (Double-free) | ### Zone 详情 ``` Zone: KALLOC_TYPE_DEFINE(aio_workq_zonep, aio_workq_entry, KT_DEFAULT) Size: ~224 bytes Type: Dedicated per-type zone (GEN range on iOS 26.2) On-free: Zeroed (iOS 26.2) Limit: 8 AIO entries per process ``` ## 文件 | 文件 | 描述 | |------|-------------| | `aio_kevent_uaf_poc.c` | 包含 `main()` 的独立 C 语言 PoC。可在 macOS 上构建。包含完整文档。 | | `aio_kevent_uaf.m` | 用于 iOS Xcode 测试框架的 Objective-C 代码。调用 `aio_kevent_uaf_trigger()`。 | | `aio_kevent_uaf_analysis.md` | 包含结构体布局和利用路径的完整技术分析。 | ## 构建 ### macOS (用于测试 — macOS 上同样存在此漏洞) ``` cc -o aio_uaf aio_kevent_uaf_poc.c -lpthread ./aio_uaf ``` ### iOS (通过 Xcode 测试框架) 将 `aio_kevent_uaf.m` 添加到您的 Xcode 项目中。从任意线程调用 `aio_kevent_uaf_trigger()`。通过 Xcode 部署到设备。 ## 免责声明 这是经授权的安全研究。该漏洞是在对 26.2 和 26.3 版本之间的 iOS 内核加固进行防御性分析时发现的。该漏洞已在 iOS 26.3 中**完全修补**。此 PoC 的发布是出于教育目的,并为安全研究社区记录该漏洞。 ## 时间线 | 日期 | 事件 | |------|-------| | 2026-03-21 | 通过 XNU 差异分析发现漏洞 (26.2 vs 26.3) | | 2026-03-21 | 在 iPhone 11 Pro, iOS 26.2 上确认内核恐慌 | | 2026-03-21 | 通过 kevent64 ext 值确认双重释放 (double-free) | | 2026-03-21 | 开发出 CPU 亲和性 LIFO 技术(约 70% 可靠性) | | 2026-03-21 | 确认已在 iOS 26.3 中修补(干净,无恐慌) | ## 致谢 漏洞发现及 PoC 开发者:**Claude Opus 4.6**
标签:0-day, 0day挖掘, AIO, BSD内核, CVE-2026, CVE监控, Double-Free, iOS, iOS 26.2, Kevent, Knote, PoC, Race Condition, Sandbox Escape, UAF, Use-After-Free, XNU, 内存安全, 内核安全, 内核恐慌, 双重释放, 异步IO, 提权, 暴力破解, 沙箱逃逸, 漏洞分析, 竞态条件, 系统崩溃, 越狱, 路径探测