From patchwork Mon May 25 14:36:04 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Antonio Quartulli X-Patchwork-Id: 4969 Return-Path: Delivered-To: patchwork@openvpn.net Received: by 2002:a05:7000:788e:b0:861:c897:cb9d with SMTP id d14csp2474125max; Mon, 25 May 2026 07:36:44 -0700 (PDT) X-Forwarded-Encrypted: i=2; AFNElJ+X2Ase8YLcioEbuyy4cSTC/dm/3KRr8XKMtUYOXO+HgoLww8QUIxbLSByZ++d3L7l0ueCRA68XBXc=@openvpn.net X-Received: by 2002:a05:6808:c2ab:b0:467:e3d5:8389 with SMTP id 5614622812f47-4854af1067fmr6929193b6e.20.1779719804434; Mon, 25 May 2026 07:36:44 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1779719804; cv=none; d=google.com; s=arc-20240605; b=hkYLaUcKCoyS8NYpBcx8WfFqf2SB69ISIdJqT5ne2rxtKJ/XTLj2WcFQzbcuTkRFoh S75dmSp0l9S/tv6soHmOsoeVp2nQqW4Cs/mnKw8e76FAsxlRLngAzbSzBkm8oKpZbHb3 uzDyBiLz3SqKs+xV8OUh0kpHaxBAx2sX5405hba7uT9tOaGCws/vrZpfvc4xBOTs+V6+ wlP7y6l0UIQ7CHaq+TLeV1AzUuBdxDMoL19zP6k61QO5C6e3XIpvDuWkU+ATGxt7XF2k kSHlnPT3r2ym3RHPeOPz6HV8aZrCpop5s8zf0Uqq+kuqGpTfPJoC7HGxLF/hxYOhCiG2 j7Fg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=errors-to:content-transfer-encoding:cc:list-subscribe:list-help :list-post:list-archive:list-unsubscribe:list-id:precedence:subject :mime-version:references:in-reply-to:message-id:date:to:from :dkim-signature:dkim-signature:dkim-signature:dkim-signature; bh=4YY8qdS0xyfdYOH+ZYd9HzFqgCWz0e5RbBdw2BAZljw=; fh=BsMg/B0Yb/hS/rzP5Npz4luh0IleZm8REk1XWiWRt2A=; b=IBbiYH0y7ODttHIFGLqUlt9KA6NZLteKCWWzpn+sFB0SDkl3kztU2iox04w3advFdR yKJp3+t/OeIsKWpWCnsNcOazxSpRxHPGB5zI4Rm0Lf4mgp85q2IQF/kdnyJITcHPtrlM z3Of0nkvI1FL1ub5H+j9h6rnnkF0xYpBi110ClRqef5hopklh1rBrYrqNCC9YAG4F7tE HlfafZahZeGqDuLFuhhSXP2EEYVC7e/brWW2TnrDvDP3/aRrM31JCz96j7CgXBy8zmKQ gsWnNiLyl4hRR8GpmTzfr4Hv81kgxEY5tQH93hB4zQIGJul7ddnc5s29kMF34lXBDz12 PcoQ==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@lists.sourceforge.net header.s=beta header.b="mNrB/15K"; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=iO4DJCgB; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=bz7TkJYn; dkim=neutral (body hash did not verify) header.i=@unstable.cc header.s=MBO0001 header.b=lc5dvxMy; spf=pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) smtp.mailfrom=openvpn-devel-bounces@lists.sourceforge.net Received: from lists.sourceforge.net (lists.sourceforge.net. [216.105.38.7]) by mx.google.com with ESMTPS id 5614622812f47-48554542953si5416972b6e.54.2026.05.25.07.36.44 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Mon, 25 May 2026 07:36:44 -0700 (PDT) Received-SPF: pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) client-ip=216.105.38.7; Authentication-Results: mx.google.com; dkim=pass header.i=@lists.sourceforge.net header.s=beta header.b="mNrB/15K"; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=iO4DJCgB; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=bz7TkJYn; dkim=neutral (body hash did not verify) header.i=@unstable.cc header.s=MBO0001 header.b=lc5dvxMy; spf=pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) smtp.mailfrom=openvpn-devel-bounces@lists.sourceforge.net DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.sourceforge.net; s=beta; h=Content-Transfer-Encoding:Content-Type:Cc: List-Subscribe:List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id: Subject:MIME-Version:References:In-Reply-To:Message-ID:Date:To:From:Sender: Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender :Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=4YY8qdS0xyfdYOH+ZYd9HzFqgCWz0e5RbBdw2BAZljw=; b=mNrB/15KL7UAXGPD8ASdkSsvFE qXlC8qWRFiP89WzS2/JKTMusEFLS4fL1PC1kAzzFIiPL+2ViJumavH5j3OF63eWOcPlKJEbHyjMIB JQ8taMOyZneZdpbGJS1hvORlfdF2b9HMPKYgxwk0EfFZRqlC25WeBoV1fg94d0Va11C4=; Received: from [127.0.0.1] (helo=sfs-ml-1.v29.lw.sourceforge.com) by sfs-ml-1.v29.lw.sourceforge.com with esmtp (Exim 4.95) (envelope-from ) id 1wRWPx-0006PE-Rt; Mon, 25 May 2026 14:36:31 +0000 Received: from [172.30.29.66] (helo=mx.sourceforge.net) by sfs-ml-1.v29.lw.sourceforge.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.95) (envelope-from ) id 1wRWPw-0006JH-B8 for openvpn-devel@lists.sourceforge.net; Mon, 25 May 2026 14:36:29 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=tHRadf2QJQEdsGXYAW31WSywdtNO+52smVfJINAQskw=; b=iO4DJCgBgE2HHkKd4lWcgzyLJa x8YVVnrJsDdCgLMQKvDipeN15tLMy0+Z/AdtFlLRG3XEPpB0kISWfHYypWB63m2OkCYp0dvaOxMlm JKOyYgxY1NFP4EvOUtVeuCe15KSoHD5Qe1xT0GNe/dtOBqq6FeImuALslNwlk4VYm8Eg=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-ID: Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=tHRadf2QJQEdsGXYAW31WSywdtNO+52smVfJINAQskw=; b=bz7TkJYn9OmUkQvO5Wvda1t6hB e6LNH7vzQapKwYahQN1XF5LtVDb9mA5ZrujZPWX0IyRCBqPBVNOcFMSrsrZhq7AuCgR84bqDKcPLq RNw/yLdKmDc0tLTOPqC9HmW2zfvHvb6PbvffGxX/LnfDqagd8dUFI2/UXp+l/u2kGj1s=; Received: from mout-p-201.mailbox.org ([80.241.56.171]) by sfi-mx-2.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.95) id 1wRWPl-0003pN-OY for openvpn-devel@lists.sourceforge.net; Mon, 25 May 2026 14:36:23 +0000 Received: from smtp102.mailbox.org (smtp102.mailbox.org [10.196.197.102]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by mout-p-201.mailbox.org (Postfix) with ESMTPS id 4gPJN92KxCz9sX2; Mon, 25 May 2026 16:36:09 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=unstable.cc; s=MBO0001; t=1779719769; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=tHRadf2QJQEdsGXYAW31WSywdtNO+52smVfJINAQskw=; b=lc5dvxMy+AL7fAj/3Tb3u0thOHJgjWI3X/vbmM7dAinpx7Vw/OaeklNKV2avX6SMTEAgWL 4kopmWt7VYMQPw6KxaliNDJXOPQKZaS8l3MFew4cgGKDkq4r58hWk8E6XFrwdKoU9VOd1l eGBoCRl533amMgzBP+GPGfyq14a/yCX22cTZTURA22yodSU+fh/4LQo9v05o+Gi/N04/aC yWQ7g8pPNytqwt3oaDVvjqxTWQTKNeWrovc/64aODThcvH4bHLjsVULoDKDUNJy4t4s9aI +WBQOCFMqZPWPYJLPGjGv9WHL/owmGMhlRTDk4jSsW7m9ZugHlWbRDjhtQ8MZQ== From: Antonio Quartulli To: openvpn-devel@lists.sourceforge.net Date: Mon, 25 May 2026 16:36:04 +0200 Message-ID: <20260525143606.1532168-2-a@unstable.cc> In-Reply-To: <20260525143606.1532168-1-a@unstable.cc> References: <20260525143606.1532168-1-a@unstable.cc> MIME-Version: 1.0 X-Spam-Score: -0.2 (/) X-Spam-Report: Spam detection software, running on the system "sfi-spamd-1.hosts.colo.sdot.me", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: From: Antonio Quartulli Memcg accounting bounds user-driven peer creation only when the calling cgroup has memory.max set; on unconstrained hosts it isn't a hard limit. Track the live peer count in ovpn_peer_collection::n_peers under the existing ovpn->lock and reject OVPN_CMD_PEER_NEW with -ENOSPC once OVPN_MAX_PEERS (65535) is reached. 65535 matches what userspace [...] Content analysis details: (-0.2 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid X-Headers-End: 1wRWPl-0003pN-OY Subject: [Openvpn-devel] [PATCH 2/4] ovpn: cap number of peers per multi-peer interface X-BeenThere: openvpn-devel@lists.sourceforge.net X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Antonio Quartulli Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox X-GMAIL-THRID: 1866171473789925560 X-GMAIL-MSGID: 1866171473789925560 From: Antonio Quartulli Memcg accounting bounds user-driven peer creation only when the calling cgroup has memory.max set; on unconstrained hosts it isn't a hard limit. Track the live peer count in ovpn_peer_collection::n_peers under the existing ovpn->lock and reject OVPN_CMD_PEER_NEW with -ENOSPC once OVPN_MAX_PEERS (65535) is reached. 65535 matches what userspace OpenVPN servers configure via --max-clients. P2P mode is unaffected. The same cap also bounds the unaccounted RX-float bind allocations, since binds are owned by peers. Signed-off-by: Antonio Quartulli --- drivers/net/ovpn/ovpnpriv.h | 3 +++ drivers/net/ovpn/peer.c | 9 +++++++++ drivers/net/ovpn/peer.h | 8 ++++++++ 3 files changed, 20 insertions(+) diff --git a/drivers/net/ovpn/ovpnpriv.h b/drivers/net/ovpn/ovpnpriv.h index 5898f6adada7..113f5f493575 100644 --- a/drivers/net/ovpn/ovpnpriv.h +++ b/drivers/net/ovpn/ovpnpriv.h @@ -24,12 +24,15 @@ * rehashed on the fly due to peer IP change) * @by_transp_addr: table of peers indexed by transport address (items can be * rehashed on the fly due to peer IP change) + * @n_peers: number of peers currently in the collection, protected by + * ovpn_priv->lock */ struct ovpn_peer_collection { DECLARE_HASHTABLE(by_id, 12); struct hlist_nulls_head by_vpn_addr4[1 << 12]; struct hlist_nulls_head by_vpn_addr6[1 << 12]; struct hlist_nulls_head by_transp_addr[1 << 12]; + u32 n_peers; }; /** diff --git a/drivers/net/ovpn/peer.c b/drivers/net/ovpn/peer.c index 511a7ce9b32b..1d564888479a 100644 --- a/drivers/net/ovpn/peer.c +++ b/drivers/net/ovpn/peer.c @@ -286,6 +286,8 @@ void ovpn_peer_endpoints_update(struct ovpn_peer *peer, struct sk_buff *skb) /* RX float path runs in softirq context: __GFP_ACCOUNT would charge * whatever cgroup is on-CPU when the packet arrives, not the userns * owner, so pass plain GFP_ATOMIC and skip accounting on this path. + * The number of bind objects that can accumulate via float events is + * bounded by the per-MP peer cap, since binds are owned by peers. */ if (unlikely(ovpn_peer_reset_sockaddr(peer, (struct sockaddr_storage *)&ss, @@ -703,6 +705,7 @@ static void ovpn_peer_remove(struct ovpn_peer *peer, hlist_nulls_del_init_rcu(&peer->hash_entry_addr4); hlist_nulls_del_init_rcu(&peer->hash_entry_addr6); hlist_nulls_del_init_rcu(&peer->hash_entry_transp_addr); + peer->ovpn->peers->n_peers--; break; case OVPN_MODE_P2P: /* prevent double remove */ @@ -959,6 +962,11 @@ static int ovpn_peer_add_mp(struct ovpn_priv *ovpn, struct ovpn_peer *peer) goto out; } + if (ovpn->peers->n_peers >= OVPN_MAX_PEERS) { + ret = -ENOSPC; + goto out; + } + bind = rcu_dereference_protected(peer->bind, true); /* peers connected via TCP have bind == NULL */ if (bind) { @@ -994,6 +1002,7 @@ static int ovpn_peer_add_mp(struct ovpn_priv *ovpn, struct ovpn_peer *peer) sizeof(peer->id))); ovpn_peer_hash_vpn_ip(peer); + ovpn->peers->n_peers++; out: spin_unlock_bh(&ovpn->lock); return ret; diff --git a/drivers/net/ovpn/peer.h b/drivers/net/ovpn/peer.h index 1bfc66821739..2efc782130f3 100644 --- a/drivers/net/ovpn/peer.h +++ b/drivers/net/ovpn/peer.h @@ -17,6 +17,14 @@ #include "socket.h" #include "stats.h" +/* Hard cap on number of peers per MP-mode interface. Caps the worst-case + * kernel memory an unprivileged userns owner driving OVPN_CMD_PEER_NEW can + * pin even when memcg accounting is unconstrained. 65535 matches what + * mainstream userspace OpenVPN servers configure via --max-clients, so + * legitimate deployments never hit this. + */ +#define OVPN_MAX_PEERS 65535 + /** * struct ovpn_peer - the main remote peer object * @ovpn: main openvpn instance this peer belongs to