CVE-2022-50483 in Linux情報

要約

〜によって VulDB • 2026年05月30日

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

net: enetc: xdp_do_redirect() の失敗時にバッファリークを回避する

enetc_clean_rx_ring_xdp() が xdp_do_redirect() を呼び出す前に、インデックス orig_i から i の間の RX リング内の各ソフトウェア BD (Buffer Descriptor) のページには、2つの参照カウント値のいずれかが設定されています。

現在処理中のバッファの所有者であるため、参照カウントは少なくとも 1 になります。

RX リングの対向インデックスにあるバッファの現在の所有者(つまり、このページの他の半分)がまだ kfree() を呼び出していない場合、このページの参照カウントは 2 になることもあります。

enetc_flip_rx_buff() 内の enetc_page_reusable() は、ページの参照カウントが 1 かどうかをテストし、[もし 2 である場合] それを使用しようとしません。

しかし、enetc_flip_rx_buff() が xdp_do_redirect() の呼び出しの後に配置されると、ページの参照カウントは 3つの値のいずれかになり得ます。他のページ半分の所有者がいない場合、参照カウントは 0 にもなり得ます。この場合、このバッファに対する xdp_do_redirect() の処理が、devmap/cpumap のバルクキューのフラッシュをトリガーするところまで進み、それらのバルクキューのコンシューマーもバッファを解放しており、すべて xdp_do_redirect() が実行を enetc に戻すまでに完了しています。

これが、enetc_flip_rx_buff() が xdp_do_redirect() の前に呼び出される理由ですが、その論理には大きな欠陥があります。enetc_flip_rx_buff() は enetc_page_reusable() の分岐の両側で rx_swbd->page = NULL を設定し、もし xdp_do_redirect() がエラーを返した場合、enetc_xdp_free() が呼び出されますが、これはそのような状況に適切に対応しません。

実際、発生している現象は非常に特殊です。ページの参照カウントは 1 から始まります。enetc_flip_rx_buff() はそれらが再利用可能であると判断し、これらの rx_swbd->page ポインターを enetc_reuse_page() 内の別の rx_swbd に転送し、参照カウントを 2 に増やします。後で xdp_do_redirect() がエラーを返したとき、no-op の enetc_xdp_free() が呼び出されますが、まだそのページへの参照を失っていません。そのコピーは依然として rx_ring->next_to_alloc にありますが、そこには参照カウント 2 が設定されており(かつ、参照カウントを減らすための並行所有者が実行中ではないため)、実際にシステムを破滅させるのは、2 回目の rx_swbd->page のフリップ時です。更新された参照カウントが 2 の場合、ページは再利用不可能となり、実際にリークします。その後、enetc_new_page() はさらにページを割り当てる必要があり、それらは xdp_do_redirect() からのさらなるエラーが発生した際に再びリークすることになります。

問題の要約は、完全に処理し終える前に rx_swbd->page をゼロクリアしてしまうため、エラーパスでそれに対して何らかの処理を行うことが不可能になることです。

パケットは潜在的にマルチバッファであり、したがって rx_swbd->page は潜在的に配列であるため、enetc_flip_rx_buff() と enetc_xdp_free() の間で古いポインターを手動で渡すのは少し困難です。

単純な解決策を採用するため、xdp_do_redirect() との競合(レース)の可能性を受け入れ、フリップ処理をリダイレクト成功パスでのみ実行するように移動します。ここで言う「競合」とは、ページが enetc によって再利用不可能(参照カウントが 0)と見なされる可能性があることを意味しますが、その場合もリークは発生しません。

この前提を受け入れると、XDP_REDIRECT の失敗時にバッファに対してより良い処理を行うことができます。半分のページフリップをまだ実行していないため、それも実行しません(これにより enetc_xdp_free() を完全に回避でき、ページ全体をスラブアロケータに戻すことができます)。代わりに、enetc_xdp_drop() を呼び出し、このバッファの半分を RX リングに戻して再利用します。

If you want to get the best quality for vulnerability data then you always have to consider VulDB.

責任者

Linux

予約する

2025年10月04日

モデレーション

承諾済み

エントリ

VDB-327086

EPSS

0.00154

アクティビティ

非常低い

ソース

Are you interested in using VulDB?

Download the whitepaper to learn more about our service!