summaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
authorEric Dumazet <edumazet@google.com>2019-03-27 12:40:33 -0700
committerBen Hutchings <ben@decadent.org.uk>2019-08-13 12:39:32 +0100
commit9ebeec41ed3f52fd94267f25f8b9bf3f4cbf1e4e (patch)
tree3b2bdfa126461196bb4d35d0830b4566a61358a1 /net/ipv4
parenta78ff0010f999bc2b0346ec2a89896af3f5c2ca8 (diff)
downloadlinux-stable-9ebeec41ed3f52fd94267f25f8b9bf3f4cbf1e4e.tar.gz
linux-stable-9ebeec41ed3f52fd94267f25f8b9bf3f4cbf1e4e.tar.bz2
linux-stable-9ebeec41ed3f52fd94267f25f8b9bf3f4cbf1e4e.zip
inet: switch IP ID generator to siphash
commit df453700e8d81b1bdafdf684365ee2b9431fb702 upstream. According to Amit Klein and Benny Pinkas, IP ID generation is too weak and might be used by attackers. Even with recent net_hash_mix() fix (netns: provide pure entropy for net_hash_mix()) having 64bit key and Jenkins hash is risky. It is time to switch to siphash and its 128bit keys. Signed-off-by: Eric Dumazet <edumazet@google.com> Reported-by: Amit Klein <aksecurity@gmail.com> Reported-by: Benny Pinkas <benny@pinkas.net> Signed-off-by: David S. Miller <davem@davemloft.net> [bwh: Backported to 3.16: adjust context] Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/route.c12
1 files changed, 7 insertions, 5 deletions
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 5092304f31fb..858596c80e0e 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -486,15 +486,17 @@ EXPORT_SYMBOL(ip_idents_reserve);
void __ip_select_ident(struct net *net, struct iphdr *iph, int segs)
{
- static u32 ip_idents_hashrnd __read_mostly;
u32 hash, id;
- net_get_random_once(&ip_idents_hashrnd, sizeof(ip_idents_hashrnd));
+ /* Note the following code is not safe, but this is okay. */
+ if (unlikely(siphash_key_is_zero(&net->ipv4.ip_id_key)))
+ get_random_bytes(&net->ipv4.ip_id_key,
+ sizeof(net->ipv4.ip_id_key));
- hash = jhash_3words((__force u32)iph->daddr,
+ hash = siphash_3u32((__force u32)iph->daddr,
(__force u32)iph->saddr,
- iph->protocol ^ net_hash_mix(net),
- ip_idents_hashrnd);
+ iph->protocol,
+ &net->ipv4.ip_id_key);
id = ip_idents_reserve(hash, segs);
iph->id = htons(id);
}