summaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
authorEric Dumazet <edumazet@google.com>2019-11-01 10:32:19 -0700
committerBen Hutchings <ben@decadent.org.uk>2019-12-19 15:58:53 +0000
commitc1fb8e44ba97f8589b7fc5137e4b45561a27dcc5 (patch)
tree4ce65c7d133529495da05f7951935a7fab1d0d1a /net/ipv4
parentc97d5d87f654979c81a36fbd75844a41e5a82cdc (diff)
downloadlinux-stable-c1fb8e44ba97f8589b7fc5137e4b45561a27dcc5.tar.gz
linux-stable-c1fb8e44ba97f8589b7fc5137e4b45561a27dcc5.tar.bz2
linux-stable-c1fb8e44ba97f8589b7fc5137e4b45561a27dcc5.zip
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> [bwh: Backported to 3.16: drop changes in chelsio] Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/datagram.c2
-rw-r--r--net/ipv4/tcp_ipv4.c4
2 files changed, 3 insertions, 3 deletions
diff --git a/net/ipv4/datagram.c b/net/ipv4/datagram.c
index f0c307cb6196..eaddffcbe654 100644
--- a/net/ipv4/datagram.c
+++ b/net/ipv4/datagram.c
@@ -74,7 +74,7 @@ int __ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len
inet->inet_daddr = fl4->daddr;
inet->inet_dport = usin->sin_port;
sk->sk_state = TCP_ESTABLISHED;
- 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 201a2d9aebd7..d3a4cb33f5f0 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -241,7 +241,7 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
inet->inet_sport,
usin->sin_port);
- inet->inet_id = tp->write_seq ^ jiffies;
+ inet->inet_id = prandom_u32();
err = tcp_connect(sk);
@@ -1449,7 +1449,7 @@ struct sock *tcp_v4_syn_recv_sock(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);