diff mbox series

[ipsec] xfrm: don't call xfrm_policy_cache_flush while holding spinlock

Message ID 20180106001308.12765-1-fw@strlen.de
State Awaiting Upstream, archived
Delegated to: David Miller
Headers show
Series [ipsec] xfrm: don't call xfrm_policy_cache_flush while holding spinlock | expand

Commit Message

Florian Westphal Jan. 6, 2018, 12:13 a.m. UTC
xfrm_policy_cache_flush can sleep, so it cannot be called while holding
a spinlock.  We could release the lock first, but I don't see why we need
to invoke this function here in first place, the packet path won't reuse
an xdst entry unless its still valid.

While at it, add an annotation to xfrm_policy_cache_flush, it would
have probably caught this bug sooner.

Fixes: ec30d78c14a813 ("xfrm: add xdst pcpu cache")
Reported-by: syzbot+e149f7d1328c26f9c12f@syzkaller.appspotmail.com
Signed-off-by: Florian Westphal <fw@strlen.de>
---
 net/xfrm/xfrm_policy.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

Comments

Steffen Klassert Jan. 9, 2018, noon UTC | #1
On Sat, Jan 06, 2018 at 01:13:08AM +0100, Florian Westphal wrote:
> xfrm_policy_cache_flush can sleep, so it cannot be called while holding
> a spinlock.  We could release the lock first, but I don't see why we need
> to invoke this function here in first place, the packet path won't reuse
> an xdst entry unless its still valid.
> 
> While at it, add an annotation to xfrm_policy_cache_flush, it would
> have probably caught this bug sooner.
> 
> Fixes: ec30d78c14a813 ("xfrm: add xdst pcpu cache")
> Reported-by: syzbot+e149f7d1328c26f9c12f@syzkaller.appspotmail.com
> Signed-off-by: Florian Westphal <fw@strlen.de>

Applied, thanks a lot!
diff mbox series

Patch

diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index d8a8129b9232..688336cb9956 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -974,8 +974,6 @@  int xfrm_policy_flush(struct net *net, u8 type, bool task_valid)
 	}
 	if (!cnt)
 		err = -ESRCH;
-	else
-		xfrm_policy_cache_flush();
 out:
 	spin_unlock_bh(&net->xfrm.xfrm_policy_lock);
 	return err;
@@ -1744,6 +1742,8 @@  void xfrm_policy_cache_flush(void)
 	bool found = 0;
 	int cpu;
 
+	might_sleep();
+
 	local_bh_disable();
 	rcu_read_lock();
 	for_each_possible_cpu(cpu) {