summaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
authorEric Dumazet <edumazet@google.com>2021-08-29 15:16:14 -0700
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2021-09-15 09:50:45 +0200
commit8692f0bb29927d13a871b198adff1d336a8d2d00 (patch)
tree01be5c3c03168d17c8feba5db7a6c408368b7e35 /net/ipv6
parent4663aaef24dffd004fa030b7434de7a7e9a34f26 (diff)
downloadlinux-stable-8692f0bb29927d13a871b198adff1d336a8d2d00.tar.gz
linux-stable-8692f0bb29927d13a871b198adff1d336a8d2d00.tar.bz2
linux-stable-8692f0bb29927d13a871b198adff1d336a8d2d00.zip
ipv6: make exception cache less predictible
[ Upstream commit a00df2caffed3883c341d5685f830434312e4a43 ] Even after commit 4785305c05b2 ("ipv6: use siphash in rt6_exception_hash()"), an attacker can still use brute force to learn some secrets from a victim linux host. One way to defeat these attacks is to make the max depth of the hash table bucket a random value. Before this patch, each bucket of the hash table used to store exceptions could contain 6 items under attack. After the patch, each bucket would contains a random number of items, between 6 and 10. The attacker can no longer infer secrets. This is slightly increasing memory size used by the hash table, we do not expect this to be a problem. Following patch is dealing with the same issue in 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> Reviewed-by: David Ahern <dsahern@kernel.org> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/route.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index bcf4fae83a9b..168a7b4d957a 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -1655,6 +1655,7 @@ static int rt6_insert_exception(struct rt6_info *nrt,
struct in6_addr *src_key = NULL;
struct rt6_exception *rt6_ex;
struct fib6_nh *nh = res->nh;
+ int max_depth;
int err = 0;
spin_lock_bh(&rt6_exception_lock);
@@ -1709,7 +1710,9 @@ static int rt6_insert_exception(struct rt6_info *nrt,
bucket->depth++;
net->ipv6.rt6_stats->fib_rt_cache++;
- if (bucket->depth > FIB6_MAX_DEPTH)
+ /* Randomize max depth to avoid some side channels attacks. */
+ max_depth = FIB6_MAX_DEPTH + prandom_u32_max(FIB6_MAX_DEPTH);
+ while (bucket->depth > max_depth)
rt6_exception_remove_oldest(bucket);
out: