All of lore.kernel.org
 help / color / mirror / Atom feed
From: Alexander Ildiyarov <alex@badcode.im>
To: alexvancasper@gmail.com
Cc: Alexander Ildiyarov <alex@badcode.im>, stable@vger.kernel.org
Subject: [PATCH net 1/2] wireguard: account peer and allowedips allocations to memcg
Date: Thu,  5 Nov 2026 17:08:14 +0300	[thread overview]
Message-ID: <20261105140815.92841-2-alex@badcode.im> (raw)
In-Reply-To: <20261105140815.92841-1-alex@badcode.im>

Peers, allowed IP trie nodes, the per-peer dst_cache and the per-device
hashtables are all allocated in the context of the process that
configures the device over netlink, but none of these allocations are
charged to that process's memory cgroup: the wg_peer and allowedips_node
caches are created without SLAB_ACCOUNT, and the hashtables and
dst_cache use plain GFP_KERNEL.

The amount of memory is bounded only by MAX_PEERS_PER_DEVICE (2^20) per
device, with no limit on the number of devices or on the number of
allowed IPs per peer. Since WG_CMD_SET_DEVICE uses GENL_UNS_ADMIN_PERM,
any user who can create a user and network namespace can do this, and
thereby escape the memory limits of the cgroup it runs in.

For example, a process in a cgroup with memory.max=64M that adds 100000
peers with 20 /128 allowed IPs each grows Slab by ~790 MiB, yet the
cgroup's memory.current stays below 1 MiB and its memory limit is never
hit.

Fix this by creating the two caches with SLAB_ACCOUNT and using
GFP_KERNEL_ACCOUNT for the hashtables and the dst_cache. The keypair
allocations are left alone, as they happen from the handshake worker and
are bounded to three per peer.

Fixes: e7096c131e51 ("net: WireGuard secure network tunnel")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Alexander Ildiyarov <alex@badcode.im>
---
 drivers/net/wireguard/allowedips.c | 2 +-
 drivers/net/wireguard/peer.c       | 4 ++--
 drivers/net/wireguard/peerlookup.c | 4 ++--
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireguard/allowedips.c b/drivers/net/wireguard/allowedips.c
index 5ece9acad64d..2f2b8a94c8a7 100644
--- a/drivers/net/wireguard/allowedips.c
+++ b/drivers/net/wireguard/allowedips.c
@@ -411,7 +411,7 @@ struct wg_peer *wg_allowedips_lookup_src(struct allowedips *table,
 
 int __init wg_allowedips_slab_init(void)
 {
-	node_cache = KMEM_CACHE(allowedips_node, 0);
+	node_cache = KMEM_CACHE(allowedips_node, SLAB_ACCOUNT);
 	return node_cache ? 0 : -ENOMEM;
 }
 
diff --git a/drivers/net/wireguard/peer.c b/drivers/net/wireguard/peer.c
index 1cb502a932e0..05b80521c706 100644
--- a/drivers/net/wireguard/peer.c
+++ b/drivers/net/wireguard/peer.c
@@ -33,7 +33,7 @@ struct wg_peer *wg_peer_create(struct wg_device *wg,
 	peer = kmem_cache_zalloc(peer_cache, GFP_KERNEL);
 	if (unlikely(!peer))
 		return ERR_PTR(ret);
-	if (unlikely(dst_cache_init(&peer->endpoint_cache, GFP_KERNEL)))
+	if (unlikely(dst_cache_init(&peer->endpoint_cache, GFP_KERNEL_ACCOUNT)))
 		goto err;
 
 	peer->device = wg;
@@ -229,7 +229,7 @@ void wg_peer_put(struct wg_peer *peer)
 
 int __init wg_peer_init(void)
 {
-	peer_cache = KMEM_CACHE(wg_peer, 0);
+	peer_cache = KMEM_CACHE(wg_peer, SLAB_ACCOUNT);
 	return peer_cache ? 0 : -ENOMEM;
 }
 
diff --git a/drivers/net/wireguard/peerlookup.c b/drivers/net/wireguard/peerlookup.c
index 99651a86ac95..f333e906014a 100644
--- a/drivers/net/wireguard/peerlookup.c
+++ b/drivers/net/wireguard/peerlookup.c
@@ -21,7 +21,7 @@ static struct hlist_head *pubkey_bucket(struct pubkey_hashtable *table,
 
 struct pubkey_hashtable *wg_pubkey_hashtable_alloc(void)
 {
-	struct pubkey_hashtable *table = kvmalloc_obj(*table);
+	struct pubkey_hashtable *table = kvmalloc_obj(*table, GFP_KERNEL_ACCOUNT);
 
 	if (!table)
 		return NULL;
@@ -82,7 +82,7 @@ static struct hlist_head *index_bucket(struct index_hashtable *table,
 
 struct index_hashtable *wg_index_hashtable_alloc(void)
 {
-	struct index_hashtable *table = kvmalloc_obj(*table);
+	struct index_hashtable *table = kvmalloc_obj(*table, GFP_KERNEL_ACCOUNT);
 
 	if (!table)
 		return NULL;
-- 
2.43.0


       reply	other threads:[~2026-11-05 14:08 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20261105140815.92841-1-alex@badcode.im>
2026-11-05 14:08 ` Alexander Ildiyarov [this message]
2026-11-10 16:52   ` [PATCH net 1/2] wireguard: account peer and allowedips allocations to memcg Jason A. Donenfeld
2026-11-05 14:08 ` [PATCH net 2/2] wireguard: noise: recheck replay and flood under write lock on initiation Alexander Ildiyarov
2026-11-10 16:51   ` Jason A. Donenfeld
2026-11-10 18:08     ` alex
2026-11-05 14:10 [PATCH net 0/2] wireguard: memcg accounting and initiation race fix Alexander Ildiyarov
2026-11-05 14:10 ` [PATCH net 1/2] wireguard: account peer and allowedips allocations to memcg Alexander Ildiyarov
2026-11-09 15:20   ` netdev-bot+sashiko
2026-11-10 16:57   ` Jason A. Donenfeld
2026-11-10 18:04     ` alex
2026-11-10 18:06       ` Jason A. Donenfeld

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=20261105140815.92841-2-alex@badcode.im \
    --to=alex@badcode.im \
    --cc=alexvancasper@gmail.com \
    --cc=stable@vger.kernel.org \
    /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.