| From foo@baz Wed 06 Nov 2019 04:08:37 PM CET |
| From: Eric Dumazet <edumazet@google.com> |
| Date: Fri, 1 Nov 2019 10:32:19 -0700 |
| Subject: inet: stop leaking jiffies on the wire |
| |
| From: Eric Dumazet <edumazet@google.com> |
| |
| [ Upstream commit a904a0693c189691eeee64f6c6b188bd7dc244e9 ] |
| |
| 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: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| net/dccp/ipv4.c | 2 +- |
| net/ipv4/datagram.c | 2 +- |
| net/ipv4/tcp_ipv4.c | 4 ++-- |
| net/sctp/socket.c | 2 +- |
| 4 files changed, 5 insertions(+), 5 deletions(-) |
| |
| --- a/net/dccp/ipv4.c |
| +++ b/net/dccp/ipv4.c |
| @@ -121,7 +121,7 @@ int dccp_v4_connect(struct sock *sk, str |
| 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; |
| --- a/net/ipv4/datagram.c |
| +++ b/net/ipv4/datagram.c |
| @@ -75,7 +75,7 @@ int __ip4_datagram_connect(struct sock * |
| inet->inet_dport = usin->sin_port; |
| 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; |
| --- a/net/ipv4/tcp_ipv4.c |
| +++ b/net/ipv4/tcp_ipv4.c |
| @@ -245,7 +245,7 @@ int tcp_v4_connect(struct sock *sk, stru |
| inet->inet_daddr); |
| } |
| |
| - inet->inet_id = tp->write_seq ^ jiffies; |
| + inet->inet_id = prandom_u32(); |
| |
| if (tcp_fastopen_defer_connect(sk, &err)) |
| return err; |
| @@ -1368,7 +1368,7 @@ struct sock *tcp_v4_syn_recv_sock(const |
| 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); |
| --- a/net/sctp/socket.c |
| +++ b/net/sctp/socket.c |
| @@ -8136,7 +8136,7 @@ void sctp_copy_sock(struct sock *newsk, |
| 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; |