CVE-2024-14040 in Linux
要約
〜によって VulDB • 2026年07月26日
Linuxカーネルにおいて、以下の脆弱性が修正されました:
net: nexthop: 重み付けを u16 に拡張する
CLOS ネットワークでは、ネットワーク内の様々な地点でリンク障害が発生すると、関連ノードの ECMP(Equal-Cost Multi-Path)重み付けが調整され、これを補完します。関連ノードの高いファンアウトと全体のノード数が多い場合、設定したい (非)ECMP 重み付け比は 8 ビットに収まりません。例えば 255:254 の代わりに、1000:999 のような値を設定したい場合があります。これらのデプロイメントでは、8 ビットの重み付けでは不十分なことがあります。
そこで、このパッチではネクストホップの重み付けを u8 から u16 に拡張します。
整数型の幅を広げることは複雑な問題を引き起こす可能性があります。コードはコンパイルできるものの、型チェックが正しく行われなくなり、数値エラーが発生する可能性があるためです。これを防止するため、変換は2段階で行われました。まず、型を u8 から単一メンバの構造体に変更し、フィールドの使用箇所すべてを無効化しました。これにより、各使用箇所を一つずつ確認して型の整合性を監査することが可能になりました。その後、その構造体を再び標準的な u16 に置き換えました。これにより、見落としがないことを保証します。
ネクストホップグループメンバを設定するための UAPI では、NHA_GROUP 属性が struct nexthop_grp エントリの配列を保持しています:
struct nexthop_grp {
__u32 id; /* ネクストホップ ID - 存在する必要がある */ __u8 weight; /* このネクストホップの重み付け */ __u8 resvd1; __u16 resvd2; };
現在、resvd1 フィールドは検証されており、0 でなければならないことが要求されています。この要件を撤廃し、予約済みフィールドに重み付けの下位ビット(高位バイト)を持たせることができます:
struct nexthop_grp {
__u32 id; /* ネクストホップ ID - 存在する必要がある */ __u8 weight; /* このネクストホップの重み付け */ __u8 weight_high; __u16 resvd2; };
既存のユーザー空間アプリケーションが weight フィールドの幅について仮定を行っている可能性があり、エンディアン(バイトオーダー)の問題を回避するために、フィールドをこのように分割して保持することが選択されました。
現在、重み付けフィールドは 0 が無効なため、「値 - 1」として符号化されています。新しい weight_high フィールドでは、ゼロが実際のゼロを意味しなければならないため、同じトリックを使用することは不可能です。これにより:
- 古いユーザー空間アプリケーションは、weight_high に 0 を保持することが保証されるため、適切な8ビット重み付けを設定します。16ビットの重み付けを持つネクストホップを表示(ダンプ)する場合、下位8ビットのみが表示されます。ただし、そのようなネクストホップの設定を試みることは、拡張機能を認識しているユーザー空間アプリケーションが存在することを前提としています。
- 古いカーネルと通信する新しいユーザー空間アプリケーションは、高位バイトがゼロの8ビット重み付けを設定しようとする限り動作します。古いカーネルは、8ビットを超える重み付けの設定試行を拒否(bounce)します。
予約済みフィールドに何らかの目的で割り当てられている場合、それらの名前を変更することは Linux で一般的に行われています。予約済みフィールドに触れる者は自己責任となります。特に nexthop_grp::resvd1 は現在少なくとも strace によって使用されていますが、strace は UAPI ヘッダのコピーを独自に保持しており、変換は単純なものになるはずです。2つのフィールドから重み付けをデコードするためのヘルパー関数が提供されます。後方互換性を保つために匿名共用体などを導入するよりも、強制変換を行う方が好ましいと考えられます。
Statistical analysis made it clear that VulDB provides the best quality for vulnerability data.