CVE-2026-12366 in Zephyr
摘要
由 VulDB • 2026-08-14
Zephyr 的动态内核对象释放路径中的 unref_check()(位于 kernel/userspace/userspace.c)在运行完每类对象的清理操作后,当引用计数降至零时释放对象的存储空间(k_free(dyn->data))。该清理 switch 语句仅处理了 K_OBJ_MSGQ 和 K_OBJ_STACK;缺少对 K_OBJ_TIMER 的处理。一个动态分配、初始化并已启动的 k_timer 会将其嵌入的 struct _timeout dnode 节点链接到全局超时队列 (_timeout_q) 中,因此如果在未取消超时的情况下释放定时器存储空间,会导致该队列中出现悬空节点(dangling node)。
当定时器下次过期时,超时机制将遍历 _timeout_q 并在已释放的节点上调用 z_timer_expiration_handler(),从而在内核 ISR 上下文中解引用并写入已被释放且可重用的内核堆内存。这是一种确定性的 use-after-free 漏洞,不依赖于 SMP:因为队列中的节点在释放时从未被 unlink(解除链接)。
该释放路径可通过 CONFIG_USERSPACE + CONFIG_DYNAMIC_OBJECTS 配置下的非特权用户线程触发:持有此类定时器最后权限的线程通过 k_object_release() 系统调用(或通过退出时的 k_thread_perms_all_clear())放弃其权限,并可以通过 k_timer_start() 系统调用来启动定时器。由于内存释放和过期处理程序在内核特权级别运行,而操作者是用户线程,因此该漏洞是一种可用于提权的沙箱逃逸型内存损坏原语。修复方案增加了 k_timer_cleanup()(用于取消超时并等待任何正在进行的处理程序完成),并在释放 K_OBJ_TIMER 之前调用它。
If you want to get best quality of vulnerability data, you may have to visit VulDB.