From: Andrii Pasichnyk <apasichnik9@gmail.com>
To: "Jason A . Donenfeld" <Jason@zx2c4.com>,
netdev@vger.kernel.org, wireguard@lists.zx2c4.com
Cc: Andrew Lunn <andrew+netdev@lunn.ch>,
"David S . Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@kernel.org>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
linux-kernel@vger.kernel.org,
Andrii Pasichnyk <apasichnik9@gmail.com>
Subject: [PATCH net] wireguard: peer: free packets left on the per-peer queues on removal
Date: Sat, 3 Oct 2026 23:16:25 +0300 [thread overview]
Message-ID: <20261003201625.4572-1-apasichnik9@gmail.com> (raw)
peer_remove_after_dead() flushes the crypt workqueue and then disables
the peer's NAPI. Once a disable is pending, __napi_poll() completes the
instance after the poll returns even if it used its whole budget, so a
peer removed while more than one budget of decrypted packets waits on
rx_queue keeps the rest there. Each entry holds a keypair and a peer
reference, so the peer is never released; the WARN_ON in rcu_release()
that checks for leftovers is never reached either.
Free whatever is left on both per-peer queues once nothing can feed them
any more: receive entries are single packets, transmit entries lists.
Reproduced with the WireGuard selftest VM (x86 KVM, 1 vCPU, net-next):
remove a peer while a UDP flood keeps its receive queue busy, re-add it,
repeat, then run the selftest's created/destroyed object check. Over
2140 removals the unpatched kernel leaked a peer and its keypair 5
times ("wg0: Peer 27: merely created"); with this patch, 0 times in
another 2140.
Fixes: e7096c131e51 ("net: WireGuard secure network tunnel")
Assisted-by: LLM
Signed-off-by: Andrii Pasichnyk <apasichnik9@gmail.com>
---
drivers/net/wireguard/peer.c | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/drivers/net/wireguard/peer.c b/drivers/net/wireguard/peer.c
index 1cb502a..3e08898 100644
--- a/drivers/net/wireguard/peer.c
+++ b/drivers/net/wireguard/peer.c
@@ -91,6 +91,25 @@ static void peer_make_dead(struct wg_peer *peer)
/* The caller must now synchronize_net() for this to take effect. */
}
+/* Each queue entry holds a keypair and a peer reference. Transmit entries
+ * are lists of packets, receive entries single packets.
+ */
+static void peer_purge_queue(struct wg_peer *peer, struct prev_queue *queue,
+ bool lists)
+{
+ struct sk_buff *first;
+
+ while ((first = wg_prev_queue_peek(queue)) != NULL) {
+ wg_prev_queue_drop_peeked(queue);
+ wg_noise_keypair_put(PACKET_CB(first)->keypair, false);
+ wg_peer_put(peer);
+ if (lists)
+ kfree_skb_list(first);
+ else
+ dev_kfree_skb(first);
+ }
+}
+
static void peer_remove_after_dead(struct wg_peer *peer)
{
WARN_ON(!peer->is_dead);
@@ -122,6 +141,11 @@ static void peer_remove_after_dead(struct wg_peer *peer)
* here from process context.
*/
netif_napi_del(&peer->napi);
+ /* A NAPI being disabled completes after at most one more poll, which
+ * may leave packets on rx_queue that still hold references.
+ */
+ peer_purge_queue(peer, &peer->rx_queue, false);
+ peer_purge_queue(peer, &peer->tx_queue, true);
/* Ensure any workstructs we own (like transmit_handshake_work or
* clear_peer_work) no longer are in use.
--
2.53.0
next reply other threads:[~2026-10-03 20:16 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-03 20:16 Andrii Pasichnyk [this message]
2026-10-03 20:19 ` [PATCH net] wireguard: peer: free packets left on the per-peer queues on removal netdev-bot+sinfo
2026-10-03 20:41 ` Andrii Pasichnyk
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261003201625.4572-1-apasichnik9@gmail.com \
--to=apasichnik9@gmail.com \
--cc=Jason@zx2c4.com \
--cc=andrew+netdev@lunn.ch \
--cc=davem@davemloft.net \
--cc=edumazet@kernel.org \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=wireguard@lists.zx2c4.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.