| From foo@baz Fri Oct 29 09:38:21 AM CEST 2021 |
| From: Ovidiu Panait <ovidiu.panait@windriver.com> |
| Date: Thu, 28 Oct 2021 20:56:30 +0300 |
| Subject: ipv6: use siphash in rt6_exception_hash() |
| To: stable@vger.kernel.org |
| Message-ID: <20211028175631.1803277-2-ovidiu.panait@windriver.com> |
| |
| From: Eric Dumazet <edumazet@google.com> |
| |
| commit 4785305c05b25a242e5314cc821f54ade4c18810 upstream. |
| |
| A group of security researchers brought to our attention |
| the weakness of hash function used in rt6_exception_hash() |
| |
| Lets use siphash instead of Jenkins Hash, to considerably |
| reduce security risks. |
| |
| Following patch deals with IPv4. |
| |
| Fixes: 35732d01fe31 ("ipv6: introduce a hash table to store dst cache") |
| Signed-off-by: Eric Dumazet <edumazet@google.com> |
| Reported-by: Keyu Man <kman001@ucr.edu> |
| Cc: Wei Wang <weiwan@google.com> |
| Cc: Martin KaFai Lau <kafai@fb.com> |
| Acked-by: Wei Wang <weiwan@google.com> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| [OP: adjusted context for 5.4 stable] |
| Signed-off-by: Ovidiu Panait <ovidiu.panait@windriver.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| net/ipv6/route.c | 20 ++++++++++++++------ |
| 1 file changed, 14 insertions(+), 6 deletions(-) |
| |
| --- a/net/ipv6/route.c |
| +++ b/net/ipv6/route.c |
| @@ -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> |
| @@ -1502,17 +1503,24 @@ static void rt6_exception_remove_oldest( |
| 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 = jhash(dst, sizeof(*dst), seed); |
| + net_get_random_once(&rt6_exception_key, sizeof(rt6_exception_key)); |
| |
| #ifdef CONFIG_IPV6_SUBTREES |
| if (src) |
| - val = jhash(src, sizeof(*src), 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 |