From: Eric Dumazet edumazet@google.com
mainline inclusion from mainline-v5.15-rc1 commit a00df2caffed3883c341d5685f830434312e4a43 category: bugfix bugzilla: NA CVE: CVE-2021-20322
-------------------------------------------------
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: Xu Jia xujia39@huawei.com Reviewed-by: Yue Haibing yuehaibing@huawei.com Reviewed-by: Xiu Jianfeng xiujianfeng@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- net/ipv6/route.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 369f4aaab1334..01f8e62302fab 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -1454,6 +1454,7 @@ static int rt6_insert_exception(struct rt6_info *nrt, struct rt6_exception_bucket *bucket; struct in6_addr *src_key = NULL; struct rt6_exception *rt6_ex; + int max_depth; int err = 0;
spin_lock_bh(&rt6_exception_lock); @@ -1515,7 +1516,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: