CVE-2026-19569 Zephyr 内核对象分配整数溢出漏洞
影响攻击者可触发堆溢出,可能导致内核崩溃或权限提升
Zephyr 内核 userspace.c 中的 dynamic_object_create() 在计算动态内核对象及线程栈元素的后备分配大小时,未对 obj_size_get(otype)+size 和 STACK_ELEMENT_DATA_SIZE(size) 做无符号回绕检查。当 size 接近 SIZE_MAX 时计算结果回绕为极小值,导致实际分配的堆块只有几个字节,而对象描述符仍按完整请求类型标记并注册到内核对象表中。
影响范围
受影响组件为 Zephyr 内核的用户态对象分配相关代码(kernel/userspace/userspace.c、kernel/dynamic.c 等)。具体受影响版本范围暂无公开信息。
漏洞详情
漏洞类型为整数溢出导致的堆缓冲区分配不足。k_object_alloc_size() 被声明为 __syscall,其验证函数 z_vrfy_k_object_alloc_size() 为直接透传,z_object_alloc() 仅对 otype 做范围检查,未对 size 做边界限制,因此用户态可直接将接近 SIZE_MAX 的 size 传入该算术运算。由于后续内核对象校验仅检查对象类型和初始化状态,过小的句柄仍能通过 K_SYSCALL_OBJ_INIT()/K_SYSCALL_OBJ_NEVER_INIT() 检查,从而造成堆越界访问。
利用条件与风险
利用前提是攻击者能够调用相关系统调用并传入超大 size 值,通常需要具备用户态代码执行能力。实战中可导致内核堆破坏,可能引发拒绝服务甚至权限提升,CVSS 8.8 属高危。
修复建议
官方修复方案暂无公开信息,建议关注 Zephyr 官方安全公告并升级至修复版本。临时缓解措施包括:在 z_vrfy_k_object_alloc_size() 等验证函数中对 size 增加上界检查,防止接近 SIZE_MAX 的输入进入分配计算。
dynamic_object_create() in kernel/userspace/userspace.c computed the backing allocation for a dynamically allocated kernel object as obj_size_get(otype) + size, and for thread stack elements as STACK_ELEMENT_DATA_SIZE(size) (a round-up plus fixed overhead), without checking either expression for unsigned wrap-around. A size close to SIZE_MAX makes the computed total wrap to a very small value, so the heap chunk handed out is a few bytes while the object descriptor is still tagged with the full requested type and registered in the kernel object table.
The size argument reaches that arithmetic directly from user mode. k_object_alloc_size() is declared __syscall in include/zephyr/sys/kobject.h, its verifier z_vrfy_k_object_alloc_size() in kernel/userspace/userspace_handler.c is a bare pass-through, and z_object_alloc() only range-checks otype — nothing bounds size. The stack-element branch is additionally reachable through the k_thread_stack_alloc() syscall via kernel/dynamic.c. Because subsequent kernel-object validation checks only the object’s type and initialization state, the undersized handle passes K_SYSCALL_OBJ_INIT()/K_SYSCALL_OBJ_NEVER_INIT(), and the matching init syscall (for example k_mutex_init(), k_sem_init(), or k_thread_create()) then writes a complete object over the truncated allocation.
An unprivileged user-mode thread can therefore trigger a supervisor-mode out-of-bounds write into the kernel resource-pool heap, of a size and content it substantially controls, corrupting sys_heap chunk metadata and adjacent kernel objects. Under CONFIG_GEN_PRIV_STACKS the thread-stack branch additionally stores an attacker-influenced wild pointer as a user thread’s privileged stack base. The practical result is escape from the CONFIG_USERSPACE sandbox — kernel-level code execution or at minimum kernel memory corruption and system compromise.
Exploitation requires CONFIG_USERSPACE together with CONFIG_DYNAMIC_OBJECTS (also selected by CONFIG_DYNAMIC_THREAD under userspace), and a calling thread with an assigned resource pool. The fix rejects both overflowing computations and frees the partially built descriptor.