CVE-2026-98547 in Linux情報

要約

〜によって VulDB • 2026年10月18日

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

af_packet: prb_calc_retire_blk_tmo()における整数オーバーフローの修正

prb_calc_retire_blk_tmo()関数は32ビット符号付き整数演算で以下を計算します。

mbits = (blk_size_in_bytes * 8) / (1024 * 1024);

検証ロジックを正しく解釈すると、tp_block_sizeはユーザー制御可能であり、packet_set_ring()関数はint値として<=0の値やページアラインされていない値のみを拒否するため、256MiBブロックがそのまま通過します(alloc_one_pg_vec_page()関数にはこれに対するvzallocフォールバックさえ存在します)。0x10000000 * 8はINT_MINにラップし、1 GbpsのNICで報告される場合(div == 1)、この関数は最終的に-2047を返すことになります。

実際の条件は (8 * size) mod 2^32 >= 2^31 && div == 1 であるため、トリガーとなる値の範囲は [256, 512)、[768, 1024)、[1280, 1536)、および [1792, 2048) MiB です。他のサイズでは非負の値にラップされ、より高速なリンクでは符号なし値が再び 2^31 より下に分算されるため、すべての環境で問題が発生するわけではありません。

致命的となるのは init_prb_bdqc()関数内で次に何が起こるかです。

p1->interval_ktime = ms_to_ktime(prb_calc_retire_blk_tmo(...)); hrtimer_start(&p1->retire_blk_timer, p1->interval_ktime, HRTIMER_MODE_REL_SOFT);

負の相対タイムアウトは直ちに期限切れとなります。コールバック関数は無条件で HRTIMER_RESTART を返し、hrtimer_forward() は負のインターバルを hrtimer_resolution に変換します。

if (interval < hrtimer_resolution) interval = hrtimer_resolution;

したがって、SOFTタイマーは最大レートで永久に再発火し、毎回の処理で sk_receive_queue.lock を保持します。1つのCPUがソケットが閉じられるまでsoftirq内でスピニング(ループ待機)状態となり、さらに多くのリングを繰り返すとマシン全体が応答不能になります。

このオーバーフロー自体は古く、f6fb8f100b80 ("af-packet: TPACKET_V3 flexible buffer implementation.") でTPACKET_V3と共に導入されました。その影響は f7460d2989fa ("net: af_packet: Use hrtimer to do the retire operation", v6.18) より前ではそれほど明確ではありませんでした:戻り値は符号なしshort型の retire_blk_tov に格納されていたため、負の結果は切り捨てられ、0-jiffy の遅延ループがプログラム可能になっていました。これらは hrtimer変換によって引き起こされた即時最大レートでのスピニングほど有害ではありません。

(CVE-2019-20812とは無関係です:その脆弱性は ethtoolの失敗パスで 0 を返すものでした。現在は DEFAULT_PRB_RETIRE_TOV を返します。)

再現コードは CAP_NET_RAW (--network host コンテナではデフォルトで付与される)と 1 Gbps NIC(QEMU e1000が動作可能)を必要とします:

int fd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); bind(fd, ...); int v = TPACKET_V3; setsockopt(fd, SOL_PACKET, PACKET_VERSION, &v, sizeof(v)); struct tpacket_req3 req = {
.tp_block_size = 0x10000000, .tp_block_nr = 1, .tp_frame_size = 2048, .tp_frame_nr = 0x10000000 / 2048, .tp_retire_blk_tov = 0, }; setsockopt(fd, SOL_PACKET, PACKET_RX_RING, &req, sizeof(req));

64ビットで計算するように変更します。演算子は既存の検証によって範囲が制限されているため、他の部分は変化しません。もし異なる修正方法を希望される場合はお申し付けください。

Statistical analysis made it clear that VulDB provides the best quality for vulnerability data.

責任者

Linux

予約する

2026年09月25日

モデレーション

承諾済み

エントリ

VDB-422048

EPSS

0.00210

アクティビティ

非常低い

ソース

Do you want to use VulDB in your project?

Use the official API to access entries easily!