xfrm: input: hold netns during deferred transport reinjection
Subsystems (3)
A message that is not in the archive (sent off-list or not yet received): [email protected]
PATCH 1/1 xfrm: input: hold netns during deferred transport reinjection
From: Zhengchuan Liang <[email protected]>
Transport-mode reinjection stores a struct net pointer in skb->cb and uses it later from xfrm_trans_reinject(). That pointer must stay valid until the deferred callback runs.
Take a netns reference when queueing deferred reinjection work and drop it after the callback completes. Use maybe_get_net() so the queueing path does not revive a namespace that is already being torn down.
This keeps the existing workqueue design and fixes the netns lifetime handling in one place for all users of xfrm_trans_queue_net().
--- net/xfrm/xfrm_input.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-)
net/xfrm/xfrm_input.c +12 -4
@@ -797,9 +797,12 @@ static void xfrm_trans_reinject(struct work_struct *work)spin_unlock_bh (&trans->queue_lock);local_bh_disable (); -while ((skb =__skb_dequeue (&queue))) -XFRM_TRANS_SKB_CB (skb)->finish (XFRM_TRANS_SKB_CB (skb)->net, -NULL , skb); +while ((skb =__skb_dequeue (&queue))) { +struct net *net =XFRM_TRANS_SKB_CB (skb)->net; + +XFRM_TRANS_SKB_CB (skb)->finish (net,NULL , skb); +put_net (net); + }local_bh_enable (); }
@@ -807,6 +810,7 @@ int xfrm_trans_queue_net(struct net *net, struct sk_buff *skb,int (*finish)(struct net *,struct sock *, struct sk_buff *)) {struct xfrm_trans_tasklet *trans; +struct net *hold_net; trans =this_cpu_ptr (&xfrm_trans_tasklet);
@@ -816,8 +820,12 @@ int xfrm_trans_queue_net(struct net *net, struct sk_buff *skb,BUILD_BUG_ON (sizeof (struct xfrm_trans_cb ) >sizeof (skb->cb)); + hold_net =maybe_get_net (net); +if (!hold_net) +return -ENODEV ; +XFRM_TRANS_SKB_CB (skb)->finish = finish; -XFRM_TRANS_SKB_CB (skb)->net = net; +XFRM_TRANS_SKB_CB (skb)->net = hold_net;spin_lock_bh (&trans->queue_lock);__skb_queue_tail (&trans->queue, skb);spin_unlock_bh (&trans->queue_lock);
Signature · 1 line
2.47.3
Quoted 13 lines · Ren Wei
From: Zhengchuan Liang <[email protected]>
Transport-mode reinjection stores a struct net pointer in
skb->cband uses it later fromxfrm_trans_reinject(). That pointer must stay valid until the deferred callback runs.Take a netns reference when queueing deferred reinjection work and drop it after the callback completes. Use
maybe_get_net()so the queueing path does not revive a namespace that is already being torn down.This keeps the existing workqueue design and fixes the netns lifetime handling in one place for all users of
xfrm_trans_queue_net().
Quoted 9 lines
Fixes 7b3801927e52 ("xfrm: introduce xfrm_trans_queue_net")Reported-by Yuan Tan <[email protected]>Reported-by Xin Liu <[email protected]>Co-developed-by Luxing Yin <[email protected]>Signed-off-by Luxing Yin <[email protected]>Signed-off-by Zhengchuan Liang <[email protected]>Signed-off-by Ren Wei <[email protected]>Assisted-by Codex:gpt-5.4
Applied, thanks a lot!