mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 01:32:21 +02:00
Merge branch 'net-fib-fix-two-use-after-free-in-drivers-during-rcu-dump'
Kuniyuki Iwashima says: ==================== net: fib: Fix two use-after-free in drivers during RCU dump. syzbot reported fib_info UAF in netdevsim, and the same bug exists in rocker and mlxsw. Patch 1 fixes it, and Patch 2 fixes the same type of bug of fib_rule. ==================== Link: https://patch.msgid.link/20260610061744.2030996-1-kuniyu@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
c33da0eeca
|
|
@ -111,6 +111,11 @@ static inline void fib_rule_get(struct fib_rule *rule)
|
|||
refcount_inc(&rule->refcnt);
|
||||
}
|
||||
|
||||
static inline bool fib_rule_get_safe(struct fib_rule *rule)
|
||||
{
|
||||
return refcount_inc_not_zero(&rule->refcnt);
|
||||
}
|
||||
|
||||
static inline void fib_rule_put(struct fib_rule *rule)
|
||||
{
|
||||
if (refcount_dec_and_test(&rule->refcnt))
|
||||
|
|
|
|||
|
|
@ -629,6 +629,11 @@ static inline void fib_info_hold(struct fib_info *fi)
|
|||
refcount_inc(&fi->fib_clntref);
|
||||
}
|
||||
|
||||
static inline bool fib_info_hold_safe(struct fib_info *fi)
|
||||
{
|
||||
return refcount_inc_not_zero(&fi->fib_clntref);
|
||||
}
|
||||
|
||||
static inline void fib_info_put(struct fib_info *fi)
|
||||
{
|
||||
if (refcount_dec_and_test(&fi->fib_clntref))
|
||||
|
|
|
|||
|
|
@ -349,7 +349,7 @@ int fib_rules_lookup(struct fib_rules_ops *ops, struct flowi *fl,
|
|||
|
||||
if (err != -EAGAIN) {
|
||||
if ((arg->flags & FIB_LOOKUP_NOREF) ||
|
||||
likely(refcount_inc_not_zero(&rule->refcnt))) {
|
||||
likely(fib_rule_get_safe(rule))) {
|
||||
arg->rule = rule;
|
||||
goto out;
|
||||
}
|
||||
|
|
@ -410,8 +410,12 @@ int fib_rules_dump(struct net *net, struct notifier_block *nb, int family,
|
|||
if (!ops)
|
||||
return -EAFNOSUPPORT;
|
||||
list_for_each_entry_rcu(rule, &ops->rules_list, list) {
|
||||
if (!fib_rule_get_safe(rule))
|
||||
continue;
|
||||
|
||||
err = call_fib_rule_notifier(nb, FIB_EVENT_RULE_ADD,
|
||||
rule, family, extack);
|
||||
fib_rule_put(rule);
|
||||
if (err)
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2172,10 +2172,14 @@ static int fib_leaf_notify(struct key_vector *l, struct fib_table *tb,
|
|||
if (fa->fa_slen == last_slen)
|
||||
continue;
|
||||
|
||||
if (!fib_info_hold_safe(fa->fa_info))
|
||||
continue;
|
||||
|
||||
last_slen = fa->fa_slen;
|
||||
err = call_fib_entry_notifier(nb, FIB_EVENT_ENTRY_REPLACE,
|
||||
l->key, KEYLENGTH - fa->fa_slen,
|
||||
fa, extack);
|
||||
fib_info_put(fa->fa_info);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user