xfrm: move xfrm_garbage_collect out of xfrm_policy_flush
Now we will force to do garbage collection if any policy removed in xfrm_policy_flush(). But during xfrm_net_exit(). We call flow_cache_fini() first and set set fc->percpu to NULL. Then after we call xfrm_policy_fini() -> frxm_policy_flush() -> flow_cache_flush(), we will get NULL pointer dereference when check percpu_empty. The code path looks like: flow_cache_fini() - fc->percpu = NULL xfrm_policy_fini() - xfrm_policy_flush() - xfrm_garbage_collect() - flow_cache_flush() - flow_cache_percpu_empty() - fcp = per_cpu_ptr(fc->percpu, cpu) To reproduce, just add ipsec in netns and then remove the netns. v2: As Xin Long suggested, since only two other places need to call it. move xfrm_garbage_collect() outside xfrm_policy_flush(). v3: Fix subject mismatch after v2 fix. Fixes: 35db06912189 ("xfrm: do the garbage collection after flushing policy") Signed-off-by: Hangbin Liu <liuhangbin@gmail.com> Reviewed-by: Xin Long <lucien.xin@gmail.com> Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
This commit is contained in:
parent
b81f884a54
commit
138437f591
@ -2755,6 +2755,8 @@ static int pfkey_spdflush(struct sock *sk, struct sk_buff *skb, const struct sad
|
||||
int err, err2;
|
||||
|
||||
err = xfrm_policy_flush(net, XFRM_POLICY_TYPE_MAIN, true);
|
||||
if (!err)
|
||||
xfrm_garbage_collect(net);
|
||||
err2 = unicast_flush_resp(sk, hdr);
|
||||
if (err || err2) {
|
||||
if (err == -ESRCH) /* empty table - old silent behavior */
|
||||
|
@ -1006,10 +1006,6 @@ int xfrm_policy_flush(struct net *net, u8 type, bool task_valid)
|
||||
err = -ESRCH;
|
||||
out:
|
||||
spin_unlock_bh(&net->xfrm.xfrm_policy_lock);
|
||||
|
||||
if (cnt)
|
||||
xfrm_garbage_collect(net);
|
||||
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL(xfrm_policy_flush);
|
||||
|
@ -2027,6 +2027,7 @@ static int xfrm_flush_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
|
||||
return 0;
|
||||
return err;
|
||||
}
|
||||
xfrm_garbage_collect(net);
|
||||
|
||||
c.data.type = type;
|
||||
c.event = nlh->nlmsg_type;
|
||||
|
Loading…
x
Reference in New Issue
Block a user