| Title | LinuxのLinux Kernelにおける競合状態に関する脆弱性 |
|---|---|
| Summary | Linuxカーネルにおいて、以下の脆弱性が修正されました。bpf: PREEMPT_RT環境下のcpumapにおける競合状態を修正しました。PREEMPT_RTカーネルでは、CPUごとのxdp_bulk_queue (bq)が同一CPU上の複数のプリエンプト可能なタスクから同時にアクセスされうる状況が存在していました。元のコードは、同一CPU上でbq_enqueue()と__cpu_map_flush()が原子的に実行されると仮定し、プリエンプションを防ぐためにlocal_bh_disable()に依存していました。しかしPREEMPT_RTでは、local_bh_disable()はPREEMPT_RT_NEEDS_BH_LOCKが設定されていない場合migrate_disable()のみを呼び出し、プリエンプションを無効化しません。これにより、bq_flush_to_queue()の実行中にCFSスケジューラがタスクをプリエンプトし、同一CPU上で別のタスクがbq_enqueue()に入り、同一のCPUローカルbqに同時アクセスが可能となりました。このことにより、以下の競合が発生しました。1. __list_del_clearprev()の二重呼び出し:bq_flush_to_queue()でbq-countがリセットされた後、プリエンプトされたタスクがbq_enqueue()およびbq_flush_to_queue()を呼び出し、bq-countがCPU_MAP_BULK_SIZEに達した際に両タスクが同一bq-flush_nodeに対して__list_del_clearprev()を呼びます。2度目の呼び出しでは既にNULLに設定されたprevポインタをデリファレンスし、クラッシュを引き起こしました。2. bq-countおよびbq-q[]の競合:同時実行されるbq_enqueue()によってパケットキューがbq_flush_to_queue()処理中に破損する可能性があります。タスクA(__cpu_map_flush - bq_flush_to_queue)とタスクB(bq_enqueue - bq_flush_to_queue)の同一CPU上での競合状態の流れは以下の通りです。 Task A (xdp_do_flush) Task B (cpu_map_enqueue)---------------------- ------------------------bq_flush_to_queue(bq) spin_lock(&q-producer_lock) /* bq-q[]をptr_ringへフラッシュ */ bq-count = 0 spin_unlock(&q-producer_lock) bq_enqueue(rcpu, xdpf) -- CFSプリエンプトでTask A中断 -- bq-q[bq-count++] = xdpf /* ...多数enqueue処理... */ bq_flush_to_queue(bq) spin_lock(&q-producer_lock) /* ptr_ringへフラッシュ */ spin_unlock(&q-producer_lock) __list_del_clearprev(flush_node) /* flush_node.prevをNULLに設定 */ -- Task A再開 -- __list_del_clearprev(flush_node) flush_node.prev-next = ... /* prevがNULLのためカーネルoops発生 */これらの問題を修正するために、xdp_bulk_queueにlocal_lock_tを追加し、bq_enqueue()と__cpu_map_flush()内でロック取得を行います。これらの処理はlocal_bh_disable()の下で既に動作しているため、non-RTではオーバーヘッドのない注釈的意味を持ち、PREEMPT_RTでは同一CPU内でのスリーピングロックとして動作し、bqへのアクセスを直列化するlocal_lock_nested_bh()を使用します。再現手順としては、bq_flush_to_queue()のbq-count = 0と__list_del_clearprev()の間にmdelay(100)を挿入し、syzkaller提供のリプロデューサを実行してください。 |
| Possible impacts | 当該ソフトウェアが扱う情報について、外部への漏えいは発生しません。 また、当該ソフトウェアが扱う情報について、書き換えは発生しません。 さらに、当該ソフトウェアが完全に停止する可能性があります。 そして、この脆弱性を悪用した攻撃の影響は、他のソフトウェアには及びません。 |
| Solution | リリース情報、またはパッチ情報が公開されています。参考情報を参照して適切な対策を実施してください。 |
| Publication Date | March 25, 2026, midnight |
| Registration Date | April 27, 2026, 11:25 a.m. |
| Last Update | April 27, 2026, 11:25 a.m. |
| CVSS3.0 : 警告 | |
| Score | 4.7 |
|---|---|
| Vector | CVSS:3.0/AV:L/AC:H/PR:L/UI:N/S:U/C:N/I:N/A:H |
| Linux |
| Linux Kernel 6.18 |
| Linux Kernel 6.18.1 以上 6.18.17 未満 |
| Linux Kernel 6.19 以上 6.19.7 未満 |
| Linux Kernel 7.0 |
| No | Changed Details | Date of change |
|---|---|---|
| 1 | [2026年04月27日] 掲載 |
April 27, 2026, 11:25 a.m. |
| Summary | In the Linux kernel, the following vulnerability has been resolved: bpf: Fix race in cpumap on PREEMPT_RT On PREEMPT_RT kernels, the per-CPU xdp_bulk_queue (bq) can be accessed The original code assumes bq_enqueue() and __cpu_map_flush() run This leads to several races: 1. Double __list_del_clearprev(): after bq->count is reset in 2. bq->count and bq->q[] races: concurrent bq_enqueue() can corrupt The race between task A (__cpu_map_flush -> bq_flush_to_queue) and Task A (xdp_do_flush) Task B (cpu_map_enqueue) Fix this by adding a local_lock_t to xdp_bulk_queue and acquiring it To reproduce, insert an mdelay(100) between bq->count = 0 and |
|---|---|
| Summary | En el kernel de Linux, la siguiente vulnerabilidad ha sido resuelta: bpf: Corrige condición de carrera en cpumap en PREEMPT_RT En kernels PREEMPT_RT, la xdp_bulk_queue (bq) por CPU puede ser accedida concurrentemente por múltiples tareas preemptibles en la misma CPU. El código original asume que bq_enqueue() y __cpu_map_flush() se ejecutan atómicamente una con respecto a la otra en la misma CPU, confiando en local_bh_disable() para prevenir la preemption. Sin embargo, en PREEMPT_RT, local_bh_disable() solo llama a migrate_disable() (cuando PREEMPT_RT_NEEDS_BH_LOCK no está configurado) y no deshabilita la preemption, lo que permite que la planificación CFS preempte una tarea durante bq_flush_to_queue(), permitiendo que otra tarea en la misma CPU entre en bq_enqueue() y opere en la misma bq por CPU concurrentemente. Esto conduce a varias condiciones de carrera: 1. Doble __list_del_clearprev(): después de que bq->count se reinicia en bq_flush_to_queue(), una tarea preemptora puede llamar a bq_enqueue() -> bq_flush_to_queue() en la misma bq cuando bq->count alcanza CPU_MAP_BULK_SIZE. Ambas tareas luego llaman a __list_del_clearprev() en el mismo bq->flush_node, la segunda llamada desreferencia el puntero prev que ya había sido establecido a NULL por la primera. 2. Condiciones de carrera de bq->count y bq->q[]: bq_enqueue() concurrente puede corromper la cola de paquetes mientras bq_flush_to_queue() la está procesando. La condición de carrera entre la tarea A (__cpu_map_flush -> bq_flush_to_queue) y la tarea B (bq_enqueue -> bq_flush_to_queue) en la misma CPU: Tarea A (xdp_do_flush) Tarea B (cpu_map_enqueue) Solucione esto añadiendo un local_lock_t a xdp_bulk_queue y adquiriéndolo en bq_enqueue() y __cpu_map_flush(). Estas rutas ya se ejecutan bajo local_bh_disable(), por lo que se usa local_lock_nested_bh() que en sistemas no-RT es una anotación pura sin sobrecarga, y en PREEMPT_RT proporciona un bloqueo de suspensión por CPU que serializa el acceso a la bq. Para reproducir, inserte un mdelay(100) entre bq->count = 0 y __list_del_clearprev() en bq_flush_to_queue(), luego ejecute el reproductor proporcionado por syzkaller. |
| Publication Date | March 25, 2026, 8:16 p.m. |
| Registration Date | April 27, 2026, 12:18 p.m. |
| Last Update | April 24, 2026, 6:16 a.m. |
| Configuration1 | or higher | or less | more than | less than | |
| cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* | 6.18.1 | 6.18.17 | |||
| cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* | 6.19 | 6.19.7 | |||
| cpe:2.3:o:linux:linux_kernel:6.18:-:*:*:*:*:*:* | |||||
| cpe:2.3:o:linux:linux_kernel:7.0:rc1:*:*:*:*:*:* | |||||
| cpe:2.3:o:linux:linux_kernel:7.0:rc2:*:*:*:*:*:* | |||||
| cpe:2.3:o:linux:linux_kernel:7.0:rc3:*:*:*:*:*:* | |||||
| cpe:2.3:o:linux:linux_kernel:7.0:rc4:*:*:*:*:*:* | |||||
| cpe:2.3:o:linux:linux_kernel:7.0:rc5:*:*:*:*:*:* | |||||
| cpe:2.3:o:linux:linux_kernel:7.0:rc6:*:*:*:*:*:* | |||||
| cpe:2.3:o:linux:linux_kernel:7.0:rc7:*:*:*:*:*:* | |||||