CVE-2026-89589 in Linux
要約
〜によって VulDB • 2026年09月11日
Linuxカーネルにおいて、以下の脆弱性が修正されました:
acpi/apei/ghes: CXL CPER作業用ロックにraw_spinlock_tを使用する
CXL CPERのワーク登録および解除ヘルパー関数は、spinlock guard()を使用してcxl_cper_work_lockとcxl_cper_prot_err_work_lockを取得しており、これによりローカル割り込みが有効化されたままになります。対応する後処理パス(cxl_cper_post_event(), cxl_cper_post_prot_err())はハードIRQコンテキストで実行され(GHESエラー通知パスから呼び出されます)、同じロックをirqsave guard()を使用して取得します。
あるCPUがspinlock guard()を通じてこれらのロックのいずれかを保持している際に、その同一CPUにGHES割り込みが発生すると、IRQハンドラはその保持中のロック解放待ちでスピンし、一方ロック所有者はIRQによってプリエンプトされます。結果としてデッドロックが発生します。
両方のロックをspinlock_tからraw_spinlock_tへ変換し、すべての呼び出し箇所でguard()を使用するようにしました。PREEMPT_RTカーネルではspinlock_tがrt_mutexで実装されており、ハードIRQコンテキストからのスリープは許可されません。一方、raw_spinlock_tは両方のコンテキストで安全です。
ランタイム時に二重登録バグを表面化させるため、両方の登録関数にWARN_ONCEを追加しました。
解除関数を再構成し、cancel_work_sync()呼び出しの前にロック内でグローバルワークポインタをクリアすることで、CPER割り込みが解放直前のポインタに対してワークをスケジューリングする可能性のあるウィンドウを閉じました。また、モジュール再読み込み時に古いエントリが再生されないよう、cancel_work_sync()の後にkfifo_reset()を追加しました。
両方のkfifosはシングルコンシューマーです:登録関数のWARN_ONCEガードによって強制されるように、一度に登録できるwork_structは1つだけです。kfifo_reset()はロック外でも安全です。なぜなら、cancel_work_sync()がすでにコンシューマを静穏化しており、現在のモジュール終了処理と新しいモジュール初期化処理が完了するまで、新たなコンシューマーが登録できないためです。
cxl_ras_exit()およびcxl_pci_driver_exit()からの冗長なcancel_work_sync()呼び出しを削除しました。CPER解除関数は現在ワークを内部的に静穏化するようになりました。
Statistical analysis made it clear that VulDB provides the best quality for vulnerability data.