diff options
| author | Eric Dumazet <edumazet@google.com> | 2021-08-29 15:16:14 -0700 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2021-11-02 18:26:44 +0100 |
| commit | c6d0d68d6da68159948cad3d808d61bb291a0283 (patch) | |
| tree | 1e5ed07880c75a11ccef3da01ef78a85701df1e0 | |
| parent | ad829847ad59af8e26a1f1c345716099abbc7a58 (diff) | |
| download | linux-c6d0d68d6da68159948cad3d808d61bb291a0283.tar.gz linux-c6d0d68d6da68159948cad3d808d61bb291a0283.tar.bz2 linux-c6d0d68d6da68159948cad3d808d61bb291a0283.zip | |
ipv6: make exception cache less predictible
commit a00df2caffed3883c341d5685f830434312e4a43 upstream.
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>
[OP: adjusted context for 4.19 stable]
Signed-off-by: Ovidiu Panait <ovidiu.panait@windriver.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
| -rw-r--r-- | net/ipv6/route.c | 5 |
1 files changed, 4 insertions, 1 deletions
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 9bc806a4ded6..d04f3951c5fb 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: |
