mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 17:47:41 +02:00
xfrm: policy: fix use-after-free on inexact bin in xfrm_policy_bysel_ctx()
Fix the race by pruning the bin while still holding xfrm_policy_lock,
before dropping it. Use __xfrm_policy_inexact_prune_bin() directly since
the lock is already held. The wrapper xfrm_policy_inexact_prune_bin()
becomes unused and is removed.
Race:
CPU0 (XFRM_MSG_DELPOLICY) CPU1 (XFRM_MSG_NEWSPDINFO)
========================== ==========================
xfrm_policy_bysel_ctx():
spin_lock_bh(xfrm_policy_lock)
bin = xfrm_policy_inexact_lookup()
__xfrm_policy_unlink(pol)
spin_unlock_bh(xfrm_policy_lock)
xfrm_policy_kill(ret)
// wide window, lock not held
xfrm_hash_rebuild():
spin_lock_bh(xfrm_policy_lock)
__xfrm_policy_inexact_flush():
kfree_rcu(bin) // bin freed
spin_unlock_bh(xfrm_policy_lock)
xfrm_policy_inexact_prune_bin(bin)
// UAF: bin is freed
Fixes: 6be3b0db6d ("xfrm: policy: add inexact policy search tree infrastructure")
Signed-off-by: Sanghyun Park <sanghyun.park.cnu@gmail.com>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
This commit is contained in:
parent
eb48730bb8
commit
7f2d76c9c0
|
|
@ -1156,15 +1156,6 @@ static void __xfrm_policy_inexact_prune_bin(struct xfrm_pol_inexact_bin *b, bool
|
|||
}
|
||||
}
|
||||
|
||||
static void xfrm_policy_inexact_prune_bin(struct xfrm_pol_inexact_bin *b)
|
||||
{
|
||||
struct net *net = read_pnet(&b->k.net);
|
||||
|
||||
spin_lock_bh(&net->xfrm.xfrm_policy_lock);
|
||||
__xfrm_policy_inexact_prune_bin(b, false);
|
||||
spin_unlock_bh(&net->xfrm.xfrm_policy_lock);
|
||||
}
|
||||
|
||||
static void __xfrm_policy_inexact_flush(struct net *net)
|
||||
{
|
||||
struct xfrm_pol_inexact_bin *bin, *t;
|
||||
|
|
@ -1707,12 +1698,12 @@ xfrm_policy_bysel_ctx(struct net *net, const struct xfrm_mark *mark, u32 if_id,
|
|||
}
|
||||
ret = pol;
|
||||
}
|
||||
if (bin && delete)
|
||||
__xfrm_policy_inexact_prune_bin(bin, false);
|
||||
spin_unlock_bh(&net->xfrm.xfrm_policy_lock);
|
||||
|
||||
if (ret && delete)
|
||||
xfrm_policy_kill(ret);
|
||||
if (bin && delete)
|
||||
xfrm_policy_inexact_prune_bin(bin);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(xfrm_policy_bysel_ctx);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user