summaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
authorEric Dumazet2019-03-27 20:40:33 +0100
committerGreg Kroah-Hartman2019-06-04 08:02:30 +0200
commit07480da0c8a1979e0973d6dd783b6aed966dccf6 (patch)
treeaa99b025ee2a5cddefa764fb457fd0aae74c5172 /net/ipv4
parentcxgb4: offload VLAN flows regardless of VLAN ethtype (diff)
downloadkernel-qcow2-linux-07480da0c8a1979e0973d6dd783b6aed966dccf6.tar.gz
kernel-qcow2-linux-07480da0c8a1979e0973d6dd783b6aed966dccf6.tar.xz
kernel-qcow2-linux-07480da0c8a1979e0973d6dd783b6aed966dccf6.zip
inet: switch IP ID generator to siphash
[ Upstream commit df453700e8d81b1bdafdf684365ee2b9431fb702 ] 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> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
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 8bacbcd2db90..40bf19f7ae1a 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -500,15 +500,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);
}