Skip to content

Commit c53484a

Browse files
edumazetshiloong
authored andcommitted
ipv4: avoid using shared IP generator for connected sockets
ANBZ: torvalds#628 commit 23f5740 upstream. ip_select_ident_segs() has been very conservative about using the connected socket private generator only for packets with IP_DF set, claiming it was needed for some VJ compression implementations. As mentioned in this referenced document, this can be abused. (Ref: Off-Path TCP Exploits of the Mixed IPID Assignment) Before switching to pure random IPID generation and possibly hurt some workloads, lets use the private inet socket generator. Not only this will remove one vulnerability, this will also improve performance of TCP flows using pmtudisc==IP_PMTUDISC_DONT Fixes: 73f156a ("inetpeer: get rid of ip_id_count") Signed-off-by: Eric Dumazet <edumazet@google.com> Reviewed-by: David Ahern <dsahern@kernel.org> Reported-by: Ray Che <xijiache@gmail.com> Cc: Willy Tarreau <w@1wt.eu> Signed-off-by: Jakub Kicinski <kuba@kernel.org> Fixes: CVE-2020-36516 Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com> Acked-by: Dust Li <dust.li@linux.alibaba.com>
1 parent 139a3d3 commit c53484a

File tree

1 file changed

+10
-11
lines changed

1 file changed

+10
-11
lines changed

include/net/ip.h

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -431,19 +431,18 @@ static inline void ip_select_ident_segs(struct net *net, struct sk_buff *skb,
431431
{
432432
struct iphdr *iph = ip_hdr(skb);
433433

434+
/* We had many attacks based on IPID, use the private
435+
* generator as much as we can.
436+
*/
437+
if (sk && inet_sk(sk)->inet_daddr) {
438+
iph->id = htons(inet_sk(sk)->inet_id);
439+
inet_sk(sk)->inet_id += segs;
440+
return;
441+
}
434442
if ((iph->frag_off & htons(IP_DF)) && !skb->ignore_df) {
435-
/* This is only to work around buggy Windows95/2000
436-
* VJ compression implementations. If the ID field
437-
* does not change, they drop every other packet in
438-
* a TCP stream using header compression.
439-
*/
440-
if (sk && inet_sk(sk)->inet_daddr) {
441-
iph->id = htons(inet_sk(sk)->inet_id);
442-
inet_sk(sk)->inet_id += segs;
443-
} else {
444-
iph->id = 0;
445-
}
443+
iph->id = 0;
446444
} else {
445+
/* Unfortunately we need the big hammer to get a suitable IPID */
447446
__ip_select_ident(net, iph, segs);
448447
}
449448
}

0 commit comments

Comments
 (0)