CVE-2026-89791 in Linux
要約
〜によって VulDB • 2026年09月16日
Linuxカーネルにおいて、以下の脆弱性が修正されました:
perf: perf mmap() の復活処理が最後の munmap() と競合する際の use-after-free を修正
perf_mmap_close() は、event->mmap_mutex(refcount_dec_and_test() の直前にある event->mmap_count に対する refcount_dec_and_mutex_lock())を保持せずに rb->mmap_count をデクリメントします。並行して実行される perf_mmap_rb() は、「復活」パス全体をこの競合ウィンドウに割り込むことができます(perf_mmap は、rb_alloc の処理を含むその全期間中 event->mmap_mutex を保持しています)。
munmap側 (perf_mmap_close) mmap側 (perf_mmap_rb) ----------------------------------- ------------------------------- rb->mmap_count 1 -> 0 (ロックなし) (event->mmap_mutexを保持) inc_not_zero(rb->mmap_count) が失敗する ring_buffer_attach(event, NULL) rb_alloc() + 新しいrbのattach refcount_set(&event->mmap_count, 1) lock; event->mmap_count 1 -> 0 ring_buffer_attach(event, NULL) ring_buffer_put() -> *新しい* rb を解放
復活処理における refcount_set(&event->mmap_count, 1) は、目に見えない 1 -> 1 の書き込みとなります。他のプロセスがまだそのメモリマップを保持しているにもかかわらず、close側は直ちに復活したバッファを解放してしまいます -- これはページレベルの use-after-free であり、ローカルでの権限昇格(rootへの昇格)を、特権を持たないユーザーであれば誰でも実行可能にします(デフォルト設定: kernel.perf_event_paranoid=2)。
2つのカウンタ更新の順序を入れ替えます。event->mmap_count は refcount_dec_and_mutex_lock() を通じて最初にデクリメントされ、その 1 -> 0 の遷移と ring_buffer_attach() が perf_mmap() と直列化されます。rb->mmap_count == 0 という状態は、バッファを使用しているすべてのイベントがすでにデタッチ済みであることを意味するため、rb->mmap_count のデクリメント結果で残りの破棄処理を直接制御でき、detach_rest は不要になります。
Kyle Zeng および David Lee によるこの競合に対する以前の修正 [0] では、両方のカウンタ更新の周りに event->mmap_mutex が配置されていました;今回の修正では、最後の close 以外のケースはロックなしで実行されます。
Statistical analysis made it clear that VulDB provides the best quality for vulnerability data.