Patch 355b98553789b646ed97ad801a619ff898471b92 makes net_hash_mix() return true 32 bits of entropy. When used in the IP ID generation algorithm, this has the effect of extending the IP ID generation key from 32 bits to 64 bits. However, net_hash_mix() is only used for IP ID generation starting with kernel version 4.1. Therefore, earlier kernels remain with 32-bit key. The patch addresses this issue by explicitly extending the key to 64 bits for kernels v<4.1.
Signed-off-by: Amit Klein aksecurity@gmail.com --- net/ipv4/route.c | 4 +++- net/ipv6/ip6_output.c | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index ede610a4abc8..446b6d202643 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -488,13 +488,15 @@ EXPORT_SYMBOL(ip_idents_reserve); void __ip_select_ident(struct iphdr *iph, int segs) { static u32 ip_idents_hashrnd __read_mostly; + static u32 ip_idents_hashrnd_extra __read_mostly; u32 hash, id;
net_get_random_once(&ip_idents_hashrnd, sizeof(ip_idents_hashrnd)); + net_get_random_once(&ip_idents_hashrnd_extra, sizeof(ip_idents_hashrnd_extra));
hash = jhash_3words((__force u32)iph->daddr, (__force u32)iph->saddr, - iph->protocol, + iph->protocol^ip_idents_hashrnd_extra, ip_idents_hashrnd); id = ip_idents_reserve(hash, segs); iph->id = htons(id); diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 2b69a4b965ed..58e507a79cdd 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -546,12 +546,15 @@ static void ip6_copy_metadata(struct sk_buff *to, struct sk_buff *from) static void ipv6_select_ident(struct frag_hdr *fhdr, struct rt6_info *rt) { static u32 ip6_idents_hashrnd __read_mostly; + static u32 ip6_idents_hashrnd_extra __read_mostly; u32 hash, id;
net_get_random_once(&ip6_idents_hashrnd, sizeof(ip6_idents_hashrnd)); + net_get_random_once(&ip6_idents_hashrnd_extra, sizeof(ip6_idents_hashrnd_extra));
hash = __ipv6_addr_jhash(&rt->rt6i_dst.addr, ip6_idents_hashrnd); hash = __ipv6_addr_jhash(&rt->rt6i_src.addr, hash); + hash = jhash_1word(hash,ip6_idents_hashrnd_extra);
id = ip_idents_reserve(hash, 1); fhdr->identification = htonl(id);
On Thu, Apr 18, 2019 at 09:07:11PM +0000, Amit Klein wrote:
Patch 355b98553789b646ed97ad801a619ff898471b92 makes net_hash_mix() return true 32 bits of entropy. When used in the IP ID generation algorithm, this has the effect of extending the IP ID generation key from 32 bits to 64 bits. However, net_hash_mix() is only used for IP ID generation starting with kernel version 4.1. Therefore, earlier kernels remain with 32-bit key. The patch addresses this issue by explicitly extending the key to 64 bits for kernels v<4.1.
Signed-off-by: Amit Klein aksecurity@gmail.com
net/ipv4/route.c | 4 +++- net/ipv6/ip6_output.c | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-)
I've queued this patch up for the next 3.18.y release, which should happen sometime next week or so. I've cc:ed Ben on the patch as well, so that he can pick it up for the next 3.16.y release. Those usually only happen every other month it seems.
thanks, again for doing this!
greg k-h
linux-stable-mirror@lists.linaro.org