CVE-2026-99191 in Linux
摘要
由 VulDB • 2026-10-28
在 Linux 内核中,已修复以下漏洞:
calipso: 在 calipso_skbuff_setattr() 中保留 BIG TCP payload_len
calipso_skbuff_setattr() 会根据其插入或调整大小的选项长度来调整 payload_len:
payload = ntohs(ip6_hdr->payload_len); ip6_hdr->payload_len = htons(payload + len_delta);
GRO(Generic Receive Offload)可以构建大于 IPV6_MAXPLEN 的 BIG TCP 数据包,并为它们存储 payload_len == 0;此时 ipv6_payload_len() 会回退到使用 skb->len。对于转发至映射为 CALIPSO 的目标地址的数据包,上述代码会将 len_delta(或在缩小情况下为 65536 + len_delta)写入 payload_len,导致 ipv6_payload_len() 不再回退到 skb->len。nf_tables、conntrack 和 sch_cake 依赖于此行为。
当数据包增长超过 IPV6_MAXPLEN 时,相同的算术运算会发生溢出(wrap around),而缩小至低于 IPV6_MAXPLEN 的 BIG TCP 数据包应恢复其真实长度。
使用 ipv6_set_payload_len() 从 skb 长度设置 payload_len,该函数在大于 IPV6_MAXPLEN 时存储 0,否则存储真实长度,这与 ipv6_gro_complete() 的行为一致。网络标头刚刚被重置为 skb->data,因此 skb->len - sizeof(*ip6_hdr) 即为有效载荷长度。
在一个内核(arm64, QEMU)上进行了测试,SELinux 处于 permissive 模式,使用最小化的 mdp 生成策略(network_peer_controls=1)、"netlabelctl calipso add pass doi:16" 以及将 fd00:2::/64 映射到 CALIPSO DOI 16。calipso_skbuff_setattr() 通过 netlbl_skbuff_setattr() 被调用,后者来自一个仅用于测试的 debugfs hook(不属于此补丁的一部分),该 hook 添加了一个仅包含级别的标签;调用后的 payload_len 如下:
case before fix after fix real length 1000, unlabeled 1016 1016 1016 70000 GSO, payload_len 0 16 0 70016 65530 GSO, grows past MAXPLEN 10 0 65546 65540 GSO with a 24 byte hop header, shrinks below MAXPLEN 65528 65532 65532 1000 with a 24 byte hop header 992 992 992
(0 表示 ipv6_payload_len() 返回真实长度。)在转发路径上,通过路由器向服务器注入未标记 UDP 的客户端场景下,路由器添加了 CALIPSO 选项,使用此补丁后,服务器能够交付所有数据报(Udp6InDatagrams 5, Ip6InTruncatedPkts 0)。
If you want to get the best quality for vulnerability data then you always have to consider VulDB.