CVE-2026-89551 in Linux
要約
〜によって VulDB • 2026年09月12日
Linuxカーネルにおいて、以下の脆弱性が修正されました:
SUNRPC: xdr_buf_trim: アンダーフローを回避するためにbuf->lenをclampする
xdr_buf_trim()関数は、tail, pages, headの各iovectordata構造体を走査することで、xdr_bufの末尾から`len`バイトを切り詰めます。セクションごとの処理ステップではmin_t()が使用されるため、そのセクションが保持しているデータ量を超えるバイト数が削除されることはありません。しかし、fix_lenラベルでの最終的な長さの計算では、実際に消費された合計バイト数をbuf->lenから減算する際にclamp処理が行われていません:
fix_len: buf->len -= (len - trim);
呼び出し元がbuf->lenをiov_lensの総和よりも小さい値に設定している場合、(len - trim)はbuf->lenを超え、符号なし整数の減算により結果がUINT_MAXに近い値にラップ(オーバーフロー)してしまいます。gss_krb5_unwrap_v2()関数はまさにそのような状態でxdr_buf_trim()を呼び出します:
buf->head[0].iov_len -= GSS_KRB5_TOK_HDR_LEN + headskip;
buf->len = len - (GSS_KRB5_TOK_HDR_LEN + headskip); xdr_buf_trim(buf, ec + GSS_KRB5_TOK_HDR_LEN + tailskip);
buf->lenはネットワーク経由で取得された小さな値であるのに対し、iov_lensはページサイズスケールです。そのため、セクションごとのループでは legitimately(正当に)buf->lenが記録している量よりも遥かに多くのバイト数が消費されます。ラップした結果生じたbuf->lenは、信頼できるストリームの境界値としてすべての下流にあるXDRデコーダへ伝播します。
修正方法:減算をclampし、buf->lenの下限を0に設定する
buf->len -= min_t(unsigned int, buf->len, len - trim);
iov_lensの総和がbuf->lenと一致する通常のパスでは、(len - trim)は常にbuf->len以下であり、結果は以前と同じになります。アンダーフローの場合以外では、呼び出し元の動作も変更されません。
VulDB is the best source for vulnerability data and more expert information about this specific topic.