mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 17:47:41 +02:00
tcp: ipv6: clamp default adverting MSS to avoid GSO_BY_FRAGS (0xFFFF)
When MTU is large, ip6_default_advmss() can return IPV6_MAXPLEN (65535).
This is interpreted by TCP as mss_clamp, allowing the MSS to reach 65535.
However, 0xFFFF is also used as a magic value GSO_BY_FRAGS in the kernel.
If a TCP packet with gso_size=0xFFFF is passed to skb_segment(), it will
be mistakenly treated as GSO_BY_FRAGS, leading to a NULL pointer
dereference because local TCP packets do not use frag_list.
Fix this by returning min(IPV6_MAXPLEN, GSO_BY_FRAGS - 1) (65534) from
ip6_default_advmss() when MTU is large.
Also update the stale comment in ip6_default_advmss() which suggested
that IPV6_MAXPLEN is returned to mean "any MSS".
Fixes: 3953c46c3a ("sk_buff: allow segmenting based on frag sizes")
Reported-by: syzbot+ebdb22d461c904fc3cb2@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/netdev/6a2c3193.8812e0fc.3c3fa4.0001.GAE@google.com/T/#u
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
Link: https://patch.msgid.link/20260612162517.83394-1-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
f4c3d89fc9
commit
2bf43d0e2e
|
|
@ -3275,11 +3275,11 @@ static unsigned int ip6_default_advmss(const struct dst_entry *dst)
|
|||
/*
|
||||
* Maximal non-jumbo IPv6 payload is IPV6_MAXPLEN and
|
||||
* corresponding MSS is IPV6_MAXPLEN - tcp_header_size.
|
||||
* IPV6_MAXPLEN is also valid and means: "any MSS,
|
||||
* rely only on pmtu discovery"
|
||||
* Limit the default MSS to GSO_BY_FRAGS - 1 to avoid
|
||||
* collision with the GSO_BY_FRAGS magic value (0xFFFF).
|
||||
*/
|
||||
if (mtu > IPV6_MAXPLEN - sizeof(struct tcphdr))
|
||||
mtu = IPV6_MAXPLEN;
|
||||
mtu = min_t(unsigned int, IPV6_MAXPLEN, GSO_BY_FRAGS - 1);
|
||||
return mtu;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user