Commit 38d57551 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'inet-siphash'



Eric Dumazet says:

====================
inet: use siphash in exception handling

A group of security researchers brought to our attention
the weakness of hash functions used in rt6_exception_hash()
and fnhe_hashfun()

I made two distinct patches to help backports, since IPv6
part was added in 4.15
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 92ea47fe 6457378f
Loading
Loading
Loading
Loading
+6 −6
Original line number Diff line number Diff line
@@ -600,14 +600,14 @@ static struct fib_nh_exception *fnhe_oldest(struct fnhe_hash_bucket *hash)
	return oldest;
}

static inline u32 fnhe_hashfun(__be32 daddr)
static u32 fnhe_hashfun(__be32 daddr)
{
	static u32 fnhe_hashrnd __read_mostly;
	u32 hval;
	static siphash_key_t fnhe_hash_key __read_mostly;
	u64 hval;

	net_get_random_once(&fnhe_hashrnd, sizeof(fnhe_hashrnd));
	hval = jhash_1word((__force u32)daddr, fnhe_hashrnd);
	return hash_32(hval, FNHE_HASH_SHIFT);
	net_get_random_once(&fnhe_hash_key, sizeof(fnhe_hash_key));
	hval = siphash_1u32((__force u32)daddr, &fnhe_hash_key);
	return hash_64(hval, FNHE_HASH_SHIFT);
}

static void fill_route_from_fnhe(struct rtable *rt, struct fib_nh_exception *fnhe)
+14 −6
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@
#include <linux/nsproxy.h>
#include <linux/slab.h>
#include <linux/jhash.h>
#include <linux/siphash.h>
#include <net/net_namespace.h>
#include <net/snmp.h>
#include <net/ipv6.h>
@@ -1484,17 +1485,24 @@ static void rt6_exception_remove_oldest(struct rt6_exception_bucket *bucket)
static u32 rt6_exception_hash(const struct in6_addr *dst,
			      const struct in6_addr *src)
{
	static u32 seed __read_mostly;
	u32 val;
	static siphash_key_t rt6_exception_key __read_mostly;
	struct {
		struct in6_addr dst;
		struct in6_addr src;
	} __aligned(SIPHASH_ALIGNMENT) combined = {
		.dst = *dst,
	};
	u64 val;

	net_get_random_once(&seed, sizeof(seed));
	val = jhash2((const u32 *)dst, sizeof(*dst)/sizeof(u32), seed);
	net_get_random_once(&rt6_exception_key, sizeof(rt6_exception_key));

#ifdef CONFIG_IPV6_SUBTREES
	if (src)
		val = jhash2((const u32 *)src, sizeof(*src)/sizeof(u32), val);
		combined.src = *src;
#endif
	return hash_32(val, FIB6_EXCEPTION_BUCKET_SIZE_SHIFT);
	val = siphash(&combined, sizeof(combined), &rt6_exception_key);

	return hash_64(val, FIB6_EXCEPTION_BUCKET_SIZE_SHIFT);
}

/* Helper function to find the cached rt in the hash table