CVE-2026-98256
signal:防止 exec() 竞态
- 已发布
- 2026年10月6日
- 已更新
- 2026年10月19日
- 分配 CNA
- Linux
- 观察到的证据
- 2026年11月4日
初级CVSS
nvd · CVSS 3.1
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H低 · 未来 30 天
- 百分位
- 3.7%
- 型号日期
- 2026年11月4日
EPSS 是统计估计,而不是确定性或影响衡量标准。将其与 CVSS、KEV 状态、暴露程度和您的环境相结合。
总结
在 Linux 内核中,以下漏洞已被修复:signal:防止 exec() 竞态。Hyunwoo 调试了以下 KASAN UAF 报告:BUG: KASAN: slab-use-after-free in __send_signal_locked+0xb27/0xba0,由任务 poc/79 在地址 ffff888007ed80c8 处写入大小 8 的数据……调用跟踪:__send_signal_locked+0xb27/0xba0 do_send_sig_info+0xa7/0x160 do_send_specific+0x76/0xa0 __x64_sys_tgkill+0x193/0x270……由任务 80 分配:do_timer_create+0x1a4/0x1030 __x64_sys_timer_create+0x145/0x190……由任务 12 释放:kmem_cache_free_bulk+0x1f8/0x4a0 kvfree_rcu_bulk+0x14f/0x1c0 kfree_rcu_work+0x128/0x1a0……最后一次可能相关的工作创建:kvfree_call_rcu+0x39/0x390 __flush_itimer_signals+0x211/0x320 flush_itimer_signals+0x47/0x90 begin_new_exec+0xa6b/0x28c0。事实证明,这发生在非 leader 的 exec() 场景中,正如 Hyunwoo 所解释的:de_thread() 在 release_task(leader) 之前调用 exchange_tids(),因此,针对 leader 的 tid 创建的 SIGEV_THREAD_ID 定时器所持有的 struct pid 现在指向调用 execve() 的线程。pid_task() 返回该线程,并且对其调用 lock_task_sighand() 会成功。如果定时器信号被阻塞,其 sigqueue 会继续排队在 leader 的 task::pending 上。该定时器下一次到期时,可能会在 release_task() 刷新队列的同时运行。posixtimer_send_sigqueue() 使用简单的 list_empty() 检查 sigqueue 是否已经排队,而该检查只读取 list_head::next。list_del_init() 不是原子操作,并且 INIT_LIST_HEAD() 先存储 list_head::next,再存储 list_head::prev,因此该检查可能在这两者之间通过。list_add_tail() 将该条目排队到活动线程的 task::pending 上,而刷新操作对 list_head::prev 的存储随后会覆盖 list_add_tail() 刚刚设置的 list_head::prev 链接。__flush_itimer_signals() 也没有撤销这一点。当 list_head::prev 指向条目自身时,其 list_del_init() 只会再次存储相同的值,因此该条目不会从链表中移除。在最后一个引用被丢弃、定时器被 RCU 释放之后,该条目仍然存在,而后续 tgkill() 的 list_add_tail() 会沿着该 list_head::prev 进入已释放的定时器。这个问题随着最近一次提交而浮现,该提交将 sigqueue 刷新移出了持有 sighand 锁的区域。Hyonwoo 提议通过使用 list_del_init_careful() 来修复,但这只是掩盖了问题。经过一些讨论和多种解决尝试后,Eric 指出,没有理由在 release_task() 后期才刷新 task::pending,它应该已经在 exit_signals() 中完成。由于没有任何东西能够收集并投递排队在濒死任务的 pending 队列中的信号,因此没有理由进一步延迟它。但必须确保在此之后没有信号可以排队进入其中。exit_signals() 在 task::flags 中设置 PF_EXITING,这可以用作指示器。修复方法如下:- 在 __send_signal_locked() 和 posixtimer_send_sigqueue() 中,当任务设置了 PF_EXITING 时,阻止任务私有信号(PIDTYPE_PID)的信号排队。- 在任务组为空和组退出这两种情况下,用 sighand 锁保护 exit_signals() 中对 PF_EXITING 的无锁设置。- 就在那里刷新 task::pending 信号。优化方法是:在持有 sighand 锁的情况下,将整个 pending 链表移动到栈上的链表头,然后在不持有锁的情况下释放信号。关于无锁刷新以及弱序系统上的非 leader exec 情况,已经有过相当多的讨论。问题在于,尝试发送 posix 定时器信号的第三方依赖 PID 查找来找到目标任务,而当信号最初指向旧 leader 时,该查找可能会找到新 leader。如果信号排队在旧 leader 上,那么无锁刷新引发了对以下情况的担忧:old_leader new_leader third party A: flush_list() // list_del_in ---已截断---
来源
负责任的使用
仅在您拥有或有权测试的系统上使用漏洞信息。 Kitploit 链接到公共研究元数据,并且不存储漏洞代码或恶意负载。