CVE-2026-98256
signal: exec() の競合を防止
- 公開済み
- 2026/10/06
- 更新済み
- 2026/10/19
- CNA の割り当て
- Linux
- 観察された証拠
- 2026/11/04
プライマリ 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/04
EPSS は統計的な推定値であり、確実性や影響の尺度ではありません。 CVSS、KEV ステータス、暴露、環境と組み合わせます。
概要
Linux カーネルにおいて、以下の脆弱性が修正されました: signal: exec() の競合を防止する。Hyunwoo は以下の KASAN UAF スプラットをデバッグしました: BUG: KASAN: slab-use-after-free in __send_signal_locked+0xb27/0xba0 Write of size 8 at addr ffff888007ed80c8 by task poc/79 ... Call Trace: __send_signal_locked+0xb27/0xba0 do_send_sig_info+0xa7/0x160 do_send_specific+0x76/0xa0 __x64_sys_tgkill+0x193/0x270 ... Allocated by task 80: do_timer_create+0x1a4/0x1030 __x64_sys_timer_create+0x145/0x190 ... Freed by task 12: kmem_cache_free_bulk+0x1f8/0x4a0 kvfree_rcu_bulk+0x14f/0x1c0 kfree_rcu_work+0x128/0x1a0 ... Last potentially related work creation: kvfree_call_rcu+0x39/0x390 __flush_itimer_signals+0x211/0x320 flush_itimer_signals+0x47/0x90 begin_new_exec+0xa6b/0x28c0 これは、Hyunwoo が説明したように、非リーダーによる exec() で発生することが判明しました: de_thread() は release_task(leader) の前に exchange_tids() を呼び出すため、リーダーの tid に対して作成された SIGEV_THREAD_ID タイマーが保持する struct pid は、execve() を呼び出したスレッドを指すようになります。pid_task() はそのスレッドを返し、それに対する lock_task_sighand() は成功します。タイマーシグナルがブロックされている場合、その sigqueue はリーダーの task::pending にキューされたままになります。そのタイマーの次の満了は、release_task() がキューをフラッシュしている最中に実行される可能性があります。posixtimer_send_sigqueue() は、sigqueue がすでにキューされているかどうかを単純な list_empty() でチェックしますが、これは list_head::next を読むだけです。list_del_init() はアトミックではなく、INIT_LIST_HEAD() は list_head::prev より先に list_head::next を格納するため、その間にチェックが通ってしまう可能性があります。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) のシグナルキューイングを防止する。 - exit_signals() における PF_EXITING のロックなし設定を、タスクグループが空の場合およびグループ終了の場合について sighand ロックで保護する。 - そこで task::pending シグナルをフラッシュする。これを最適化するため、pending リスト全体を sighand ロック下でオンスタックのリストヘッドに移動し、ロックを保持せずにシグナルを解放する。ロックレスフラッシュおよび弱い順序付けシステムにおける非リーダー exec の場合について、かなりの議論がありました。問題は、posix タイマーシグナルを送信しようとする第三者が、ターゲットタスクを見つけるために PID ルックアップに依存しており、そのルックアップが、シグナルが元々古いリーダーに向けられていた場合に新しいリーダーを返す可能性があることです。シグナルが古いリーダーにキューされた場合、ロックレスフラッシュは以下の状況について懸念を引き起こしました: old_leader new_leader third party A: flush_list() // list_del_in ---省略---
責任ある使用
脆弱性情報は、自分が所有しているシステム、またはテストを許可されているシステムでのみ使用してください。 Kitploit は公開研究メタデータにリンクしており、エクスプロイト コードや悪意のあるペイロードは保存しません。