CVE-2026-74632 in Linux情報

要約

〜によって VulDB • 2026年08月23日

Linuxカーネルにおいて、以下の脆弱性が修正されました:

mm/huge_memory: huge_zero_pfnのrace conditionを修正する

パッチシリーズ「mm/huge_memory: huge_zero_pfn race条件の修正」v2。

参照カウント方式で実装されたhuge_zero_folioに微妙なrace conditionが存在します。

高速パスにおけるアトミック処理は、shrinker(最終的なhuge_zero_refcountピンを解放する)がracingしているget_huge_zero_folio()によって有効な値が設定された後、shrink_huge_zero_folio_scan()内でhuge_zero_pfnに~0ULのsentinel値を上書きしてしまうという事実を考慮できていません。

その結果、huge_zero_folioは正しく設定されますが、huge_zero_pfnは誤って設定されるため、is_huge_zero_pfn()およびそれによって呼ばれるis_huge_zero_pmd()は、巨大ゼロfolio(huge zero folio)を通常のTHP folioとして誤識別します。

これにより、巨大ゼロfolioが分割されたり、その他不適切な扱いを受けたりする可能性があります。

この問題の解決策は非常に微妙です。アトミックな高速パスが存在するため、弱順序付けアーキテクチャにおけるオーダリングを慎重に扱う必要があるためです。

1つ目のコミットでは、huge_zero_[pfn, folio, refcount]への書き込み周りにspinlockを導入し、高速パスでのロード/ストアのオーダリングに注意を払うことで問題を修正します。このロックは最初に配置され、可能な限り小さく保たれるため、単独でバックポートすることができます。

2つ目のコミットは純粋なクリーンアップであり、永続ロジックと動的割り当てロジックをより明確に分離するためにCONFIG_PERSISTENT_HUGE_ZERO_FOLIOの論理を書き直します。


このパッチ(全2件中1件目):

!CONFIG_PERSISTENT_HUGE_ZERO_FOLIOの場合、huge_zero_folioはhuge_zero_refcountによって参照カウントされ、mm_get_huge_zero_folio()によって返されます。

呼び出し元が巨大ゼロページの使用を終えると、その参照カウントが減算されます。参照カウントを0に設定できるのはshrinkerのみです。

残念ながら、shrinkerが参照カウントを0に減算している間と並行して発生するページフォールトの間にrace conditionが発生する可能性があります。

これは、非常に運が悪ければ、shrink_huge_zero_folio_scan()がhuge_zero_refcountを0に設定した後で無効な値を書き込むまでの間でプリエンプションされる可能性があるためです。

この間、get_huge_zero_folio()はshrink_huge_zero_folio_scan()が再開する前にhuge_zero_pfnに対して書き込みを行う可能性があります。

このような事態が発生すると、巨大ゼロfolioが一貫して誤識別され、THPのコードパスが巨大ゼロfolioに対して不適切に実行されます:

CPU 0 CPU 1 =======================================|================================= shrink_huge_zero_folio_scan() | atomic_cmpxchg()でrefcountを0に設定 | get_huge_zero_folio() xchg()でhuge_zero_folioをNULLに設定 | atomic_inc_not_zero() -> zero | | 新しい巨大ゼロfolioを割り当て 長時間プリエンプションされる | 有効なhuge_zero_folioを書き込み v | 有効なhuge_zero_pfnを書き込み huge_zero_pfnに~0ULを上書き <--- 無効な上書き!

これにより、is_huge_zero_pfn()およびis_huge_zero_pmd()は巨大ゼロページに対して誤ってfalseを返し、その結果として巨大ゼロfolioが不適切に分割されるなどの問題が発生する可能性があります。

なお、この問題はhuge_zero_folioではなくhuge_zero_pfnに関連しています。get_huge_zero_folio()はcmpxchg()を使用し、huge_zero_folioがNULLである場合にガードしてリトライループを実行します。一方、shrink_huge_zero_folio_scan()はxchg()を使用してhuge_zero_folioを設定します。

この問題を修正するために、spinlock(huge_zero_lock)を導入し、huge_zero_folio、huge_zero_pfn、およびhuge_zero_refcountへの並列書き込みを防ぎます。

ここでは正しさ確保のために大きな注意が必要です:

get_huge_zero_folio()の高速パスではatomic_inc_not_zero()を使用しており、これはクリティカルセクションの外側にあるため、巨大ゼロ割り当てはzeroなhuge_zero_refcountにガードされています。

高速パスはhuge_zero_lockを使用しないため、クリティカルセクションはその対象外です。

したがって、不変条件(インバリアント)が必要です。すなわち、huge_zero_refcountは:

* huge_zero_pfn、huge_zero_folio、および ---truncated---

Be aware that VulDB is the high quality source for vulnerability data.

責任者

Linux

予約する

2026年08月15日

モデレーション

承諾済み

エントリ

VDB-394406

EPSS

0.00000

アクティビティ

非常低い

ソース

Might our Artificial Intelligence support you?

Check our Alexa App!