mirror of
https://github.com/torvalds/linux.git
synced 2026-05-27 00:22:00 +02:00
Merge branch 'inet-exceptions-less-predictable'
Eric Dumazet says: ==================== inet: make exception handling less predictible This second round of patches is addressing Keyu Man recommendations to make linux hosts more robust against a class of brute force attacks. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
63cad4c743
|
|
@ -587,18 +587,25 @@ static void fnhe_flush_routes(struct fib_nh_exception *fnhe)
|
|||
}
|
||||
}
|
||||
|
||||
static struct fib_nh_exception *fnhe_oldest(struct fnhe_hash_bucket *hash)
|
||||
static void fnhe_remove_oldest(struct fnhe_hash_bucket *hash)
|
||||
{
|
||||
struct fib_nh_exception *fnhe, *oldest;
|
||||
struct fib_nh_exception __rcu **fnhe_p, **oldest_p;
|
||||
struct fib_nh_exception *fnhe, *oldest = NULL;
|
||||
|
||||
oldest = rcu_dereference(hash->chain);
|
||||
for (fnhe = rcu_dereference(oldest->fnhe_next); fnhe;
|
||||
fnhe = rcu_dereference(fnhe->fnhe_next)) {
|
||||
if (time_before(fnhe->fnhe_stamp, oldest->fnhe_stamp))
|
||||
for (fnhe_p = &hash->chain; ; fnhe_p = &fnhe->fnhe_next) {
|
||||
fnhe = rcu_dereference_protected(*fnhe_p,
|
||||
lockdep_is_held(&fnhe_lock));
|
||||
if (!fnhe)
|
||||
break;
|
||||
if (!oldest ||
|
||||
time_before(fnhe->fnhe_stamp, oldest->fnhe_stamp)) {
|
||||
oldest = fnhe;
|
||||
oldest_p = fnhe_p;
|
||||
}
|
||||
}
|
||||
fnhe_flush_routes(oldest);
|
||||
return oldest;
|
||||
*oldest_p = oldest->fnhe_next;
|
||||
kfree_rcu(oldest, rcu);
|
||||
}
|
||||
|
||||
static u32 fnhe_hashfun(__be32 daddr)
|
||||
|
|
@ -677,16 +684,21 @@ static void update_or_create_fnhe(struct fib_nh_common *nhc, __be32 daddr,
|
|||
if (rt)
|
||||
fill_route_from_fnhe(rt, fnhe);
|
||||
} else {
|
||||
if (depth > FNHE_RECLAIM_DEPTH)
|
||||
fnhe = fnhe_oldest(hash);
|
||||
else {
|
||||
fnhe = kzalloc(sizeof(*fnhe), GFP_ATOMIC);
|
||||
if (!fnhe)
|
||||
goto out_unlock;
|
||||
/* Randomize max depth to avoid some side channels attacks. */
|
||||
int max_depth = FNHE_RECLAIM_DEPTH +
|
||||
prandom_u32_max(FNHE_RECLAIM_DEPTH);
|
||||
|
||||
fnhe->fnhe_next = hash->chain;
|
||||
rcu_assign_pointer(hash->chain, fnhe);
|
||||
while (depth > max_depth) {
|
||||
fnhe_remove_oldest(hash);
|
||||
depth--;
|
||||
}
|
||||
|
||||
fnhe = kzalloc(sizeof(*fnhe), GFP_ATOMIC);
|
||||
if (!fnhe)
|
||||
goto out_unlock;
|
||||
|
||||
fnhe->fnhe_next = hash->chain;
|
||||
|
||||
fnhe->fnhe_genid = genid;
|
||||
fnhe->fnhe_daddr = daddr;
|
||||
fnhe->fnhe_gw = gw;
|
||||
|
|
@ -694,6 +706,8 @@ static void update_or_create_fnhe(struct fib_nh_common *nhc, __be32 daddr,
|
|||
fnhe->fnhe_mtu_locked = lock;
|
||||
fnhe->fnhe_expires = max(1UL, expires);
|
||||
|
||||
rcu_assign_pointer(hash->chain, fnhe);
|
||||
|
||||
/* Exception created; mark the cached routes for the nexthop
|
||||
* stale, so anyone caching it rechecks if this exception
|
||||
* applies to them.
|
||||
|
|
|
|||
|
|
@ -1657,6 +1657,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);
|
||||
|
|
@ -1711,7 +1712,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:
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user