Messages in this thread Patch in this message | | | From | Joerg Vehlow <> | Subject | [PATCH] xfrm_input: Protect queue with lock | Date | Mon, 9 Sep 2019 10:37:00 +0200 |
| |
From: Joerg Vehlow <joerg.vehlow@aox-tech.de>
During the skb_queue_splice_init the tasklet could have been preempted and __skb_queue_tail called, which led to an inconsistent queue.
Signed-off-by: Joerg Vehlow <joerg.vehlow@aox-tech.de> --- net/xfrm/xfrm_input.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c index 790b514f86b6..4c4e669fcd16 100644 --- a/net/xfrm/xfrm_input.c +++ b/net/xfrm/xfrm_input.c @@ -512,12 +512,15 @@ EXPORT_SYMBOL(xfrm_input_resume); static void xfrm_trans_reinject(unsigned long data) { + unsigned long flags; struct xfrm_trans_tasklet *trans = (void *)data; struct sk_buff_head queue; struct sk_buff *skb; __skb_queue_head_init(&queue); + spin_lock_irqsave(&trans->queue.lock, flags); skb_queue_splice_init(&trans->queue, &queue); + spin_unlock_irqrestore(&trans->queue.lock, flags); while ((skb = __skb_dequeue(&queue))) XFRM_TRANS_SKB_CB(skb)->finish(dev_net(skb->dev), NULL, skb); @@ -535,7 +538,7 @@ int xfrm_trans_queue(struct sk_buff *skb, return -ENOBUFS; XFRM_TRANS_SKB_CB(skb)->finish = finish; - __skb_queue_tail(&trans->queue, skb); + skb_queue_tail(&trans->queue, skb); tasklet_schedule(&trans->tasklet); return 0; } @@ -560,7 +563,7 @@ void __init xfrm_input_init(void) struct xfrm_trans_tasklet *trans; trans = &per_cpu(xfrm_trans_tasklet, i); - __skb_queue_head_init(&trans->queue); + skb_queue_head_init(&trans->queue); tasklet_init(&trans->tasklet, xfrm_trans_reinject, (unsigned long)trans); } -- 2.20.1
| |