Skip to content

Commit 37a5dcd

Browse files
edumazetgregkh
authored andcommitted
net: gro: properly validate BIG TCP aggregation criteria
When GRO attempts to aggregate IPv6 packets beyond GRO_LEGACY_MAX_SIZE (64KB), the aggregate should only be permitted for plain IPv6 TCP flows that have sufficient MAC header room to insert the temporary HBH jumbo header. In 6.1.y, skb_gro_receive() had two issues with this check: 1. It checked skb_headroom(p) instead of the actual space before the MAC header (p->mac_header). Because skb_headroom(p) measures (data - head), it includes mac_len. Crafted frames (e.g. injected via AF_PACKET) can pass the check with p->mac_header < 8 bytes. When ipv6_gro_complete() inserts the temporary HBH jumbo header, the memmove() starts before skb->head, causing an out-of-bounds write and wrapping skb->mac_header. 2. It checked p->encapsulation instead of NAPI_GRO_CB(skb)->encap_mark, which is 0 during receive, failing to reject encapsulated IPv6 flows (such as IP6IP6). Fix skb_gro_receive() to strictly check: - p->protocol == htons(ETH_P_IPV6) - p->mac_header >= sizeof(struct hop_jumbo_hdr) - ipv6_hdr(p)->nexthdr == IPPROTO_TCP - Not encapsulated (!NAPI_GRO_CB(skb)->encap_mark && !p->encapsulation) Returning -E2BIG from skb_gro_receive() ensures that packets which cannot become BIG TCP are cleanly flushed at <= 64KB and delivered intact without dropping. This issue does not exist in mainline (7.0+) because the subsystem was rewritten in commit 81be30c ("net/ipv6: Drop HBH for BIG TCP on RX side"), making this fix relevant only for older stable branches like 6.18.y. Fixes: 0fe79f2 ("net: allow gro_max_size to exceed 65536") Reported-by: Sam Dlinn <sledge@meta.com> Signed-off-by: Eric Dumazet <edumazet@google.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 8e68c38 commit 37a5dcd

1 file changed

Lines changed: 2 additions & 1 deletion

File tree

net/core/gro.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,8 +182,9 @@ int skb_gro_receive(struct sk_buff *p, struct sk_buff *skb)
182182

183183
if (unlikely(p->len + len >= GRO_LEGACY_MAX_SIZE)) {
184184
if (p->protocol != htons(ETH_P_IPV6) ||
185-
skb_headroom(p) < sizeof(struct hop_jumbo_hdr) ||
185+
p->mac_header < sizeof(struct hop_jumbo_hdr) ||
186186
ipv6_hdr(p)->nexthdr != IPPROTO_TCP ||
187+
NAPI_GRO_CB(skb)->encap_mark ||
187188
p->encapsulation)
188189
return -E2BIG;
189190
}

0 commit comments

Comments
 (0)