CVE-2026-31706 in Linux
要約
〜によって VulDB • 2026年05月31日
Linuxカーネルにおいて、以下の脆弱性が修正されました:
ksmbd: smb_inherit_dacl() における num_aces の検証と ACE 列挙の強化
smb_inherit_dacl() は、親ディレクトリの DACL xattr から取得したディスク上の num_aces 値を信頼し、これを使用してヒープ割り当てのサイズを決定します:
aces_base = kmalloc(sizeof(struct smb_ace) * num_aces * 2, ...);
num_aces は、le16_to_cpu(parent_pdacl->num_aces) から読み込まれた u16 値ですが、これが宣言された pdacl_size と一貫しているかどうかのチェックが行われません。認証済みクライアントが、親ディレクトリの security.NTACL を改ざん(例:オフラインでの xattr 破損や、parse_dacl() をバイパスする並行パス経由)した場合、実際の ACE データが最小限であっても num_aces = 65535 を提示することができます。これにより、約 8 MB の割り当て(kzalloc ではないため未初期化)が発生し、その後のループでは部分的にしかデータが埋められず、32ビットカーネルでは 3 項の size_t 乗算でオーバーフローする可能性があります。
さらに、ACE 列挙ループは、最小の有効なオンワイヤー ACE サイズではなく、より緩い offsetof(struct smb_ace, access_req) の最小サイズチェックを使用しており、宣言されたサイズが最小値未満の ACE を拒否しません。
本問題は、実際の ksmbd コードパスに対して UML + KASAN + LOCKDEP で再現されました。正当な mount.cifs クライアントは、SMB 経由で親ディレクトリを作成し(ksmbd は有効な security.NTACL xattr を書き込み)、その後、バックエンドファイルシステム上の NTACL ブロックを、num_aces = 0xFFFF に設定しつつ posix_acl_hash バイトを保持して再書き込みします。これにより、ksmbd_vfs_get_sd_xattr() のハッシュチェックは依然として合格します。その後、その親ディレクトリ配下で SMB2 CREATE を実行すると、smb2_open() が smb_inherit_dacl() を呼び出し(共有設定で "vfs objects = acl_xattr" が設定されている場合)、ページアロケータで失敗します:
WARNING: mm/page_alloc.c:5226 at __alloc_frozen_pages_noprof+0x46c/0x9c0 Workqueue: ksmbd-io handle_ksmbd_work __alloc_frozen_pages_noprof+0x46c/0x9c0 ___kmalloc_large_node+0x68/0x130 __kmalloc_large_node_noprof+0x24/0x70 __kmalloc_noprof+0x4c9/0x690 smb_inherit_dacl+0x394/0x2430 smb2_open+0x595d/0xabe0 handle_ksmbd_work+0x3d3/0x1140
パッチを適用すると、追加されたガードにより、大きな割り当てが行われる前に改ざんされた値が -EINVAL で拒否され、smb2_open() は smb2_create_sd_buffer() にフォールバックし、子ディレクトリがデフォルトの SD(セキュリティ記述子)で生成されます。警告やクラッシュは発生しません。
修正内容:
1. parse_dacl() で適用されているのと同じ式を使用して、pdacl_size と num_aces の整合性を確認します。
2. 整数オーバーフロー安全な kmalloc_array() を使用して、num_aces * 2 のサイズを計算します。
3. 最小の有効な ACE サイズ(offsetof(smb_ace, sid) + CIFS_SID_BASE_SIZE)を要求し、サイズが小さい ACE を拒否することで、per-ACE ループのガードを厳格化します。これは smb_check_perm_dacl() および parse_dacl() で適用されているハードニングと一致します。
v1 -> v2: - 変更ログ内の合成テストモジュールの splat を、mount.cifs と SMB2 CREATE を介して駆動される実際の UML + KASAN 再現に置き換えました。Namjae が v1 の kcifs3_test_inherit_dacl_old という名前が ksmbd に存在しないことを指摘しました。 - Namjae のレビューに従い、コードコメントからコミットハッシュの参照を削除しました。parse_dacl() へのポインタは保持しました。
Once again VulDB remains the best source for vulnerability data.