[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20220902121406.246311198@linuxfoundation.org>
Date: Fri, 2 Sep 2022 14:19:26 +0200
From: Greg Kroah-Hartman <gregkh@...uxfoundation.org>
To: linux-kernel@...r.kernel.org
Cc: Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
stable@...r.kernel.org, "Denis V. Lunev" <den@...nvz.org>,
Yang Yingliang <yangyingliang@...wei.com>,
Nikolay Aleksandrov <razor@...ckwall.org>,
"David S. Miller" <davem@...emloft.net>
Subject: [PATCH 5.4 77/77] net: neigh: dont call kfree_skb() under spin_lock_irqsave()
From: Yang Yingliang <yangyingliang@...wei.com>
commit d5485d9dd24e1d04e5509916515260186eb1455c upstream.
It is not allowed to call kfree_skb() from hardware interrupt
context or with interrupts being disabled. So add all skb to
a tmp list, then free them after spin_unlock_irqrestore() at
once.
Fixes: 66ba215cb513 ("neigh: fix possible DoS due to net iface start/stop loop")
Suggested-by: Denis V. Lunev <den@...nvz.org>
Signed-off-by: Yang Yingliang <yangyingliang@...wei.com>
Reviewed-by: Nikolay Aleksandrov <razor@...ckwall.org>
Signed-off-by: David S. Miller <davem@...emloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@...uxfoundation.org>
---
net/core/neighbour.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -282,21 +282,27 @@ static int neigh_del_timer(struct neighb
static void pneigh_queue_purge(struct sk_buff_head *list, struct net *net)
{
+ struct sk_buff_head tmp;
unsigned long flags;
struct sk_buff *skb;
+ skb_queue_head_init(&tmp);
spin_lock_irqsave(&list->lock, flags);
skb = skb_peek(list);
while (skb != NULL) {
struct sk_buff *skb_next = skb_peek_next(skb, list);
if (net == NULL || net_eq(dev_net(skb->dev), net)) {
__skb_unlink(skb, list);
- dev_put(skb->dev);
- kfree_skb(skb);
+ __skb_queue_tail(&tmp, skb);
}
skb = skb_next;
}
spin_unlock_irqrestore(&list->lock, flags);
+
+ while ((skb = __skb_dequeue(&tmp))) {
+ dev_put(skb->dev);
+ kfree_skb(skb);
+ }
}
static void neigh_flush_dev(struct neigh_table *tbl, struct net_device *dev,
Powered by blists - more mailing lists