| From 72e16d7c131f540829e19b8271f1f95e6b7a1002 Mon Sep 17 00:00:00 2001 |
| From: Eric Dumazet <edumazet@google.com> |
| Date: Fri, 1 Nov 2019 10:32:19 -0700 |
| Subject: [PATCH] inet: stop leaking jiffies on the wire |
| |
| commit a904a0693c189691eeee64f6c6b188bd7dc244e9 upstream. |
| |
| Historically linux tried to stick to RFC 791, 1122, 2003 |
| for IPv4 ID field generation. |
| |
| RFC 6864 made clear that no matter how hard we try, |
| we can not ensure unicity of IP ID within maximum |
| lifetime for all datagrams with a given source |
| address/destination address/protocol tuple. |
| |
| Linux uses a per socket inet generator (inet_id), initialized |
| at connection startup with a XOR of 'jiffies' and other |
| fields that appear clear on the wire. |
| |
| Thiemo Nagel pointed that this strategy is a privacy |
| concern as this provides 16 bits of entropy to fingerprint |
| devices. |
| |
| Let's switch to a random starting point, this is just as |
| good as far as RFC 6864 is concerned and does not leak |
| anything critical. |
| |
| Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") |
| Signed-off-by: Eric Dumazet <edumazet@google.com> |
| Reported-by: Thiemo Nagel <tnagel@google.com> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/drivers/crypto/chelsio/chtls/chtls_cm.c b/drivers/crypto/chelsio/chtls/chtls_cm.c |
| index 774d991d7cca..aca75237bbcf 100644 |
| --- a/drivers/crypto/chelsio/chtls/chtls_cm.c |
| +++ b/drivers/crypto/chelsio/chtls/chtls_cm.c |
| @@ -1297,7 +1297,7 @@ static void make_established(struct sock *sk, u32 snd_isn, unsigned int opt) |
| tp->write_seq = snd_isn; |
| tp->snd_nxt = snd_isn; |
| tp->snd_una = snd_isn; |
| - inet_sk(sk)->inet_id = tp->write_seq ^ jiffies; |
| + inet_sk(sk)->inet_id = prandom_u32(); |
| assign_rxopt(sk, opt); |
| |
| if (tp->rcv_wnd > (RCV_BUFSIZ_M << 10)) |
| diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c |
| index 6791eb9d4f16..6b8a602849dd 100644 |
| --- a/net/dccp/ipv4.c |
| +++ b/net/dccp/ipv4.c |
| @@ -117,7 +117,7 @@ int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) |
| inet->inet_daddr, |
| inet->inet_sport, |
| inet->inet_dport); |
| - inet->inet_id = dp->dccps_iss ^ jiffies; |
| + inet->inet_id = prandom_u32(); |
| |
| err = dccp_connect(sk); |
| rt = NULL; |
| diff --git a/net/ipv4/datagram.c b/net/ipv4/datagram.c |
| index 9a0fe0c2fa02..4a8550c49202 100644 |
| --- a/net/ipv4/datagram.c |
| +++ b/net/ipv4/datagram.c |
| @@ -73,7 +73,7 @@ int __ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len |
| reuseport_has_conns(sk, true); |
| sk->sk_state = TCP_ESTABLISHED; |
| sk_set_txhash(sk); |
| - inet->inet_id = jiffies; |
| + inet->inet_id = prandom_u32(); |
| |
| sk_dst_set(sk, &rt->dst); |
| err = 0; |
| diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c |
| index cfa81190a1b1..e47341ba215d 100644 |
| --- a/net/ipv4/tcp_ipv4.c |
| +++ b/net/ipv4/tcp_ipv4.c |
| @@ -300,7 +300,7 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) |
| inet->inet_daddr); |
| } |
| |
| - inet->inet_id = tp->write_seq ^ jiffies; |
| + inet->inet_id = prandom_u32(); |
| |
| if (tcp_fastopen_defer_connect(sk, &err)) |
| return err; |
| @@ -1437,7 +1437,7 @@ struct sock *tcp_v4_syn_recv_sock(const struct sock *sk, struct sk_buff *skb, |
| inet_csk(newsk)->icsk_ext_hdr_len = 0; |
| if (inet_opt) |
| inet_csk(newsk)->icsk_ext_hdr_len = inet_opt->opt.optlen; |
| - newinet->inet_id = newtp->write_seq ^ jiffies; |
| + newinet->inet_id = prandom_u32(); |
| |
| if (!dst) { |
| dst = inet_csk_route_child_sock(sk, newsk, req); |
| diff --git a/net/sctp/socket.c b/net/sctp/socket.c |
| index 34ad7445db13..4966c88cd7f8 100644 |
| --- a/net/sctp/socket.c |
| +++ b/net/sctp/socket.c |
| @@ -9161,7 +9161,7 @@ void sctp_copy_sock(struct sock *newsk, struct sock *sk, |
| newinet->inet_rcv_saddr = inet->inet_rcv_saddr; |
| newinet->inet_dport = htons(asoc->peer.port); |
| newinet->pmtudisc = inet->pmtudisc; |
| - newinet->inet_id = asoc->next_tsn ^ jiffies; |
| + newinet->inet_id = prandom_u32(); |
| |
| newinet->uc_ttl = inet->uc_ttl; |
| newinet->mc_loop = 1; |
| -- |
| 2.7.4 |
| |