From patchwork Mon Jul 27 20:06:57 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Antonio Quartulli X-Patchwork-Id: 5131 Return-Path: Delivered-To: patchwork@openvpn.net Received: by 2002:a05:7000:190f:b0:87d:a69c:34be with SMTP id g15csp1598647maz; Mon, 27 Jul 2026 13:07:29 -0700 (PDT) X-Forwarded-Encrypted: i=2; AHgh+Rp+5kjtQfdootRCJ+uUdCIb4Y0Q58hYphBQ/0afXgfOKmgA8fDzKhYyGU9E+i5UR+uKl9LKkSqwdpk=@openvpn.net X-Received: by 2002:a05:6820:1893:b0:6ab:24a:242 with SMTP id 006d021491bc7-6ac90e81801mr885221eaf.61.1785182849438; Mon, 27 Jul 2026 13:07:29 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1785182849; cv=none; d=google.com; s=arc-20260327; b=qkIncZEKyRAAXh3CFMwLOB6FcGOkOrg/DH6E9yIWgZnW/7GZhU+ksRml73swYJrxue WvaQXXdrxHqkVyX1Z0t4Ozy2PdjUx3W97rNYZShG/8OdpqAfqSCZTGhJwdFI9unA9EW8 pM/JMihJ3MG9PWYz9nh7bv5AdPGWCLlnJVGwgft91nA8eyvbl1iT8Xv9r1+guIqJYvHw 4OQvbAhrdqW0MAZd6C3/W8S2r7j0byw9dp7yGJIm1AVoXRnMg2wR3qaHsRyXslk48YSL GGJchnGbZre6T2SOeKjEvCA/zVWropJ4mYdsHuaNOoxJkUQek5XLM19f1dA1hJTK+m4N o++w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20260327; 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=4JI7XNkscyUSBkFxU8QJIaqodb34DsucJL7LCK2HePQ=; fh=BsMg/B0Yb/hS/rzP5Npz4luh0IleZm8REk1XWiWRt2A=; b=JIjchMJZu535KxASOHfGVVhe2otORHir/65CUysW1GwXHBpRMsthA8v185tya+ZhcY CbzHrevS1NmFHurxjEGYKMOo3tgpb8WLznDhDmjpQAYld0u5UUaQOWnAnNdHsW2SIwR5 U+uqfuYAaxc+rv6Puru9ldQmrUxt7Wy5Oh265vlyPTVvMRvEzToX3MMh1tslZMXEO5DG TyD/kGT5hJB/lXd/zT8ogdklqbbp+ksOVW8aVZfffD8/II+2pMNxO+e1XD+g7whFGpPI F2hDdqVNfDOQDFNb4X5NDAKRYPR3tJhrZbpntNAqE8nD4DGvTxkr7YAB7oqbKAs5BofA gPEw==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@lists.sourceforge.net header.s=beta header.b=c32LyuHT; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=UFjSCz9o; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=kM22pa8M; dkim=neutral (body hash did not verify) header.i=@unstable.cc header.s=MBO0001 header.b=FFGf59OR; 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 586e51a60fabf-457aa973f07si13404833fac.277.2026.07.27.13.07.29 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Mon, 27 Jul 2026 13:07:29 -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=c32LyuHT; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=UFjSCz9o; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=kM22pa8M; dkim=neutral (body hash did not verify) header.i=@unstable.cc header.s=MBO0001 header.b=FFGf59OR; 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=4JI7XNkscyUSBkFxU8QJIaqodb34DsucJL7LCK2HePQ=; b=c32LyuHT9cTf7JRhGk8q/QW+lu wsVxC0FlEoIrFTC2kElvpLKO+ETaK79cXJ/6L9HrD4/ZmEZIJmfoRqEOVf717eJJYjPO4vNXvTqwJ qukSTX8hEP5xNESZOxUN2XuTJdpBmE+zsPq8RLTZuxrodf06FussObTQLVzdU3jFfgZs=; Received: from [127.0.0.1] (helo=sfs-ml-3.v29.lw.sourceforge.com) by sfs-ml-3.v29.lw.sourceforge.com with esmtp (Exim 4.95) (envelope-from ) id 1woRbi-0004J4-64; Mon, 27 Jul 2026 20:07:26 +0000 Received: from [172.30.29.66] (helo=mx.sourceforge.net) by sfs-ml-3.v29.lw.sourceforge.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.95) (envelope-from ) id 1woRbh-0004It-2U for openvpn-devel@lists.sourceforge.net; Mon, 27 Jul 2026 20:07:25 +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=tRaDtzA/BJj2zwxV9t0k38HHdjtHPPreMlLZlmWrfj4=; b=UFjSCz9o+oVzOFKP5IyydXvBby dR9rEeDdFcE/KQ4nIz9RE/NyGP1PN2MyAmPXfT7CvHrRmsZZ+V+gsaZgQVKs/Lgm5+6PWX9WdeQzl 2wiNtMWr0qg/4p72En6SnLJxaJFX9tpddsuhEghk5t81nDOi2ZIGuIFQULEDQciVPorY=; 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=tRaDtzA/BJj2zwxV9t0k38HHdjtHPPreMlLZlmWrfj4=; b=kM22pa8M9z14fRfaKhmKmaFVM2 mwjn4UHiXcwUjfDBfV4LoApavL3NQzEBdl8B0N6pfV+CNMVeUUK3QX99U6ydieM4t0CH9ZYRfIfes WDwG+E/D+rpWwf/sbyYut1EFkar421RPhlcyKyu8TSoh0ZQGPuL2ixznm7ndf1KZJTEk=; Received: from mout-p-201.mailbox.org ([80.241.56.171]) by sfi-mx-1.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.95) id 1woRbh-0002cl-3I for openvpn-devel@lists.sourceforge.net; Mon, 27 Jul 2026 20:07:25 +0000 Received: from smtp102.mailbox.org (smtp102.mailbox.org [IPv6:2001:67c:2050:b231:465::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 4h88l55GLRzMlJh; Mon, 27 Jul 2026 22:07:13 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=unstable.cc; s=MBO0001; t=1785182833; 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=tRaDtzA/BJj2zwxV9t0k38HHdjtHPPreMlLZlmWrfj4=; b=FFGf59ORw4ICji4WPafskiOXH2zLyqb81GJGIt3ZM8K9riT5W7cq94zJ+pysJT4Qf86xi6 eEI9yjKis5IrDKjYyvZEZUR9LWnwUmpkZvpw0qJelQ/9F+kbGiPGKBvWBMjMZQxJXzmlY9 0seg4KzTMTnT8WQpFUmbhfbbWaoNzJxNobGs7SzLqeMUJnYxsHE5AIbIhLJ+7YSFlAlAfz KxSICtDTNHgIZQBtg6cmbC0Dp56+Z7E1hkMzGgWLN0XzDQgoW7unPkP/JbhiGYrhHbSNdh 5Q3ptrpOWhtyXjzxH+UPO7EO/Zu/z/UyDtBfcnGSc3UaoTahvu2HcRY/QFZlxg== Authentication-Results: outgoing_mbo_mout; dkim=none; spf=pass (outgoing_mbo_mout: domain of a@unstable.cc designates 2001:67c:2050:b231:465::102 as permitted sender) smtp.mailfrom=a@unstable.cc From: Antonio Quartulli To: openvpn-devel@lists.sourceforge.net Date: Mon, 27 Jul 2026 22:06:57 +0200 Message-ID: <20260727200705.869169-2-a@unstable.cc> In-Reply-To: <20260727200705.869169-1-a@unstable.cc> References: <20260727200705.869169-1-a@unstable.cc> MIME-Version: 1.0 X-Rspamd-Queue-Id: 4h88l55GLRzMlJh 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 ovpn_nl_peer_set_doit() resolves the target peer via ovpn_peer_get_by_id() before taking ovpn->lock. In the window between the lookup (which only takes a refcount) and the subsequent spin_lock_bh(&ovp [...] Content analysis details: (-0.2 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature 0.0 RCVD_IN_MSPIKE_H5 RBL: Excellent reputation (+5) [80.241.56.171 listed in wl.mailspike.net] 0.0 RCVD_IN_MSPIKE_WL Mailspike good senders X-Headers-End: 1woRbh-0002cl-3I Subject: [Openvpn-devel] [PATCH ovpn net v3 1/9] ovpn: skip rehash for peers already removed from by_id 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: 1871899891413595780 X-GMAIL-MSGID: 1871899891413595780 From: Antonio Quartulli ovpn_nl_peer_set_doit() resolves the target peer via ovpn_peer_get_by_id() before taking ovpn->lock. In the window between the lookup (which only takes a refcount) and the subsequent spin_lock_bh(&ovpn->lock), a concurrent OVPN_CMD_PEER_DEL, keepalive expiry, or socket teardown can take ovpn->lock first, run ovpn_peer_remove() to unhash the peer from all four tables (by_id, by_vpn_addr4/6, by_transp_addr) and release the lock. set_doit then acquires ovpn->lock and calls ovpn_peer_hash_vpn_ip(), which re-inserts the now-removed peer back into the rehashing tables. The same race affects the float path: ovpn_peer_endpoints_update() holds only a refcount and acquires ovpn->lock very late (after async AEAD decrypt and a netlink notification), then rehashes the peer in the by_transp_addr table. The resurrected peer becomes reachable again from the RX lookup (ovpn_peer_get_by_transp_addr) and the TX VPN-IP lookup, even though userspace believes it is gone. Once the data-path refcount drops the peer is freed via call_rcu while the hash entries embedded in it remain linked, opening a UAF window. Bail out of the rehash when hash_entry_id is unhashed, mirroring the sentinel already used by ovpn_peer_remove() to detect the already-removed state. The check is safe under ovpn->lock, which serializes every mutation of hash_entry_id, and is a no-op for the add path because ovpn_peer_add_mp() inserts hash_entry_id before calling ovpn_peer_hash_vpn_ip(). Fixes: 1d36a36f6d53 ("ovpn: implement peer add/get/dump/delete via netlink") Signed-off-by: Antonio Quartulli --- Changes since v1: * simplified flow in ovpn_peer_endpoints_update() and introduced new unlock2 label --- drivers/net/ovpn/peer.c | 73 ++++++++++++++++++++++++----------------- 1 file changed, 43 insertions(+), 30 deletions(-) diff --git a/drivers/net/ovpn/peer.c b/drivers/net/ovpn/peer.c index a21d02ac715e..68021c0c1783 100644 --- a/drivers/net/ovpn/peer.c +++ b/drivers/net/ovpn/peer.c @@ -297,40 +297,46 @@ void ovpn_peer_endpoints_update(struct ovpn_peer *peer, struct sk_buff *skb) /* rehashing is required only in MP mode as P2P has one peer * only and thus there is no hashtable */ - if (peer->ovpn->mode == OVPN_MODE_MP) { - spin_lock_bh(&peer->ovpn->lock); - spin_lock_bh(&peer->lock); - bind = rcu_dereference_protected(peer->bind, - lockdep_is_held(&peer->lock)); - if (unlikely(!bind)) { - spin_unlock_bh(&peer->lock); - spin_unlock_bh(&peer->ovpn->lock); - return; - } + if (peer->ovpn->mode != OVPN_MODE_MP) + return; - /* This function may be invoked concurrently, therefore another - * float may have happened in parallel: perform rehashing - * using the peer->bind->remote directly as key - */ + spin_lock_bh(&peer->ovpn->lock); + spin_lock_bh(&peer->lock); + bind = rcu_dereference_protected(peer->bind, + lockdep_is_held(&peer->lock)); + if (unlikely(!bind)) + goto unlock2; - switch (bind->remote.in4.sin_family) { - case AF_INET: - salen = sizeof(*sa); - break; - case AF_INET6: - salen = sizeof(*sa6); - break; - } + /* peer may have been concurrently removed between the caller's + * initial lookup and our acquisition of ovpn->lock; skip the + * rehash so we don't re-insert a removed peer + */ + if (unlikely(hlist_unhashed(&peer->hash_entry_id))) + goto unlock2; - /* remove old hashing */ - hlist_nulls_del_init_rcu(&peer->hash_entry_transp_addr); - /* re-add with new transport address */ - nhead = ovpn_get_hash_head(peer->ovpn->peers->by_transp_addr, - &bind->remote, salen); - hlist_nulls_add_head_rcu(&peer->hash_entry_transp_addr, nhead); - spin_unlock_bh(&peer->lock); - spin_unlock_bh(&peer->ovpn->lock); + /* This function may be invoked concurrently, therefore another + * float may have happened in parallel: perform rehashing + * using the peer->bind->remote directly as key + */ + + switch (bind->remote.in4.sin_family) { + case AF_INET: + salen = sizeof(*sa); + break; + case AF_INET6: + salen = sizeof(*sa6); + break; } + + /* remove old hashing */ + hlist_nulls_del_init_rcu(&peer->hash_entry_transp_addr); + /* re-add with new transport address */ + nhead = ovpn_get_hash_head(peer->ovpn->peers->by_transp_addr, + &bind->remote, salen); + hlist_nulls_add_head_rcu(&peer->hash_entry_transp_addr, nhead); +unlock2: + spin_unlock_bh(&peer->lock); + spin_unlock_bh(&peer->ovpn->lock); return; unlock: spin_unlock_bh(&peer->lock); @@ -906,6 +912,13 @@ void ovpn_peer_hash_vpn_ip(struct ovpn_peer *peer) if (peer->ovpn->mode != OVPN_MODE_MP) return; + /* peer may have been concurrently removed between the caller's + * initial lookup and our acquisition of ovpn->lock; skip the + * rehash so we don't re-insert a removed peer + */ + if (hlist_unhashed(&peer->hash_entry_id)) + return; + if (peer->vpn_addrs.ipv4.s_addr != htonl(INADDR_ANY)) { /* remove potential old hashing */ hlist_nulls_del_init_rcu(&peer->hash_entry_addr4); From patchwork Mon Jul 27 20:06:58 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Antonio Quartulli X-Patchwork-Id: 5133 Return-Path: Delivered-To: patchwork@openvpn.net Received: by 2002:a05:7000:190f:b0:87d:a69c:34be with SMTP id g15csp1598656maz; Mon, 27 Jul 2026 13:07:30 -0700 (PDT) X-Forwarded-Encrypted: i=2; AHgh+RrBIhZw7SYf1jGTLgm10NJwLVzVzYjnGRkYTwomrPH3WzPaVw5y8yTI4fuBL635S/j/PmGbo5jlmzU=@openvpn.net X-Received: by 2002:a05:6870:1649:b0:440:4df:c208 with SMTP id 586e51a60fabf-4585e441228mr757720fac.33.1785182849818; Mon, 27 Jul 2026 13:07:29 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1785182849; cv=none; d=google.com; s=arc-20260327; b=F2wHhH+qNw7crGQMNnJpNDTvbd0bqAT6JDPIu2OsAw30duodAj1iVBBIQ92UZ9GH2+ SuTafD5QkGJc3A03voTfKvd+0n4D+lwd3LHuVJvVvFLELvycXgq2Y61+A5ENnTx51fTE WGTKwGZxhDskUuPfO2mErQdgI9IDzFGErM/sEc8HSayatdPtdGz824/3kfzBA3YrdQX5 F8b+DXSggWaWi3sUEfJY/9D5TA7ca30pczJJB05rECeNIwD/R/6SOyDe7ovaJn61KopG y4qX18cg+u+E2tg/GPn1fuGaoavs3WwiNkhiN3BqCUsDOUgab15YG+oTH0xVfGyzpphT e2SQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20260327; 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=z5GgYCQ51eyqREAMH1U7IE5jnb0HCmRV0DVGN0Y6nQk=; fh=BsMg/B0Yb/hS/rzP5Npz4luh0IleZm8REk1XWiWRt2A=; b=Rn/KHvBBvUGZqL+JRg3B37xl/AwFCh3sKjJ0F+Aftz9s2Vx8kxU37jahG0v11oPgue K9fFnYQ0PC9JztBqlnmPh1m/Pz1oDWBIs+uKgxJ2zFlmNU+kRMW//eVW+Vb860Tffg3I HKqi6K4mM/n5LzjwquDCJJFhNAJVVF+DKYzqwaC94p/fG2dE+iFOh+oMAmdzO+eI7Fvx SdYfDgI6dv9m1BmtYeMzmvDuoAdtdm77mWE8AHm9Ai59DVhBbBQcklvTP3+NHguDKuoa OlI9DRXYerOpEMoWmwMG7ReKyLubhAR8NqCyKukOTT082EfiDgEu6pVDDfT4RbxkW990 RzSg==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@lists.sourceforge.net header.s=beta header.b=l9Ko3Siz; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=cAY8NaJA; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=JXlLqKhu; dkim=neutral (body hash did not verify) header.i=@unstable.cc header.s=MBO0001 header.b=vHYgQU5y; 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 586e51a60fabf-457aa973f30si13389761fac.275.2026.07.27.13.07.29 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Mon, 27 Jul 2026 13:07:29 -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=l9Ko3Siz; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=cAY8NaJA; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=JXlLqKhu; dkim=neutral (body hash did not verify) header.i=@unstable.cc header.s=MBO0001 header.b=vHYgQU5y; 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=z5GgYCQ51eyqREAMH1U7IE5jnb0HCmRV0DVGN0Y6nQk=; b=l9Ko3SizrQhKPETnZfEeGxrXQK /7O4s9r3WhK1zD7n+N82Yz9MUxI0bfwVlNQ1A6d8sX0yr/juHb6piHFwxS/rLBRnumT/GyawaVrro 1VgX7hifrlUC93quFWSN15vZ0jAJIRkbdCk5cqv5hlZksJF6K9KICWBtJ3xL8hIFq4ik=; Received: from [127.0.0.1] (helo=sfs-ml-4.v29.lw.sourceforge.com) by sfs-ml-4.v29.lw.sourceforge.com with esmtp (Exim 4.95) (envelope-from ) id 1woRbg-000132-Lc; Mon, 27 Jul 2026 20:07:24 +0000 Received: from [172.30.29.66] (helo=mx.sourceforge.net) by sfs-ml-4.v29.lw.sourceforge.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.95) (envelope-from ) id 1woRbf-00012u-DH for openvpn-devel@lists.sourceforge.net; Mon, 27 Jul 2026 20:07:23 +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=oj93ZxyY5w0ozartbYOt5zHsxh+gzD1zzN/FHy8ef28=; b=cAY8NaJAQSt6eBaFk5hfjNHUL7 UmRKy9ndW+fJIgIhNBRbLbBfz98z2EginRIHWEtfRokQToWk/D9afdBR0ADGaQ9wKYIOEiq6BeC7E aEZDeAZKWhE1OHywrQumAsGmdQZ5HgFV3/0yY93CgqmewFiyNOC4wt7Xk2YpBpbSOCmI=; 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=oj93ZxyY5w0ozartbYOt5zHsxh+gzD1zzN/FHy8ef28=; b=JXlLqKhuRiWI7Wyi4QnhpDSWY+ 6Y9wZog+mZjdBIsiDZZqCce0/4QYyMUlzZvUiGDJhIOYpo4mfgp/JZs0u4dGVJwfjnDTh/Qat+bZI Tjy7yR9dFnWaQqvX4Au3ABhOqZLZopVpn4QQ1KDJOSXIoi/tCenR3Mh/FvefP7NZpnXk=; Received: from mout-p-101.mailbox.org ([80.241.56.151]) by sfi-mx-2.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.95) id 1woRbd-0001P9-SW for openvpn-devel@lists.sourceforge.net; Mon, 27 Jul 2026 20:07:23 +0000 Received: from smtp102.mailbox.org (smtp102.mailbox.org [IPv6:2001:67c:2050:b231:465::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-101.mailbox.org (Postfix) with ESMTPS id 4h88l63Rlvz8v96; Mon, 27 Jul 2026 22:07:14 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=unstable.cc; s=MBO0001; t=1785182834; 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=oj93ZxyY5w0ozartbYOt5zHsxh+gzD1zzN/FHy8ef28=; b=vHYgQU5yPx7eDmNA3d06hTkjhpipNL6jxgfH3DaBz3ya0TQg3TRrrAOHIVclQjf4ZmbWxI H3sm9k//jIRLVMorYr/yLUjKvOv84POxvpgQn9A213uXo7OOa9PSLkRaBac7AyDZn+vIQG Tss0tv0GuW5e/mBbBlWWKYCXf13e+//p8qT7GUqccuMpwOA5OUPjhhjk+q9JkMvk0CBotW sMJ5n77xASK1eekaadeXSlF1v2dfx2MW7nTx0nsNJIM+uBIbOxLTjQNgVxD/TgGvOlJFW3 qLsx0N9Lpg6Z6f16YAvrZjlfUhLEoKsy7dfm9dsItUFLX8wFDvfqJ0nLt4QzRw== Authentication-Results: outgoing_mbo_mout; dkim=none; spf=pass (outgoing_mbo_mout: domain of a@unstable.cc designates 2001:67c:2050:b231:465::102 as permitted sender) smtp.mailfrom=a@unstable.cc From: Antonio Quartulli To: openvpn-devel@lists.sourceforge.net Date: Mon, 27 Jul 2026 22:06:58 +0200 Message-ID: <20260727200705.869169-3-a@unstable.cc> In-Reply-To: <20260727200705.869169-1-a@unstable.cc> References: <20260727200705.869169-1-a@unstable.cc> MIME-Version: 1.0 X-Rspamd-Queue-Id: 4h88l63Rlvz8v96 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 When userspace updates a peer's remote endpoint via OVPN_CMD_PEER_SET, ovpn_nl_peer_modify() installs a new ovpn_bind through ovpn_peer_reset_sockaddr(), but ovpn_nl_peer_set_doit() only calls ovpn_pe [...] Content analysis details: (-0.2 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature 0.0 RCVD_IN_MSPIKE_H5 RBL: Excellent reputation (+5) [80.241.56.151 listed in wl.mailspike.net] 0.0 RCVD_IN_MSPIKE_WL Mailspike good senders X-Headers-End: 1woRbd-0001P9-SW Subject: [Openvpn-devel] [PATCH ovpn net v3 2/9] ovpn: rehash peer in by_transp_addr table on CMD_PEER_SET 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: 1871899891705658253 X-GMAIL-MSGID: 1871899891705658253 From: Antonio Quartulli When userspace updates a peer's remote endpoint via OVPN_CMD_PEER_SET, ovpn_nl_peer_modify() installs a new ovpn_bind through ovpn_peer_reset_sockaddr(), but ovpn_nl_peer_set_doit() only calls ovpn_peer_hash_vpn_ip() to refresh the VPN-IP hashtables. The peer is left in the bucket of peers->by_transp_addr corresponding to its old remote address. As a consequence, datagrams arriving at the UDP RX path from the newly configured remote hash to a different slot and the lockless lookup in ovpn_peer_get_by_transp_addr() (called from ovpn_udp_encap_recv()) does not find the peer, until either a float event or a peer re-add fixes the bucket. Introduce ovpn_peer_hash_transp_addr() (modeled after ovpn_peer_hash_vpn_ip()) and invoke it from ovpn_nl_peer_set_doit() whenever the request carried a new remote address. The helper bails out in P2P mode and on peers without a bind (TCP), and relies on hlist_nulls_del_init_rcu()'s pprev==NULL short-circuit to handle the case of an entry not currently linked in the table. Fixes: 1d36a36f6d53 ("ovpn: implement peer add/get/dump/delete via netlink") Signed-off-by: Antonio Quartulli --- drivers/net/ovpn/netlink.c | 6 +++ drivers/net/ovpn/peer.c | 105 +++++++++++++++++++++++++------------ drivers/net/ovpn/peer.h | 1 + 3 files changed, 79 insertions(+), 33 deletions(-) diff --git a/drivers/net/ovpn/netlink.c b/drivers/net/ovpn/netlink.c index 4c66c1ec497e..4dad85294198 100644 --- a/drivers/net/ovpn/netlink.c +++ b/drivers/net/ovpn/netlink.c @@ -534,6 +534,12 @@ int ovpn_nl_peer_set_doit(struct sk_buff *skb, struct genl_info *info) */ if (ret > 0) ovpn_peer_hash_vpn_ip(peer); + /* if the remote endpoint was updated, the by_transp_addr hash bucket + * also needs to be refreshed, otherwise incoming packets from the new + * remote address would fail the lockless lookup + */ + if (attrs[OVPN_A_PEER_REMOTE_IPV4] || attrs[OVPN_A_PEER_REMOTE_IPV6]) + ovpn_peer_hash_transp_addr(peer); spin_unlock_bh(&ovpn->lock); ovpn_peer_put(peer); diff --git a/drivers/net/ovpn/peer.c b/drivers/net/ovpn/peer.c index 68021c0c1783..a330892e82bf 100644 --- a/drivers/net/ovpn/peer.c +++ b/drivers/net/ovpn/peer.c @@ -189,6 +189,9 @@ int ovpn_peer_reset_sockaddr(struct ovpn_peer *peer, &(*__tbl1)[ovpn_get_hash_slot(*__tbl1, _key, _key_len)];\ }) +static void __ovpn_peer_hash_transp_addr(struct ovpn_peer *peer, + const struct ovpn_bind *bind); + /** * ovpn_peer_endpoints_update - update remote or local endpoint for peer * @peer: peer to update the remote endpoint for @@ -196,7 +199,6 @@ int ovpn_peer_reset_sockaddr(struct ovpn_peer *peer, */ void ovpn_peer_endpoints_update(struct ovpn_peer *peer, struct sk_buff *skb) { - struct hlist_nulls_head *nhead; struct sockaddr_storage ss; struct sockaddr_in6 *sa6; bool reset_cache = false; @@ -295,46 +297,23 @@ void ovpn_peer_endpoints_update(struct ovpn_peer *peer, struct sk_buff *skb) ovpn_nl_peer_float_notify(peer, &ss); /* rehashing is required only in MP mode as P2P has one peer - * only and thus there is no hashtable + * only and thus there is no hashtable. + * + * This function may be invoked concurrently, so re-read peer->bind + * under the proper locks and rehash against its current value. */ if (peer->ovpn->mode != OVPN_MODE_MP) return; + /* This function may be invoked concurrently, therefore another + * float may have happened in parallel: re-acquire the locks and + * rehash using the peer->bind->remote directly as key + */ spin_lock_bh(&peer->ovpn->lock); spin_lock_bh(&peer->lock); bind = rcu_dereference_protected(peer->bind, lockdep_is_held(&peer->lock)); - if (unlikely(!bind)) - goto unlock2; - - /* peer may have been concurrently removed between the caller's - * initial lookup and our acquisition of ovpn->lock; skip the - * rehash so we don't re-insert a removed peer - */ - if (unlikely(hlist_unhashed(&peer->hash_entry_id))) - goto unlock2; - - /* This function may be invoked concurrently, therefore another - * float may have happened in parallel: perform rehashing - * using the peer->bind->remote directly as key - */ - - switch (bind->remote.in4.sin_family) { - case AF_INET: - salen = sizeof(*sa); - break; - case AF_INET6: - salen = sizeof(*sa6); - break; - } - - /* remove old hashing */ - hlist_nulls_del_init_rcu(&peer->hash_entry_transp_addr); - /* re-add with new transport address */ - nhead = ovpn_get_hash_head(peer->ovpn->peers->by_transp_addr, - &bind->remote, salen); - hlist_nulls_add_head_rcu(&peer->hash_entry_transp_addr, nhead); -unlock2: + __ovpn_peer_hash_transp_addr(peer, bind); spin_unlock_bh(&peer->lock); spin_unlock_bh(&peer->ovpn->lock); return; @@ -902,6 +881,66 @@ bool ovpn_peer_check_by_src(struct ovpn_priv *ovpn, struct sk_buff *skb, return match; } +/* Move @peer to the by_transp_addr bucket matching its current bind. + * + * Caller must hold both peer->ovpn->lock and peer->lock, and must have + * already dereferenced a valid (non-NULL) peer->bind, passed in as @bind. + */ +static void __ovpn_peer_hash_transp_addr(struct ovpn_peer *peer, + const struct ovpn_bind *bind) +{ + struct hlist_nulls_head *nhead; + size_t salen; + + lockdep_assert_held(&peer->ovpn->lock); + lockdep_assert_held(&peer->lock); + + if (WARN_ON_ONCE(!bind)) + return; + + /* peer may have been concurrently removed between the caller's + * initial lookup and our acquisition of ovpn->lock; skip the + * rehash so we don't re-insert a removed peer + */ + if (unlikely(hlist_unhashed(&peer->hash_entry_id))) + return; + + switch (bind->remote.in4.sin_family) { + case AF_INET: + salen = sizeof(struct sockaddr_in); + break; + case AF_INET6: + salen = sizeof(struct sockaddr_in6); + break; + default: + return; + } + + /* remove old hashing (no-op if entry is not currently linked) */ + hlist_nulls_del_init_rcu(&peer->hash_entry_transp_addr); + /* re-add with current transport address */ + nhead = ovpn_get_hash_head(peer->ovpn->peers->by_transp_addr, + &bind->remote, salen); + hlist_nulls_add_head_rcu(&peer->hash_entry_transp_addr, nhead); +} + +void ovpn_peer_hash_transp_addr(struct ovpn_peer *peer) +{ + struct ovpn_bind *bind; + + lockdep_assert_held(&peer->ovpn->lock); + + /* rehashing makes sense only in multipeer mode */ + if (peer->ovpn->mode != OVPN_MODE_MP) + return; + + spin_lock_bh(&peer->lock); + bind = rcu_dereference_protected(peer->bind, + lockdep_is_held(&peer->lock)); + __ovpn_peer_hash_transp_addr(peer, bind); + spin_unlock_bh(&peer->lock); +} + void ovpn_peer_hash_vpn_ip(struct ovpn_peer *peer) { struct hlist_nulls_head *nhead; diff --git a/drivers/net/ovpn/peer.h b/drivers/net/ovpn/peer.h index 86c8cffada6d..dfa5c0037e02 100644 --- a/drivers/net/ovpn/peer.h +++ b/drivers/net/ovpn/peer.h @@ -150,6 +150,7 @@ struct ovpn_peer *ovpn_peer_get_by_id(struct ovpn_priv *ovpn, u32 peer_id); struct ovpn_peer *ovpn_peer_get_by_dst(struct ovpn_priv *ovpn, struct sk_buff *skb); void ovpn_peer_hash_vpn_ip(struct ovpn_peer *peer); +void ovpn_peer_hash_transp_addr(struct ovpn_peer *peer); bool ovpn_peer_check_by_src(struct ovpn_priv *ovpn, struct sk_buff *skb, struct ovpn_peer *peer); From patchwork Mon Jul 27 20:06:59 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Antonio Quartulli X-Patchwork-Id: 5132 Return-Path: Delivered-To: patchwork@openvpn.net Received: by 2002:a05:7000:190f:b0:87d:a69c:34be with SMTP id g15csp1598646maz; Mon, 27 Jul 2026 13:07:29 -0700 (PDT) X-Forwarded-Encrypted: i=2; AHgh+RrzuDJ49ULRcJb5dttsNpemNcjCa5sFtqS5wMgf8SNp6wMzO4lTAnYnmg8MrUMhhM/TlvStJcxml2s=@openvpn.net X-Received: by 2002:a05:6830:6f8b:b0:7e6:f083:130e with SMTP id 46e09a7af769-7eff7b1bd0amr725306a34.4.1785182849481; Mon, 27 Jul 2026 13:07:29 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1785182849; cv=none; d=google.com; s=arc-20260327; b=F0eW73SXnWfsVe1x0jgzgG02jjrmIl8C/7/PCtRcB+KomvWHNG3cq5oITN9XGnlJKp c6MGY94d1zy5NtUARGXf7m6bNTOL6I8XWWobns7b8yB8ZtJBp//JuWuVnlehhO1rKeiK fOQHJP9obre3wpUHK4u+w+Yu+8QEr8sGh4ohO5wiDqmQu6jzcPJIOP/ajT2nJZmgCqKm 9hhwPvzqbEaqZ8PDU88sNIYXmU0gVSbOR4ABdPrnLDHngoNjzjrB+aq95WCIaU8TEO8i /zKeO6Vot10MNXbNfn04b3Xe/TyI8uCLBAUfXIxCuvA2EStKgREG4MFWbPH8fV02g/OK BDYg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20260327; 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=fU92+gKt4yApHpIwY37R1b5J7gHtzpyeXo1Ak2efZCE=; fh=BsMg/B0Yb/hS/rzP5Npz4luh0IleZm8REk1XWiWRt2A=; b=JphRHEua94dfgv3pVwvJwuIRZ0hoCxyXmP92K5mIzLc4mYw+tsJ6MLjIwtBBCO8zkH 8E6vmLIc/5eEznFjqsSl0KA5cUAlZnAn64zxM6bbEENDOraz9v/Sqk3/7bQPWBercL8V 2v1eQ/2eftzSX/dVMwMQ/wNe2RVb3SMXa0+ZqWNPhxrV/aOUU7m3v4GzbzP80uilH5dt QsGObqe/fzIIjMAfg39jAORpXKtqg93dvHCP2/OHZgZqRkqNyJQZn26p3e/Oq2GHv1Rx dPpP6jpEWrpjlAn94cLPVpPckuaIM4pJ9Xaq+FAJlNGaXPCGW2UEeqSXtlvcLWsoWDeO TbFA==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@lists.sourceforge.net header.s=beta header.b="X5/e8RLg"; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=c+nFI+s3; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=hmFYp09V; dkim=neutral (body hash did not verify) header.i=@unstable.cc header.s=MBO0001 header.b=p9YL2Hf2; 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 46e09a7af769-7ee49bebab3si11285581a34.31.2026.07.27.13.07.29 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Mon, 27 Jul 2026 13:07:29 -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="X5/e8RLg"; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=c+nFI+s3; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=hmFYp09V; dkim=neutral (body hash did not verify) header.i=@unstable.cc header.s=MBO0001 header.b=p9YL2Hf2; 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=fU92+gKt4yApHpIwY37R1b5J7gHtzpyeXo1Ak2efZCE=; b=X5/e8RLgQE5Vg3UjfxbDoscdyb B996dAfQ16FcGprWFoAuUqUVdZK6ebLopS/QbOihhwxnKQqQKIxrOVFTbBg40tmANcL+4EI2c8JgV v0hBl9MMyQu99TLaybFyYvrOpH79AQHR0y10XgRSo96vRNYIBuNTYUx6wPz3y90BLpPY=; Received: from [127.0.0.1] (helo=sfs-ml-3.v29.lw.sourceforge.com) by sfs-ml-3.v29.lw.sourceforge.com with esmtp (Exim 4.95) (envelope-from ) id 1woRbf-0004Ij-Ot; Mon, 27 Jul 2026 20:07:24 +0000 Received: from [172.30.29.66] (helo=mx.sourceforge.net) by sfs-ml-3.v29.lw.sourceforge.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.95) (envelope-from ) id 1woRbe-0004Ic-GJ for openvpn-devel@lists.sourceforge.net; Mon, 27 Jul 2026 20:07:23 +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=Q5s+IliVCAtSxSuO/VpXlFTI87izFQhZPPXqXBnI1qQ=; b=c+nFI+s3f86h3qIO0Fl0WTXJZh 9C/dR617UcgafYNwAmV8dReH7Uzs3DQlMXY++o/FUJClCK1MvUcmR33/xoeS8/21ysZwXD0ILV4ls +THTHvWOhfoPYKd0Xod9kJYVp8MIMqNKd8AfNnZBMFUZRjqh2fQjYaVHvFClgEdQCmfw=; 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=Q5s+IliVCAtSxSuO/VpXlFTI87izFQhZPPXqXBnI1qQ=; b=hmFYp09VSguFhQc6oHPguBxqwt +4nNFhI7r/EjlCADyGLSEbvElm1CZxe4zq4/IcKQrMcWnxX/S/hXevCKLFHeKbODzloj/SGE8FN2K C+MP6Utrc3DvowBo5cs6QhAW7c9C1p+A8XAk5Cec0XJcOkT1Q1dkeK12UvLYutJrx4x0=; Received: from mout-p-102.mailbox.org ([80.241.56.152]) by sfi-mx-1.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.95) id 1woRbh-0002cm-RY for openvpn-devel@lists.sourceforge.net; Mon, 27 Jul 2026 20:07:23 +0000 Received: from smtp102.mailbox.org (smtp102.mailbox.org [IPv6:2001:67c:2050:b231:465::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-102.mailbox.org (Postfix) with ESMTPS id 4h88l702gMzKw2M; Mon, 27 Jul 2026 22:07:15 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=unstable.cc; s=MBO0001; t=1785182835; 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=Q5s+IliVCAtSxSuO/VpXlFTI87izFQhZPPXqXBnI1qQ=; b=p9YL2Hf2Ux0l6ZwCPUAWiL6HikyCvl0IDNh5S27xMw/lW4jLviN1uhUFH+IFVnTvFFDpyc dy4xwUrp/JBf1g0gQQPiCaExlVtiJQ4hinTmBjqPPYmufTCfia9h0mZpzWtzogsGnnxrN5 ujHUnKV70cXeIj3E5oKqir3XioQ4pVXMdYoOPUITOhviEMG9WaGHrDexQoIddHASTQtjtw oNgqYf1bvTtmXRazShOwtAF+A47nPkzpXM6M+Cx6qnnKGe4cwok4/zG+5IWFGRvKPnAoUA koTsjXs5doE/Yk13G+HOMZ3KR2v4n2j8Gnjl0lKIYum21i/i81sac+Qf3XnqkA== Authentication-Results: outgoing_mbo_mout; dkim=none; spf=pass (outgoing_mbo_mout: domain of a@unstable.cc designates 2001:67c:2050:b231:465::102 as permitted sender) smtp.mailfrom=a@unstable.cc From: Antonio Quartulli To: openvpn-devel@lists.sourceforge.net Date: Mon, 27 Jul 2026 22:06:59 +0200 Message-ID: <20260727200705.869169-4-a@unstable.cc> In-Reply-To: <20260727200705.869169-1-a@unstable.cc> References: <20260727200705.869169-1-a@unstable.cc> MIME-Version: 1.0 X-Rspamd-Queue-Id: 4h88l702gMzKw2M X-Spam-Score: -0.2 (/) X-Spam-Report: Spam detection software, running on the system "sfi-spamd-2.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 The cached local source address bind->local is updated in place on a live, RCU-published ovpn_bind while holding peer->lock: the UDP output error paths reset it (ovpn_udp4_output()/ovpn_udp6_output()) [...] Content analysis details: (-0.2 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 RCVD_IN_MSPIKE_H5 RBL: Excellent reputation (+5) [80.241.56.152 listed in wl.mailspike.net] -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.0 RCVD_IN_MSPIKE_WL Mailspike good senders X-Headers-End: 1woRbh-0002cm-RY Subject: [Openvpn-devel] [PATCH ovpn net v3 3/9] ovpn: fix data race reading cached local endpoint on TX path 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: 1871899891534364586 X-GMAIL-MSGID: 1871899891534364586 From: Antonio Quartulli The cached local source address bind->local is updated in place on a live, RCU-published ovpn_bind while holding peer->lock: the UDP output error paths reset it (ovpn_udp4_output()/ovpn_udp6_output()) and the RX float path learns it (ovpn_peer_endpoints_update()). The UDP TX fast path and the netlink dump, however, read bind->local holding only rcu_read_lock(), never peer->lock. For bind->local.ipv6 this is a torn read: struct in6_addr is 128 bit and is copied as multiple words, so a concurrent in-place update can make a reader observe a mix of the old and new address. The mangled source address then feeds ip6_dst_lookup_flow() and udp_tunnel6_xmit_skb(). For bind->local.ipv4 (a single aligned word) it is a data race without tearing. A spinlock on the per-packet TX path is not acceptable, and READ_ONCE()/WRITE_ONCE() cannot atomically access the 128-bit IPv6 address (the >8-byte access is rejected at build time and per-word accesses still can't yield a consistent snapshot). Serialize the IPv6 field with a per-peer seqcount_spinlock_t tied to the existing peer->lock: the in-place writers (already under peer->lock) bump it, and readers take a lock-free read_seqcount_begin()/retry() snapshot via the new ovpn_peer_local_ipv6() helper. The single-word IPv4 field is handled with plain READ_ONCE()/WRITE_ONCE(). bind->remote is untouched: it is immutable for a given bind object (only swapped via whole-bind RCU replacement), so reading it locklessly remains safe. Fixes: 08857b5ec5d9 ("ovpn: implement basic TX path (UDP)") Signed-off-by: Antonio Quartulli --- drivers/net/ovpn/netlink.c | 13 +++++++++++-- drivers/net/ovpn/peer.c | 26 +++++++++++++++++++++++++- drivers/net/ovpn/peer.h | 6 ++++++ drivers/net/ovpn/udp.c | 17 +++++++++++++---- 4 files changed, 55 insertions(+), 7 deletions(-) diff --git a/drivers/net/ovpn/netlink.c b/drivers/net/ovpn/netlink.c index 4dad85294198..8e21fa3e7822 100644 --- a/drivers/net/ovpn/netlink.c +++ b/drivers/net/ovpn/netlink.c @@ -610,14 +610,23 @@ static int ovpn_nl_send_peer(struct sk_buff *skb, const struct genl_info *info, bind = rcu_dereference(peer->bind); if (bind) { if (bind->remote.in4.sin_family == AF_INET) { + /* bind->local is updated in place under peer->lock; + * READ_ONCE() pairs with the WRITE_ONCE() updaters + */ if (nla_put_in_addr(skb, OVPN_A_PEER_REMOTE_IPV4, bind->remote.in4.sin_addr.s_addr) || nla_put_net16(skb, OVPN_A_PEER_REMOTE_PORT, bind->remote.in4.sin_port) || nla_put_in_addr(skb, OVPN_A_PEER_LOCAL_IPV4, - bind->local.ipv4.s_addr)) + READ_ONCE(bind->local.ipv4.s_addr))) goto err_unlock; } else if (bind->remote.in4.sin_family == AF_INET6) { + struct in6_addr local_ipv6; + + /* read the 128-bit local address under the peer + * seqcount to avoid a torn read + */ + ovpn_peer_local_ipv6(peer, bind, &local_ipv6); if (nla_put_in6_addr(skb, OVPN_A_PEER_REMOTE_IPV6, &bind->remote.in6.sin6_addr) || nla_put_u32(skb, OVPN_A_PEER_REMOTE_IPV6_SCOPE_ID, @@ -625,7 +634,7 @@ static int ovpn_nl_send_peer(struct sk_buff *skb, const struct genl_info *info, nla_put_net16(skb, OVPN_A_PEER_REMOTE_PORT, bind->remote.in6.sin6_port) || nla_put_in6_addr(skb, OVPN_A_PEER_LOCAL_IPV6, - &bind->local.ipv6)) + &local_ipv6)) goto err_unlock; } } diff --git a/drivers/net/ovpn/peer.c b/drivers/net/ovpn/peer.c index a330892e82bf..3554da01e406 100644 --- a/drivers/net/ovpn/peer.c +++ b/drivers/net/ovpn/peer.c @@ -113,6 +113,7 @@ struct ovpn_peer *ovpn_peer_new(struct ovpn_priv *ovpn, u32 id) RCU_INIT_POINTER(peer->bind, NULL); ovpn_crypto_state_init(&peer->crypto); spin_lock_init(&peer->lock); + seqcount_spinlock_init(&peer->bind_local_seq, &peer->lock); kref_init(&peer->refcount); ovpn_peer_stats_init(&peer->vpn_stats); ovpn_peer_stats_init(&peer->link_stats); @@ -176,6 +177,27 @@ int ovpn_peer_reset_sockaddr(struct ovpn_peer *peer, return 0; } +/** + * ovpn_peer_local_ipv6 - read the cached local IPv6 endpoint of a peer + * @peer: the peer owning the binding + * @bind: the binding to read the local address from + * @dst: where the local IPv6 address is copied to + * + * bind->local is updated in place under peer->lock (TX error path and RX + * float path). Read the 128-bit address under the peer seqcount so that + * lockless readers never observe a torn value. + */ +void ovpn_peer_local_ipv6(const struct ovpn_peer *peer, + const struct ovpn_bind *bind, struct in6_addr *dst) +{ + unsigned int seq; + + do { + seq = read_seqcount_begin(&peer->bind_local_seq); + *dst = bind->local.ipv6; + } while (read_seqcount_retry(&peer->bind_local_seq, seq)); +} + /* variable name __tbl2 needs to be different from __tbl1 * in the macro below to avoid confusing clang */ @@ -238,7 +260,7 @@ void ovpn_peer_endpoints_update(struct ovpn_peer *peer, struct sk_buff *skb) netdev_name(peer->ovpn->dev), peer->id, &bind->local.ipv4.s_addr, &ip_hdr(skb)->daddr); - bind->local.ipv4.s_addr = ip_hdr(skb)->daddr; + WRITE_ONCE(bind->local.ipv4.s_addr, ip_hdr(skb)->daddr); reset_cache = true; } break; @@ -269,7 +291,9 @@ void ovpn_peer_endpoints_update(struct ovpn_peer *peer, struct sk_buff *skb) netdev_name(peer->ovpn->dev), peer->id, &bind->local.ipv6, &ipv6_hdr(skb)->daddr); + write_seqcount_begin(&peer->bind_local_seq); bind->local.ipv6 = ipv6_hdr(skb)->daddr; + write_seqcount_end(&peer->bind_local_seq); reset_cache = true; } break; diff --git a/drivers/net/ovpn/peer.h b/drivers/net/ovpn/peer.h index dfa5c0037e02..c0994c606554 100644 --- a/drivers/net/ovpn/peer.h +++ b/drivers/net/ovpn/peer.h @@ -10,6 +10,7 @@ #ifndef _NET_OVPN_OVPNPEER_H_ #define _NET_OVPN_OVPNPEER_H_ +#include #include #include @@ -56,6 +57,8 @@ * @link_stats: per-peer link/transport TX/RX stats * @delete_reason: why peer was deleted (i.e. timeout, transport error, ..) * @lock: protects binding to peer (bind) and keepalive* fields + * @bind_local_seq: seqcount serializing in-place updates of bind->local + * (done under @lock) against lockless readers on the TX path * @refcount: reference counter * @rcu: used to free peer in an RCU safe way * @release_entry: entry for the socket release list @@ -110,6 +113,7 @@ struct ovpn_peer { struct ovpn_peer_stats link_stats; enum ovpn_del_peer_reason delete_reason; spinlock_t lock; /* protects bind and keepalive* */ + seqcount_spinlock_t bind_local_seq; /* protects bind->local */ struct kref refcount; struct rcu_head rcu; struct llist_node release_entry; @@ -151,6 +155,8 @@ struct ovpn_peer *ovpn_peer_get_by_dst(struct ovpn_priv *ovpn, struct sk_buff *skb); void ovpn_peer_hash_vpn_ip(struct ovpn_peer *peer); void ovpn_peer_hash_transp_addr(struct ovpn_peer *peer); +void ovpn_peer_local_ipv6(const struct ovpn_peer *peer, + const struct ovpn_bind *bind, struct in6_addr *dst); bool ovpn_peer_check_by_src(struct ovpn_priv *ovpn, struct sk_buff *skb, struct ovpn_peer *peer); diff --git a/drivers/net/ovpn/udp.c b/drivers/net/ovpn/udp.c index 7f69e8890b5b..17d65d1595ed 100644 --- a/drivers/net/ovpn/udp.c +++ b/drivers/net/ovpn/udp.c @@ -147,7 +147,10 @@ static int ovpn_udp4_output(struct ovpn_peer *peer, struct ovpn_bind *bind, { struct rtable *rt; struct flowi4 fl = { - .saddr = bind->local.ipv4.s_addr, + /* bind->local is updated in place under peer->lock; a single + * aligned word is read/written atomically via {READ,WRITE}_ONCE + */ + .saddr = READ_ONCE(bind->local.ipv4.s_addr), .daddr = bind->remote.in4.sin_addr.s_addr, .fl4_sport = inet_sk(sk)->inet_sport, .fl4_dport = bind->remote.in4.sin_port, @@ -169,7 +172,7 @@ static int ovpn_udp4_output(struct ovpn_peer *peer, struct ovpn_bind *bind, */ fl.saddr = 0; spin_lock_bh(&peer->lock); - bind->local.ipv4.s_addr = 0; + WRITE_ONCE(bind->local.ipv4.s_addr, 0); spin_unlock_bh(&peer->lock); dst_cache_reset(cache); } @@ -178,7 +181,7 @@ static int ovpn_udp4_output(struct ovpn_peer *peer, struct ovpn_bind *bind, if (IS_ERR(rt) && PTR_ERR(rt) == -EINVAL) { fl.saddr = 0; spin_lock_bh(&peer->lock); - bind->local.ipv4.s_addr = 0; + WRITE_ONCE(bind->local.ipv4.s_addr, 0); spin_unlock_bh(&peer->lock); dst_cache_reset(cache); @@ -224,7 +227,6 @@ static int ovpn_udp6_output(struct ovpn_peer *peer, struct ovpn_bind *bind, int ret; struct flowi6 fl = { - .saddr = bind->local.ipv6, .daddr = bind->remote.in6.sin6_addr, .fl6_sport = inet_sk(sk)->inet_sport, .fl6_dport = bind->remote.in6.sin6_port, @@ -233,6 +235,11 @@ static int ovpn_udp6_output(struct ovpn_peer *peer, struct ovpn_bind *bind, .flowi6_oif = bind->remote.in6.sin6_scope_id, }; + /* bind->local is updated in place under peer->lock; read the 128-bit + * address under the peer seqcount to avoid a torn read + */ + ovpn_peer_local_ipv6(peer, bind, &fl.saddr); + local_bh_disable(); dst = dst_cache_get_ip6(cache, &fl.saddr); if (dst) @@ -245,7 +252,9 @@ static int ovpn_udp6_output(struct ovpn_peer *peer, struct ovpn_bind *bind, */ fl.saddr = in6addr_any; spin_lock_bh(&peer->lock); + write_seqcount_begin(&peer->bind_local_seq); bind->local.ipv6 = in6addr_any; + write_seqcount_end(&peer->bind_local_seq); spin_unlock_bh(&peer->lock); dst_cache_reset(cache); } From patchwork Mon Jul 27 20:07:00 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Antonio Quartulli X-Patchwork-Id: 5130 Return-Path: Delivered-To: patchwork@openvpn.net Received: by 2002:a05:7000:190f:b0:87d:a69c:34be with SMTP id g15csp1598655maz; Mon, 27 Jul 2026 13:07:29 -0700 (PDT) X-Forwarded-Encrypted: i=2; AHgh+RozkHdF5HZIfpJYS0VJreYsL+Vv17ppISSdQaSw43KguIf4MXfVoRRcPpqvX252hQ3IG/jIXFgtmnE=@openvpn.net X-Received: by 2002:a9d:4c86:0:b0:7eb:c618:434f with SMTP id 46e09a7af769-7effa7e13b9mr149589a34.0.1785182849735; Mon, 27 Jul 2026 13:07:29 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1785182849; cv=none; d=google.com; s=arc-20260327; b=KZdHdmJIi9wn5cvDJqvDV7b8BXKTRAupF/uqOWRWVeu+y9X/ojS+gfsuyR+/pmZHjr S7lazClkOso3GdtmN7KZfatxD8ci/daAImWF+4ehQkvlWHuoVwaHP4JSZEUywCLmnxIw FG/JnrbjO0zlDvcXaTAg0zIka103ODab5eheKZoV9NPGygniz+OF2gk3lvi5Bry1ZGn4 j+FaZnEjoBpopfmeRHPezbliMrWQAx+yh1nXZaQupZvxKOQkQZQFLiSRl4K8vfWBwRSU Ph9W2kDLpvLzbmz9YawAUywOMlkCUTC+2jCa++MQDncEmBaHmT7rAkcV8nfsc8shqt4o aUJw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20260327; 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=Oj8Z5EuLMRxrE2iZMLlUC+4BrcJM5h7LPIlkZgChsak=; fh=BsMg/B0Yb/hS/rzP5Npz4luh0IleZm8REk1XWiWRt2A=; b=Zh6Z+G23R4gM39AA8W3s8W49k2EYqaOf+780lspNniGL61NWUoDbQ/XOrtOEjJ9okC R7J2E6NA7+/TFfnpGY4470oP6LuyecpvkeXCfcrG8WATiYw7XbXW0blOyAPEnYWFh6vV eYbmMzXXDm/fhzFMx448eMbdldVfIQsM6wkTOh/Wr6olwfxaFaZ4tjtE80/NpsqhisCz TSx1sHKBgr8oMHozG4v5+vwm4/Z0qpQPM61+ZjFZSCq0+XBSOdJ9qzhg2DRKxUljb6Nu 5QMZhd/sxXWEEEQHDhXY/7ZCoZmsefhbX6i6kxXShjYCDnKuaKDMlGhMtsRxOYoyCFwb yYgA==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@lists.sourceforge.net header.s=beta header.b="cEGA4/KN"; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=Jl5Ek1zt; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=X3xT1Izo; dkim=neutral (body hash did not verify) header.i=@unstable.cc header.s=MBO0001 header.b=LLfawQVS; 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 46e09a7af769-7ee49e15ebbsi11073987a34.69.2026.07.27.13.07.29 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Mon, 27 Jul 2026 13:07:29 -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="cEGA4/KN"; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=Jl5Ek1zt; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=X3xT1Izo; dkim=neutral (body hash did not verify) header.i=@unstable.cc header.s=MBO0001 header.b=LLfawQVS; 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=Oj8Z5EuLMRxrE2iZMLlUC+4BrcJM5h7LPIlkZgChsak=; b=cEGA4/KN2QM+drzV8fmc6reilm J49x/FyO9mCsXmvKzCY1jICG9Xks4uHnLGLekUErdy+jlxGDG9AcP8leuSeVkCWLGnE6yBIwkGRZM Ad5lKzb+j/DmmRbvwP/F/aCy/41XV2HwkUuLGmf/caPbm1iYyGulaICP+Ii5VCkWcxhM=; Received: from [127.0.0.1] (helo=sfs-ml-2.v29.lw.sourceforge.com) by sfs-ml-2.v29.lw.sourceforge.com with esmtp (Exim 4.95) (envelope-from ) id 1woRbh-00063U-O3; Mon, 27 Jul 2026 20:07:26 +0000 Received: from [172.30.29.66] (helo=mx.sourceforge.net) by sfs-ml-2.v29.lw.sourceforge.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.95) (envelope-from ) id 1woRbg-000638-6N for openvpn-devel@lists.sourceforge.net; Mon, 27 Jul 2026 20:07:24 +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=ixElgIOpjex/L7zdwx7lUWOiWK5w4EbBc2Uvh57Z4fI=; b=Jl5Ek1ztTDc7FaZvJLO+L8nbS6 cu8W3c/9a7W61y5dreEuY+Mh9LUkk7DIlL5gH1P2Y/25KNW4uyw6thdCL5nPShZNGmW2buAUZRZ50 frm+jWI3Alno0CLvTO3Ra/HPGuobrR5ptgFFrfoxoSLWA5v5kj74wNcppdaGfSxTwPSQ=; 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=ixElgIOpjex/L7zdwx7lUWOiWK5w4EbBc2Uvh57Z4fI=; b=X3xT1IzoUZKZKgxVuMq6dvt6Ri HPFhYbJhUydiUDb7lFyu0kzwy0PaSo+XJX89MYaW+b/DCIrvUex+yjSB4TkGTb2y9+tLiLhYGcmEE OXnNH/Eqa3HkPUhygQ6XuGJBxlkWOkT5t8qhXgqr20NX8sNrIAToAIET2gLXDVESfotk=; Received: from mout-p-102.mailbox.org ([80.241.56.152]) by sfi-mx-1.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.95) id 1woRbi-0002cp-Nt for openvpn-devel@lists.sourceforge.net; Mon, 27 Jul 2026 20:07:24 +0000 Received: from smtp102.mailbox.org (smtp102.mailbox.org [IPv6:2001:67c:2050:b231:465::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-102.mailbox.org (Postfix) with ESMTPS id 4h88l74C05zKw2N; Mon, 27 Jul 2026 22:07:15 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=unstable.cc; s=MBO0001; t=1785182835; 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=ixElgIOpjex/L7zdwx7lUWOiWK5w4EbBc2Uvh57Z4fI=; b=LLfawQVSg+Y4jKWZP/gc/QI0SHIcuFoAZcvH5Uv/wMZw3M9GF1zqqZDPEkCSrvEkdDkAXH susfja5Q1P6qia15s8qy+qMe9u59ByYvi4ZXcgVY3bMTqULknsX/jV3c9wA8hrkz7CiT9x 8T4dHmYV9y8GajFahxZ2XUdnf99FwM1Viy5CybQaHrRv5K8bunvR6Qn+gG6wsZ0jEUwIcO 7/58gmmuucu6H24dxk0qRPHrbKxzrjLenA2LuqU4xx66vw0hOCa/hi51e2MqqBHXmxa25F KBp6yWMC83ibFUn0HwhrSIIoeP+QLHq+HCH0VfEFGU6paafbPPAFFDZnWlrKcg== Authentication-Results: outgoing_mbo_mout; dkim=none; spf=pass (outgoing_mbo_mout: domain of a@unstable.cc designates 2001:67c:2050:b231:465::102 as permitted sender) smtp.mailfrom=a@unstable.cc From: Antonio Quartulli To: openvpn-devel@lists.sourceforge.net Date: Mon, 27 Jul 2026 22:07:00 +0200 Message-ID: <20260727200705.869169-5-a@unstable.cc> In-Reply-To: <20260727200705.869169-1-a@unstable.cc> References: <20260727200705.869169-1-a@unstable.cc> MIME-Version: 1.0 X-Rspamd-Queue-Id: 4h88l74C05zKw2N 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 Some subsystems, like BPF SOCKMAP, set sk_user_data without actually setting the encap_type. For this reason, we must make sure that the type is the one ovpn expects before dereferencing sk_user_data. Content analysis details: (-0.2 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 RCVD_IN_MSPIKE_H5 RBL: Excellent reputation (+5) [80.241.56.152 listed in wl.mailspike.net] -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature 0.0 RCVD_IN_MSPIKE_WL Mailspike good senders X-Headers-End: 1woRbi-0002cp-Nt Subject: [Openvpn-devel] [PATCH ovpn net v3 4/9] ovpn: ensure socket is owned by ovpn before deref sk_user_data 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: 1871899892164428237 X-GMAIL-MSGID: 1871899892164428237 From: Antonio Quartulli Some subsystems, like BPF SOCKMAP, set sk_user_data without actually setting the encap_type. For this reason, we must make sure that the type is the one ovpn expects before dereferencing sk_user_data. Failing to do so may lead to out-of-bounds reads. Fixes: f6226ae7a0cd ("ovpn: introduce the ovpn_socket object") Signed-off-by: Antonio Quartulli --- drivers/net/ovpn/socket.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/net/ovpn/socket.c b/drivers/net/ovpn/socket.c index 517caa64a4fe..6cbeb2caaeec 100644 --- a/drivers/net/ovpn/socket.c +++ b/drivers/net/ovpn/socket.c @@ -162,6 +162,15 @@ struct ovpn_socket *ovpn_socket_new(struct socket *sock, struct ovpn_peer *peer) rcu_read_lock(); ovpn_sock = rcu_dereference_sk_user_data(sk); if (ovpn_sock) { + /* something else filled the sk_user_data without + * setting the encap_type. Reject the socket. + */ + if (!type) { + ovpn_sock = ERR_PTR(-EBUSY); + rcu_read_unlock(); + goto sock_release; + } + /* socket owned by another ovpn instance, we can't use it */ if (ovpn_sock->ovpn != peer->ovpn) { ovpn_sock = ERR_PTR(-EBUSY); From patchwork Mon Jul 27 20:07:01 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Antonio Quartulli X-Patchwork-Id: 5134 Return-Path: Delivered-To: patchwork@openvpn.net Received: by 2002:a05:7000:190f:b0:87d:a69c:34be with SMTP id g15csp1598667maz; Mon, 27 Jul 2026 13:07:31 -0700 (PDT) X-Forwarded-Encrypted: i=2; AHgh+RqHjM3ZOyJa+6j/3gYcpEq+QfMICk8uTSANUB2SPLrF01QV44KD2q1a+vWNuvXkn0p89CuJH0IvOdk=@openvpn.net X-Received: by 2002:a05:6809:245:20b0:49e:d43f:1b94 with SMTP id 5614622812f47-4ad57fa31bcmr145952b6e.0.1785182851015; Mon, 27 Jul 2026 13:07:31 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1785182851; cv=none; d=google.com; s=arc-20260327; b=q/gXsZwgE+9yMY87IkLzxI3ttqlgEd6zZyMweB0CiCS9H0JCKL4ug8EnM9GVty9McO qR2tnJF0A35c09npqzzFfo04/fv71nkwftM1DGmvPnsWHRP84KKLNo/VdQ1QHBos1hlC AxVEDVvIOsBscmk/gQjwNUddomNHr9s4c8d8n4K69qtl+7krXE3U38F0m8uwbo5mYYpt rT4dl/MmYTQx9XQL33ye1rgs9TWNvp6pyBxUA/U8B+flDbGuJSsH1LVmA3IMofuM14Qg XKePlrWwdrAIQBh3RhwM8s/cKdBXyBLfT7QKQLCORwTmU7bB2rru950ZCCvRAtKy08JC ejmg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20260327; 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=xv0zSlUOk2szzstBzlGxyib7OVgXa2IUsOBKeaufRp4=; fh=BsMg/B0Yb/hS/rzP5Npz4luh0IleZm8REk1XWiWRt2A=; b=jf3x2FW0vMcpcrmWboQsl2FLM5nX7rQR9to+p0LscdIS5FTbiurH/7Q/0rLO+EHiQx sWyhVbOgSOqGU3pYmiMm7AO0YIVwTqGdM5n4x2kCPFlg9SblJUZVjlMxEftTPilOxo4a geTlbVG0RbpiQ4Tt1hUBftj1JbECnYEQYvPQYEH8bWlbAyxnyaVXsbXP89bHQQyytp6B ywqXX1EltJgz/3yVYiabp8DeSZf/P1Sp0j3XsdPXQITMLIV6UcLFLN7zvGs/nmNzYpUH l+8zNWd5vp3YtP8+/LreyIBcu7R3GwcXyFz4UGRTsCcqFGL1XjB03O7j9QLnwU6CehVE 6kSg==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@lists.sourceforge.net header.s=beta header.b=JeVWMwFn; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=YMGPaFDO; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=PPbNpmXv; dkim=neutral (body hash did not verify) header.i=@unstable.cc header.s=MBO0001 header.b=FkNWVE0I; 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-4ab4b3faac3si9225718b6e.66.2026.07.27.13.07.30 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Mon, 27 Jul 2026 13:07:31 -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=JeVWMwFn; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=YMGPaFDO; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=PPbNpmXv; dkim=neutral (body hash did not verify) header.i=@unstable.cc header.s=MBO0001 header.b=FkNWVE0I; 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=xv0zSlUOk2szzstBzlGxyib7OVgXa2IUsOBKeaufRp4=; b=JeVWMwFnZr+cOsM2FArJw6mzrh EjtE5/YbiSTbtr3mjDSsEb7k1cWHBm7TyGmZY/DiQBMu1vMkgTnkuJIQwkLX/gl21RaLAfKF4ejZS swXyPRnNP+XuhYoFyBgTIalL43X4dqWx2138U23bzK6+XLTsTLr5vHrJfYPSROMm3wfk=; 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 1woRbm-0008Lt-8n; Mon, 27 Jul 2026 20:07:27 +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 1woRbi-0008Le-OU for openvpn-devel@lists.sourceforge.net; Mon, 27 Jul 2026 20:07:24 +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=SxS5EazCkfznQezlhD63nt8VnLSO3xzQC/LLduZkApU=; b=YMGPaFDO7Ui7+2ukT8PzwuRBeL qhclj7VPKWqAqyjmL3aCJ9C98qLSikJdcmWNQL5C6vDTuaTvjULen8tTzVmh4NQ6cQLjUGRtSneD6 ivgrWTPMIBgbpk2GuLICj2REszNtBDVlXk8UPSFyULsdPIXsOLw3EaPj7KdNZpZ4XKao=; 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=SxS5EazCkfznQezlhD63nt8VnLSO3xzQC/LLduZkApU=; b=PPbNpmXvlU32N6e7oLL2IIEuNK 8DRoKzI4D4BCGGkmExkXq4RNCD6UQf1NSVAjG15EQ5b0EdzZkx3tncQBVyak/rwZYFGwha6qKuBc+ qEbo7UsIIrUtU73jZ5C+3wtsg/eLrJk1HQwjgmvucDSngH+JIDFd8TQUuMsByGyL+ePM=; Received: from mout-p-102.mailbox.org ([80.241.56.152]) by sfi-mx-2.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.95) id 1woRbf-0001PK-NQ for openvpn-devel@lists.sourceforge.net; Mon, 27 Jul 2026 20:07:24 +0000 Received: from smtp102.mailbox.org (smtp102.mailbox.org [IPv6:2001:67c:2050:b231:465::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-102.mailbox.org (Postfix) with ESMTPS id 4h88l80kYVzKw2d; Mon, 27 Jul 2026 22:07:16 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=unstable.cc; s=MBO0001; t=1785182836; 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=SxS5EazCkfznQezlhD63nt8VnLSO3xzQC/LLduZkApU=; b=FkNWVE0IJj9XDGynifc4JhZ9PwHEP3acyA6dxnigryZ/8zzFH5pUqvtUuYYc9Td6st9K32 tFYSUM7LNQ6tb3kQG/kJgge7BwyLUEv5pZ6bHbxuf2AOSgzTIGzmTRAQTYvTiVAXv6T8Lg 6KLMuI2qN2A1+HKIsiHXu45fA9aP9fwEaDE25nnGN6+3upNfzZ//L5avNSEv2QieueNAi6 qtc8v5V27wYHUw0AOgUiyTN5KOg0eYtjX7tM0tMg91yCbyt/+SWAR2SWuht03mudHdWQpo MoNGaWlqgrnKZPK8gCmgAp/UJnLelCnzHerbZkn36Aw9WtMEp0zwVwLhvQyPsQ== Authentication-Results: outgoing_mbo_mout; dkim=none; spf=pass (outgoing_mbo_mout: domain of a@unstable.cc designates 2001:67c:2050:b231:465::102 as permitted sender) smtp.mailfrom=a@unstable.cc From: Antonio Quartulli To: openvpn-devel@lists.sourceforge.net Date: Mon, 27 Jul 2026 22:07:01 +0200 Message-ID: <20260727200705.869169-6-a@unstable.cc> In-Reply-To: <20260727200705.869169-1-a@unstable.cc> References: <20260727200705.869169-1-a@unstable.cc> MIME-Version: 1.0 X-Rspamd-Queue-Id: 4h88l80kYVzKw2d X-Spam-Score: -0.2 (/) X-Spam-Report: Spam detection software, running on the system "sfi-spamd-2.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 ovpn_peer_endpoints_update() builds the new remote endpoint in an on-stack struct sockaddr_storage that is left uninitialized. For IPv4 only sin_family/sin_addr/sin_port are written, leaving the 8-byt [...] Content analysis details: (-0.2 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 RCVD_IN_MSPIKE_H5 RBL: Excellent reputation (+5) [80.241.56.152 listed in wl.mailspike.net] -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.0 RCVD_IN_MSPIKE_WL Mailspike good senders X-Headers-End: 1woRbf-0001PK-NQ Subject: [Openvpn-devel] [PATCH ovpn net v3 5/9] ovpn: zero-initialize sockaddr before learning a floated endpoint 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: 1871899892959295152 X-GMAIL-MSGID: 1871899892959295152 From: Antonio Quartulli ovpn_peer_endpoints_update() builds the new remote endpoint in an on-stack struct sockaddr_storage that is left uninitialized. For IPv4 only sin_family/sin_addr/sin_port are written, leaving the 8-byte sin_zero padding as stack garbage (for IPv6, sin6_flowinfo is left uninitialized likewise). ovpn_peer_reset_sockaddr() -> ovpn_bind_from_sockaddr() then memcpy()s sizeof(struct sockaddr_in)/sizeof(struct sockaddr_in6) bytes - padding included - into bind->remote. That buffer is later hashed with jhash() over the same length to place the peer in the by_transp_addr table, so the garbage padding lands the floated peer in an essentially random bucket. Lockless lookups in ovpn_peer_get_by_transp_addr() build their key from a zero-initialized sockaddr_storage, compute a different bucket and fail to find the peer. This is also a plain use of uninitialized stack memory in jhash(). Zero-initialize the sockaddr_storage, matching what the lookup and netlink paths already do. Fixes: f0281c1d3732 ("ovpn: add support for updating local or remote UDP endpoint") Signed-off-by: Antonio Quartulli --- drivers/net/ovpn/peer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ovpn/peer.c b/drivers/net/ovpn/peer.c index 3554da01e406..be772d14ae41 100644 --- a/drivers/net/ovpn/peer.c +++ b/drivers/net/ovpn/peer.c @@ -221,7 +221,7 @@ static void __ovpn_peer_hash_transp_addr(struct ovpn_peer *peer, */ void ovpn_peer_endpoints_update(struct ovpn_peer *peer, struct sk_buff *skb) { - struct sockaddr_storage ss; + struct sockaddr_storage ss = {}; struct sockaddr_in6 *sa6; bool reset_cache = false; struct sockaddr_in *sa; From patchwork Mon Jul 27 20:07:02 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Antonio Quartulli X-Patchwork-Id: 5136 Return-Path: Delivered-To: patchwork@openvpn.net Received: by 2002:a05:7000:190f:b0:87d:a69c:34be with SMTP id g15csp1598707maz; Mon, 27 Jul 2026 13:07:34 -0700 (PDT) X-Forwarded-Encrypted: i=2; AHgh+RqFtvBNIjvjYMxxIqGBwMQwGjcJh2cbunA4LkuE4dffFGocKB1vgSeyyNBnPVJnnikYwsR216/yEj4=@openvpn.net X-Received: by 2002:a05:6820:2008:b0:6a1:3e91:dca8 with SMTP id 006d021491bc7-6aaff8f2c5emr7904156eaf.24.1785182854209; Mon, 27 Jul 2026 13:07:34 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1785182854; cv=none; d=google.com; s=arc-20260327; b=gxNr0jTGQNeyeEHdyqtamQcuKHN9F+q4DFYFdSMC63WFW2bsEOaTl7yI8Zw6wg9nJ1 rUb27A739xlG0UumCXkrD+BmJIOK65mNQ9VVB729paAyv4Uv61IdgJ7BckXG+FC+9GDw h+hrNpbWLHRvHGSU6ZStWwMjvw4qXzNPSdMume6NlF7DR2LyZ//JPEABzVjWKx+4pNkQ V35R5F/nitgN2q79/KzyKylWTlpUpE4Bdcx0bWTNCH7CqsOb0DbdId7LoPfDLZ+hlIAv L4XPLRLuITj+RXbqrwK6yP3PfdI4gmq7DcfEgvdy+qw76UWDCxwbcGUigZrQF+XQd12A w6HA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20260327; 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=c3LMynfM/+OH0kRIAcfdfck6JfPCIhuWHv84WnQ5XCA=; fh=BsMg/B0Yb/hS/rzP5Npz4luh0IleZm8REk1XWiWRt2A=; b=OiZG/m3Sf/HXLI40GeqC/W45FWa/YXumLKuAXm3HtcUxBrq1Wr+xBwp+kvHaTtCVsF 32Nkmw4IBex7B3eniaFfL/WRI/8hSc3QpL92pPbW4hy7Mt6q6oDzLclwPZURqEsVPt+a s8RRaNUafnfx2S2LXdowrqGAqrxUgAw1vRrZitL5PW7uxmogkRJbMu4RFYfNH4wzAqEq hw6ibwBAAkVYz5CDLKohze+RjCPcIJ/4O3DTXpOxjiS67xEUoQUVpnw1P54mcrs1652X Isl2lbsydOCWAzNQdjMhAuafx+s3p1muSkyG4TjNwG645kYdFza7702fA3M+hZ5uj6Vw 5NVA==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@lists.sourceforge.net header.s=beta header.b=QofmzTc7; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=KGTOD6IV; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=GyR8MZO6; dkim=neutral (body hash did not verify) header.i=@unstable.cc header.s=MBO0001 header.b=zfXcc6E1; 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 586e51a60fabf-457aa18e57esi13456497fac.12.2026.07.27.13.07.33 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Mon, 27 Jul 2026 13:07:34 -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=QofmzTc7; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=KGTOD6IV; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=GyR8MZO6; dkim=neutral (body hash did not verify) header.i=@unstable.cc header.s=MBO0001 header.b=zfXcc6E1; 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=c3LMynfM/+OH0kRIAcfdfck6JfPCIhuWHv84WnQ5XCA=; b=QofmzTc7KUAnlNQReshSIjl5u0 JzWQoclltwLvy2IAhzdHGiRyAYekbv5h2eMqJBM2C3AcCyyWjVuIzQnsgD69aBpIaxGule2Rg96fR QTrvHV+/BuucSDDXQYo3Ms+n2NS/O20h5B2+A/5gzRj9CVAAj8521ZoyN0iUzygiCTr4=; Received: from [127.0.0.1] (helo=sfs-ml-3.v29.lw.sourceforge.com) by sfs-ml-3.v29.lw.sourceforge.com with esmtp (Exim 4.95) (envelope-from ) id 1woRbm-0004Jc-Gv; Mon, 27 Jul 2026 20:07:31 +0000 Received: from [172.30.29.66] (helo=mx.sourceforge.net) by sfs-ml-3.v29.lw.sourceforge.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.95) (envelope-from ) id 1woRbi-0004JD-I4 for openvpn-devel@lists.sourceforge.net; Mon, 27 Jul 2026 20:07:27 +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=IU8+7nKGLXOwf74BQT5HAZ0RSMUWAe0anDASGXWrYcM=; b=KGTOD6IVTY6HBMDLARd71wMeU5 f/IA66quBNWOjlh6aeEwMCWooq/7bfitc5nOnPvkkgxvOjgLOERRjrIUFQiFfAu9WH8BwjTEAISZr 3tMWd+EGLRKR07WbF71dcrfOycuwc8YYYIzpU5C+mie+iSF/UcHUzCmAVbaTnQrg6GM0=; 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=IU8+7nKGLXOwf74BQT5HAZ0RSMUWAe0anDASGXWrYcM=; b=GyR8MZO6kDUDNTu0UbGHdhLjOt ZbzXA3XshLljrz+ZhnOMp47xBkIEn8OYkKvZE2cNB8+o6MrSJ1UAQ8FXb9waMX+iO2AJMvEkZ1JFl 6CPOjI7xjA/Wp8ReHIRrQdDM4vzgw7+gWRXRpEDUF0T/Nv3KCjLA9yP7aEAiaoHuYNW8=; 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 1woRbg-0001PL-Ds for openvpn-devel@lists.sourceforge.net; Mon, 27 Jul 2026 20:07:27 +0000 Received: from smtp102.mailbox.org (smtp102.mailbox.org [IPv6:2001:67c:2050:b231:465::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 4h88l84TqHzMlKk; Mon, 27 Jul 2026 22:07:16 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=unstable.cc; s=MBO0001; t=1785182836; 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=IU8+7nKGLXOwf74BQT5HAZ0RSMUWAe0anDASGXWrYcM=; b=zfXcc6E1Bt8Ty9SH8lb8hFm1aKyMCCkfTvRP/cE+AjGNyh/PJSOVpK3MIlrMRNjG9zaNK7 9l4pbKC5GE7Ic2aSommwEDL48sqaxf9AT8H1Ll+fT714j08fOiL8ZdPxBmfMt2e5Ra0s/F OuFoOZqWpj/oavmAGSO+WExKQv4OidHQivyHBD7/XNjoCQqx95uptPpj2WenbhiyoOZJP/ PFXVB3OrRj4MP8MKcN5yoGd8El8p0epEvxADubt6jeM2jDYxPvUu774GX8DAZym8at8aue lxxp/E6f5xIf/f4BNMYghyglaPCfF141ePUs9TtJkYoLLSVW9U2+0Xet+yRbNA== Authentication-Results: outgoing_mbo_mout; dkim=none; spf=pass (outgoing_mbo_mout: domain of a@unstable.cc designates 2001:67c:2050:b231:465::102 as permitted sender) smtp.mailfrom=a@unstable.cc From: Antonio Quartulli To: openvpn-devel@lists.sourceforge.net Date: Mon, 27 Jul 2026 22:07:02 +0200 Message-ID: <20260727200705.869169-7-a@unstable.cc> In-Reply-To: <20260727200705.869169-1-a@unstable.cc> References: <20260727200705.869169-1-a@unstable.cc> MIME-Version: 1.0 X-Rspamd-Queue-Id: 4h88l84TqHzMlKk 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 The by_transp_addr table is keyed on the peer's remote transport address, but the float rehash hashed bind->remote directly, while the two other sites that touch the table build a clean key first: ovp [...] Content analysis details: (-0.2 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 RCVD_IN_MSPIKE_H5 RBL: Excellent reputation (+5) [80.241.56.171 listed in wl.mailspike.net] -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature 0.0 RCVD_IN_MSPIKE_WL Mailspike good senders X-Headers-End: 1woRbg-0001PL-Ds Subject: [Openvpn-devel] [PATCH ovpn net v3 6/9] ovpn: hash floated peer by transport identity only 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: 1871899896984629390 X-GMAIL-MSGID: 1871899896984629390 From: Antonio Quartulli The by_transp_addr table is keyed on the peer's remote transport address, but the float rehash hashed bind->remote directly, while the two other sites that touch the table build a clean key first: ovpn_peer_add_mp() and the lookup in ovpn_peer_get_by_transp_addr() both hash a sockaddr holding only family/address/port. For a link-local IPv6 peer, bind->remote carries sin6_scope_id (set from ipv6_iface_scope_id() when the endpoint is learned), and that field is folded into the jhash() over sizeof(struct sockaddr_in6). The lookup never sets sin6_scope_id, so after such a peer floats it is rehashed into a scope_id-dependent bucket that lookups (scope_id 0) never visit, making the peer unreachable through the by_transp_addr fallback. ovpn_peer_transp_match() only compares address and port, so the hash was keying on a field the match ignores. sin6_scope_id must stay in bind->remote because the TX path uses it as flowi6_oif, so it cannot just be cleared there. Instead build the hash key from family/address/port only, exactly like ovpn_peer_add_mp() and the lookup, so all three sites agree on the bucket. Fixes: f0281c1d3732 ("ovpn: add support for updating local or remote UDP endpoint") Signed-off-by: Antonio Quartulli --- drivers/net/ovpn/peer.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/drivers/net/ovpn/peer.c b/drivers/net/ovpn/peer.c index be772d14ae41..5282dfead4b3 100644 --- a/drivers/net/ovpn/peer.c +++ b/drivers/net/ovpn/peer.c @@ -913,7 +913,10 @@ bool ovpn_peer_check_by_src(struct ovpn_priv *ovpn, struct sk_buff *skb, static void __ovpn_peer_hash_transp_addr(struct ovpn_peer *peer, const struct ovpn_bind *bind) { + struct sockaddr_storage sa = {}; struct hlist_nulls_head *nhead; + struct sockaddr_in6 *sa6; + struct sockaddr_in *sa4; size_t salen; lockdep_assert_held(&peer->ovpn->lock); @@ -929,12 +932,26 @@ static void __ovpn_peer_hash_transp_addr(struct ovpn_peer *peer, if (unlikely(hlist_unhashed(&peer->hash_entry_id))) return; + /* Build the hash key from the transport identity only + * (family/address/port), matching ovpn_peer_add_mp() and the lookup + * in ovpn_peer_get_by_transp_addr(). Hashing bind->remote directly + * would fold in sin6_scope_id (set on the float path but never by the + * lookup), scattering the peer into a bucket lookups cannot reach. + */ switch (bind->remote.in4.sin_family) { case AF_INET: - salen = sizeof(struct sockaddr_in); + sa4 = (struct sockaddr_in *)&sa; + sa4->sin_family = AF_INET; + sa4->sin_addr.s_addr = bind->remote.in4.sin_addr.s_addr; + sa4->sin_port = bind->remote.in4.sin_port; + salen = sizeof(*sa4); break; case AF_INET6: - salen = sizeof(struct sockaddr_in6); + sa6 = (struct sockaddr_in6 *)&sa; + sa6->sin6_family = AF_INET6; + sa6->sin6_addr = bind->remote.in6.sin6_addr; + sa6->sin6_port = bind->remote.in6.sin6_port; + salen = sizeof(*sa6); break; default: return; @@ -943,8 +960,8 @@ static void __ovpn_peer_hash_transp_addr(struct ovpn_peer *peer, /* remove old hashing (no-op if entry is not currently linked) */ hlist_nulls_del_init_rcu(&peer->hash_entry_transp_addr); /* re-add with current transport address */ - nhead = ovpn_get_hash_head(peer->ovpn->peers->by_transp_addr, - &bind->remote, salen); + nhead = ovpn_get_hash_head(peer->ovpn->peers->by_transp_addr, &sa, + salen); hlist_nulls_add_head_rcu(&peer->hash_entry_transp_addr, nhead); } From patchwork Mon Jul 27 20:07:03 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Antonio Quartulli X-Patchwork-Id: 5135 Return-Path: Delivered-To: patchwork@openvpn.net Received: by 2002:a05:7000:190f:b0:87d:a69c:34be with SMTP id g15csp1598685maz; Mon, 27 Jul 2026 13:07:32 -0700 (PDT) X-Forwarded-Encrypted: i=2; AHgh+RrxHgUDoAnZQwGR1nC1nM6OIZ4sRZlH6PwT/0lx1wh3o9W0AzKGQBJWaxekBHMva5ubjLZsK8qOv/k=@openvpn.net X-Received: by 2002:a05:6808:4fd3:b0:4a4:866:c395 with SMTP id 5614622812f47-4ab6a01445dmr9910013b6e.13.1785182852338; Mon, 27 Jul 2026 13:07:32 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1785182851; cv=none; d=google.com; s=arc-20260327; b=pCPSnCt0yJzHeBS8HVzQ6GqNkjSHI5wAYG/LsJmsuOqwlhW710XnOBLB7dgOxt9DCh 3+AqrwYeh4BOFwn3h/Yc8MPTjhvq91YgTfROPQ4Zx76FHns1vRNtIvTCByvQaAQhYDNY wNiRpa9JNPE/v05QkPNRvhsc8BJ1DJ4DCw2rKBBzzcR732htIOdY62ZkvZgygP87f4rj ekxuJnZCSdVD8xv86GmJEr9uSV2eFoBfp8DV+rjB5vZ3yMRaT+08FTrd8E5Iprg2Eoeq OpGT2s6AvjjIrZMhdF27IAD/XyvB0GCE+FWfyxNNyC8x1W7NBLbLhiCo6QsbcNsUbLOo Gcnw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20260327; 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=WVBJxS8hJ21PO9M0cCVGQ3NZ//jvWPqSrDtCfNWize0=; fh=BsMg/B0Yb/hS/rzP5Npz4luh0IleZm8REk1XWiWRt2A=; b=rSNc1nLgB+9qEOfighAIj+DI/oVV6jG4Qnrrfa3FlKNOmINjp1GkgQqZ/kKsT/+Xxv 9HXveLCc7CPy0Z6tmpGJ3cvKo4f5698A6pBS4KbNaD6Wkc/cTPBWnJDerTRmv602vti2 dNKhfZvYqALZh5Oa/OuYBbYxONiZRkIvbXQJwC1iSAVgyKTl2bBSycjdCdZeGIUwMsvd u5ZEx1JWp7/KhF2W2dhxisYstITim0l5d/uNNzL06gOlpYzjhSTiVopVLNBSv6R/BZIU BXImyGWkaY8x41ieE1qTGozOeGoFXLZyY8Xbki0hbWnxHeiSUVXRl2YjyI0AEHlVlTWQ dPpA==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@lists.sourceforge.net header.s=beta header.b=Th2xbdl1; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=dgIPhQo7; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=HhkPyZ4T; dkim=neutral (body hash did not verify) header.i=@unstable.cc header.s=MBO0001 header.b=KB5Tn0MA; 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-4ab4b457ae4si9290790b6e.92.2026.07.27.13.07.30 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Mon, 27 Jul 2026 13:07:31 -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=Th2xbdl1; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=dgIPhQo7; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=HhkPyZ4T; dkim=neutral (body hash did not verify) header.i=@unstable.cc header.s=MBO0001 header.b=KB5Tn0MA; 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=WVBJxS8hJ21PO9M0cCVGQ3NZ//jvWPqSrDtCfNWize0=; b=Th2xbdl1r1LQznit+NYz8xeFaU ABuV9xfLcqVhmO3tTQz+W0QkvySgcbLM1B1VWdTPKelZWHyiDrhkg/eYYWSexlQ91PX17QFNshcF5 CfEwC+TTTiSl/Cd6B0cymnteRYXSpXYSCyqG2vsroVptZRdEE8GW3+EW9wP/nsvFllsI=; Received: from [127.0.0.1] (helo=sfs-ml-4.v29.lw.sourceforge.com) by sfs-ml-4.v29.lw.sourceforge.com with esmtp (Exim 4.95) (envelope-from ) id 1woRbk-00013P-1S; Mon, 27 Jul 2026 20:07:28 +0000 Received: from [172.30.29.66] (helo=mx.sourceforge.net) by sfs-ml-4.v29.lw.sourceforge.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.95) (envelope-from ) id 1woRbi-00013E-P5 for openvpn-devel@lists.sourceforge.net; Mon, 27 Jul 2026 20:07:26 +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=YJuazhbGH4Gvwf2Gu6aH9UhNU90q2oiwbgb+HRB7nF8=; b=dgIPhQo7dnvnSDG6w3TrY9Gtcn o5x2WxWKN+RE5ck1x7bmsAR7k13a25LA7n2pI2RE2fl9eg7n650tSWvyTXQxu5iTyYsxvKLL6ByFs gKfA+L033IHo+XX8U6mK8I7ZsGYpQ6CfL7C/9GILkb14qdpTVIxeMRgLrXFfJgWw6DVQ=; 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=YJuazhbGH4Gvwf2Gu6aH9UhNU90q2oiwbgb+HRB7nF8=; b=HhkPyZ4TivSIlJBJm5IVPcn5Rg 01H17X3LS8RThfF5x3sAwAAYtAq3GJBjPIYrT2i+TQ9Khm95Gj3xrZSsdTL73SEOVVZejCtbSRDHe ypR1czfJ+Udg9YjIlDrEN7ucjG09S1QDUoWjnw1cmrSRumutu1ldO309WtE5zfwSwEi0=; Received: from mout-p-202.mailbox.org ([80.241.56.172]) by sfi-mx-1.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.95) id 1woRbk-0002ct-LA for openvpn-devel@lists.sourceforge.net; Mon, 27 Jul 2026 20:07:26 +0000 Received: from smtp102.mailbox.org (unknown [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-202.mailbox.org (Postfix) with ESMTPS id 4h88l929f8zMlMl; Mon, 27 Jul 2026 22:07:17 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=unstable.cc; s=MBO0001; t=1785182837; 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=YJuazhbGH4Gvwf2Gu6aH9UhNU90q2oiwbgb+HRB7nF8=; b=KB5Tn0MAJ27AjGAFiR4w3wc2GTBbn5ZP83Ypjcw88nxCXdI5uvTQ1VJmfw1iEp9doYqxeW LqEvgWRpkIp+6XSiP5ZNKTuE7gmPj95BCLMLCn7ZM12jSIOHVi0RFh+T8OlnvkWmG0QhsD xq9N4PH7kggrBRzz5WBOWGx5dO2iMNuMcVwWH9XhD9mIPrddpXX0nDxop3hpEdd/yC0WWk Pw2E7o94a75AhhBwlU2i3OD7s3YtbFscO6jtN1g5awqVGCxaCvFDQejM4132g7m33dNAgJ o371AlFbLMWKP745voAhFKZKNEq/8Ug7F+HO7Byfn2xhYMDfObH5smxVYbldDw== From: Antonio Quartulli To: openvpn-devel@lists.sourceforge.net Date: Mon, 27 Jul 2026 22:07:03 +0200 Message-ID: <20260727200705.869169-8-a@unstable.cc> In-Reply-To: <20260727200705.869169-1-a@unstable.cc> References: <20260727200705.869169-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 ovpn_mp_alloc() tried to disable SEND_REDIRECTS on a multipeer interface, but it runs from ovpn_net_init() (->ndo_init), which register_netdevice() invokes before the NETDEV_REGISTER notifier chain. T [...] Content analysis details: (-0.2 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature 0.0 RCVD_IN_MSPIKE_H5 RBL: Excellent reputation (+5) [80.241.56.172 listed in wl.mailspike.net] 0.0 RCVD_IN_MSPIKE_WL Mailspike good senders X-Headers-End: 1woRbk-0002ct-LA Subject: [Openvpn-devel] [PATCH ovpn net v3 7/9] ovpn: disable IPv4 redirects on MP interfaces 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: 1871899893371236696 X-GMAIL-MSGID: 1871899893371236696 From: Antonio Quartulli ovpn_mp_alloc() tried to disable SEND_REDIRECTS on a multipeer interface, but it runs from ovpn_net_init() (->ndo_init), which register_netdevice() invokes before the NETDEV_REGISTER notifier chain. The IPv4 in_device is only created when that notifier reaches inetdev_event() -> inetdev_init(), so __in_dev_get_rtnl() always returned NULL at ndo_init time and the whole redirect-disabling block (both the per-device and the per-netns IPV4_DEVCONF_ALL write) was dead. MP interfaces therefore kept emitting ICMP redirects. Disabling redirects only once is not enough either: the IPv4 in_device is destroyed and recreated when the interface is moved to a different network namespace (NETDEV_UNREGISTER/NETDEV_REGISTER), and the newly created in_device inherits the destination namespace defaults, silently re-enabling SEND_REDIRECTS. Disable redirects from ovpn_net_open() (->ndo_open) instead: it runs every time the interface is brought up, including after the in_device has been recreated, so the setting is always re-applied. This mirrors what wireguard does in wg_open(). RTNL is held on the ndo_open() path, so __in_dev_get_rtnl() is safe. Fixes: 05003b408c20 ("ovpn: implement multi-peer support") Signed-off-by: Antonio Quartulli --- drivers/net/ovpn/main.c | 50 ++++++++++++++++++++++++++++------------- 1 file changed, 35 insertions(+), 15 deletions(-) diff --git a/drivers/net/ovpn/main.c b/drivers/net/ovpn/main.c index 9993c1dfe471..c4e775250727 100644 --- a/drivers/net/ovpn/main.c +++ b/drivers/net/ovpn/main.c @@ -35,25 +35,11 @@ static void ovpn_priv_free(struct net_device *net) static int ovpn_mp_alloc(struct ovpn_priv *ovpn) { - struct in_device *dev_v4; int i; if (ovpn->mode != OVPN_MODE_MP) return 0; - dev_v4 = __in_dev_get_rtnl(ovpn->dev); - if (dev_v4) { - /* disable redirects as Linux gets confused by ovpn - * handling same-LAN routing. - * This happens because a multipeer interface is used as - * relay point between hosts in the same subnet, while - * in a classic LAN this would not be needed because the - * two hosts would be able to talk directly. - */ - IN_DEV_CONF_SET(dev_v4, SEND_REDIRECTS, false); - IPV4_DEVCONF_ALL(dev_net(ovpn->dev), SEND_REDIRECTS) = false; - } - /* the peer container is fairly large, therefore we allocate it only in * MP mode */ @@ -97,9 +83,38 @@ static void ovpn_net_uninit(struct net_device *dev) gro_cells_destroy(&ovpn->gro_cells); } +static int ovpn_net_open(struct net_device *dev) +{ + struct ovpn_priv *ovpn = netdev_priv(dev); + struct in_device *dev_v4; + + /* the IPv4 in_device (and thus its config) is recreated whenever the + * interface is moved to a new netns, so redirects must be disabled on + * every bring-up rather than once at creation time, otherwise the + * setting is silently lost after such a move + */ + if (ovpn->mode == OVPN_MODE_MP) { + dev_v4 = __in_dev_get_rtnl(dev); + if (dev_v4) { + /* disable redirects as Linux gets confused by ovpn + * handling same-LAN routing. + * This happens because a multipeer interface is used as + * relay point between hosts in the same subnet, while + * in a classic LAN this would not be needed because the + * two hosts would be able to talk directly. + */ + IN_DEV_CONF_SET(dev_v4, SEND_REDIRECTS, false); + IPV4_DEVCONF_ALL(dev_net(dev), SEND_REDIRECTS) = false; + } + } + + return 0; +} + static const struct net_device_ops ovpn_netdev_ops = { .ndo_init = ovpn_net_init, .ndo_uninit = ovpn_net_uninit, + .ndo_open = ovpn_net_open, .ndo_start_xmit = ovpn_net_xmit, }; @@ -183,6 +198,7 @@ static int ovpn_newlink(struct net_device *dev, struct ovpn_priv *ovpn = netdev_priv(dev); struct nlattr **data = params->data; enum ovpn_mode mode = OVPN_MODE_P2P; + int ret; if (data && data[IFLA_OVPN_MODE]) { mode = nla_get_u8(data[IFLA_OVPN_MODE]); @@ -207,7 +223,11 @@ static int ovpn_newlink(struct net_device *dev, else netif_carrier_off(dev); - return register_netdevice(dev); + ret = register_netdevice(dev); + if (ret < 0) + return ret; + + return 0; } static int ovpn_fill_info(struct sk_buff *skb, const struct net_device *dev) From patchwork Mon Jul 27 20:07: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: 5137 Return-Path: Delivered-To: patchwork@openvpn.net Received: by 2002:a05:7000:190f:b0:87d:a69c:34be with SMTP id g15csp1598710maz; Mon, 27 Jul 2026 13:07:34 -0700 (PDT) X-Forwarded-Encrypted: i=2; AHgh+RqtdSWJRZ8AD252Uck3HeCuEH8qi8MH/Olt7F4dpnlJI3vtFxM+aCxSvKx+Oe8JFWglWQ50fX5tZ0Y=@openvpn.net X-Received: by 2002:a4a:ee10:0:b0:6aa:9be1:484a with SMTP id 006d021491bc7-6ac90bbdb31mr889088eaf.7.1785182854379; Mon, 27 Jul 2026 13:07:34 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1785182854; cv=none; d=google.com; s=arc-20260327; b=Gj2kcXJc63nvS2fSYNJqIRS4090LJqVJK2Q0JmMOWuEgEyA+WLS4reicS46RinM8J2 3JlIna6URGVbHUDrv4u+oZJvFXfxCQnbnNrbFiOVhPss0vlLP6oBIL5VBs5A92Jdr8c3 yHCBtfgU+mWX6fFln9zZz+xAtxgWp/TN3FOd5ifhBha3c+ycheIkBllfD5dWgNJmZ4Yt z9S49sJ6HR77nVlMIr+fXrAWcVsLmqx0lUGOX05X7MWMPcE9fQKChNCo2K35fWZxVvuD AvqNxvyyzPdf1NG561sYcQGYNxLPNlHwn6gqtBf/qIfCFomdM7UOqDHD467RVJSTp3dS klmw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20260327; 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=MwQgd9got00wHlhrV53CT4w4al0uuUpnTo79rg8BRDw=; fh=BsMg/B0Yb/hS/rzP5Npz4luh0IleZm8REk1XWiWRt2A=; b=Nx/WPfC0efItRhaxSOIdwEW2ir5i8BbDlFc8uipkXU1H9ya3AWBw1ixtgr06+wNkeT uk8hF7vsdfb18dEYc62QOCnGMgxb7AkbRvJldVvRQjqMmLfTqoqIlfSHgVrjabID5XZG fQLE9j6S/ghu5371SgHZjc5nu1gM1xzyi5H4dGnLwOX2idsqwwOOBG40n6Jx7MOnEQFn +7UwvmR5/WtcD7FFKiqwDLNlocfycbKR6Wz8OZ9zKzTgnEpxRFnZvCCESKYVgs+wOmbd eDmfFoOH8sUCc6u8vApTo1JqJyPPCZCEehh6p3B8TQZVg6zDUF8grxagngab2LgkPGS7 PkaQ==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@lists.sourceforge.net header.s=beta header.b=ZPPRxsyf; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b="gzR4m/0K"; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=k+xRhFph; dkim=neutral (body hash did not verify) header.i=@unstable.cc header.s=MBO0001 header.b=kGEsLO6q; 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 006d021491bc7-6aaf91684c1si6485846eaf.0.2026.07.27.13.07.34 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Mon, 27 Jul 2026 13:07:34 -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=ZPPRxsyf; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b="gzR4m/0K"; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=k+xRhFph; dkim=neutral (body hash did not verify) header.i=@unstable.cc header.s=MBO0001 header.b=kGEsLO6q; 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=MwQgd9got00wHlhrV53CT4w4al0uuUpnTo79rg8BRDw=; b=ZPPRxsyfD+3vNg8+Zix8Yi/R9P FowRsnAmCKAs5EaP81JbjBpq/q/5ME6B9gHKD9ssErjKQEiOEMCAJeocMel2g0NRu0X0Y4SG8sluB 8b+bUK7n3NYpyKjHD7LInq9y9jvNtDc6hqAnUlcbV4QGWikbU8UyowmYUGMMRgPFeAXc=; 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 1woRbp-0008ME-MZ; Mon, 27 Jul 2026 20:07: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 1woRbl-0008Lm-Iz for openvpn-devel@lists.sourceforge.net; Mon, 27 Jul 2026 20:07:27 +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=j4K0CryDDnvcfv4cinY40LKzzK/Yzm1HDYN5nMvZdnA=; b=gzR4m/0KiiK92eCv3hWQJecbv9 huu4gBo9FWPyXkP5dcg8psIlOCSBixS7BSS8ZMAlRVDPvt956FM9qul2c5bGxN0U3Nx8wukY3I0Dc IMQ4JfILgNeHB3yGKQkeJaiFkiroxxbseK86gHW0b7SJ3EcbTyzBNQUzWw2zUGqF3aiY=; 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=j4K0CryDDnvcfv4cinY40LKzzK/Yzm1HDYN5nMvZdnA=; b=k+xRhFpheFdQRbK7fYEWTv5yTC FGLrVYrHYZXwjH0ynogr6OpHXFPcI72LFl2eeILIaHr1x26nCa9Rq3AlfljPzZTFk0gTP6FkumBV+ XWVY4DbUPmBSBaMiMqxnGw0RX/meHNI22zqMz9R67VtKtHEu747bIkHcp541YSbiqp/4=; Received: from mout-p-202.mailbox.org ([80.241.56.172]) by sfi-mx-2.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.95) id 1woRbh-0001PN-KQ for openvpn-devel@lists.sourceforge.net; Mon, 27 Jul 2026 20:07:27 +0000 Received: from smtp102.mailbox.org (smtp102.mailbox.org [IPv6:2001:67c:2050:b231:465::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-202.mailbox.org (Postfix) with ESMTPS id 4h88l95vs4zMlP0; Mon, 27 Jul 2026 22:07:17 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=unstable.cc; s=MBO0001; t=1785182837; 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=j4K0CryDDnvcfv4cinY40LKzzK/Yzm1HDYN5nMvZdnA=; b=kGEsLO6qDCoasEG/prSuCCPap8MvDAZWCG8wjELyW1qwuwhcNeob0fUdEyXy1fNYmDIxFe 5J8iHkDb12Lxhx6biM0rZmzyqO2kPTad/X/RHeYhFSAn63vZPQQxoqqh9R6EpIX+JRqrgF m6jcNhn05xpc33MgmXAUiirB3y69NRqpemh4Mf9ub6vtA6KhP1DUvZxoahLySQ8e/QY9w8 iYZJAfe90z6C5MN97SgbKEjWZqsWcBSK60uyyBJE2nenJV5NJ8GUc8DFMpb0Yhbmf4UPUL 5HUfFgs8bBOJH4fcr35mC9eiJn0+x7804Vo9uVGuqueFuAqt49RN+dUenAcepA== Authentication-Results: outgoing_mbo_mout; dkim=none; spf=pass (outgoing_mbo_mout: domain of a@unstable.cc designates 2001:67c:2050:b231:465::102 as permitted sender) smtp.mailfrom=a@unstable.cc From: Antonio Quartulli To: openvpn-devel@lists.sourceforge.net Date: Mon, 27 Jul 2026 22:07:04 +0200 Message-ID: <20260727200705.869169-9-a@unstable.cc> In-Reply-To: <20260727200705.869169-1-a@unstable.cc> References: <20260727200705.869169-1-a@unstable.cc> MIME-Version: 1.0 X-Rspamd-Queue-Id: 4h88l95vs4zMlP0 X-Spam-Score: -0.2 (/) X-Spam-Report: Spam detection software, running on the system "sfi-spamd-2.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 Netlink calls may access TCP global vars (i.e. when attaching a TCP socket), therefore we need to make sure the latters are initialized beforehand. For this reason move the global TCP initialization at the top of the module init function. Content analysis details: (-0.2 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 RCVD_IN_MSPIKE_H5 RBL: Excellent reputation (+5) [80.241.56.172 listed in wl.mailspike.net] -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.0 RCVD_IN_MSPIKE_WL Mailspike good senders X-Headers-End: 1woRbh-0001PN-KQ Subject: [Openvpn-devel] [PATCH ovpn net v3 8/9] ovpn: ensure TCP vars are initialized first 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: 1871899896915577587 X-GMAIL-MSGID: 1871899896915577587 From: Antonio Quartulli Netlink calls may access TCP global vars (i.e. when attaching a TCP socket), therefore we need to make sure the latters are initialized beforehand. For this reason move the global TCP initialization at the top of the module init function. Fixes: 11851cbd60ea ("ovpn: implement TCP transport") Signed-off-by: Antonio Quartulli --- drivers/net/ovpn/main.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/net/ovpn/main.c b/drivers/net/ovpn/main.c index c4e775250727..f8ae64612951 100644 --- a/drivers/net/ovpn/main.c +++ b/drivers/net/ovpn/main.c @@ -253,8 +253,14 @@ static struct rtnl_link_ops ovpn_link_ops = { static int __init ovpn_init(void) { - int err = rtnl_link_register(&ovpn_link_ops); + int err; + /* init TCP first so that any subsequent netlink operation + * is ensured to access initialized TCP global vars + */ + ovpn_tcp_init(); + + err = rtnl_link_register(&ovpn_link_ops); if (err) { pr_err("ovpn: can't register rtnl link ops: %d\n", err); return err; @@ -266,8 +272,6 @@ static int __init ovpn_init(void) goto unreg_rtnl; } - ovpn_tcp_init(); - return 0; unreg_rtnl: From patchwork Mon Jul 27 20:07:05 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Antonio Quartulli X-Patchwork-Id: 5138 Return-Path: Delivered-To: patchwork@openvpn.net Received: by 2002:a05:7000:190f:b0:87d:a69c:34be with SMTP id g15csp1598725maz; Mon, 27 Jul 2026 13:07:36 -0700 (PDT) X-Forwarded-Encrypted: i=2; AHgh+Rr3gmfqFpChC1gAOMWlXldEkQ6iEFOyJYeoj2nic5uYrh1X6RMEZxon56Y0Mraw5xKbAw9Y/XasvTk=@openvpn.net X-Received: by 2002:a4a:ee84:0:b0:6aa:f688:cd30 with SMTP id 006d021491bc7-6ac938c4df2mr104939eaf.31.1785182856359; Mon, 27 Jul 2026 13:07:36 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1785182856; cv=none; d=google.com; s=arc-20260327; b=dekiCiGWShz+iReFt6e1fXNhruWm59hwxqcYLlJ26bHKpcl0y4Jgoze0BBE6k4KkXJ 8qoaWHPpXZec0946qsmynQ7gX0AuM0/vESUCet1Fxw4GFRei2oOEZuBsS4c7ZaGpKsHz lxcuiqFtUMiw2DDnsXahzv6QyBikPV8oMfXCtMCbA26LBq17r5KvGsfuv9MM72o+o1Ld nuJB4ui6M7t2T8hxSOPp/yIqUNLvryFEe/FKaRN/2gXNPFGA+uksXdUEdWFHUxXtqNzF 9VopmA/trTP0w3roAy7NkFk/bm/AFUlX8GXgl3l/YtU5rS2d3UG4s17FRHjoBKKUp442 Lh3A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20260327; 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=ny4MRHVcSK6yira5JNqkiDKWuMPmr1qC8fPpjYZjYCM=; fh=BsMg/B0Yb/hS/rzP5Npz4luh0IleZm8REk1XWiWRt2A=; b=LhgPHydiQOHlKh9/lcwgajitqilXlADa1FvFM81hzqNi0yS0O1LKjxKzhNoLdHFZkA dPmfUJgyGl81JF7CfwlPpIw5koPTw72WabzofFGBwkKcwzTnwRhJyr8W8vymnpyleIff 3HpDGbHvr7yd3mckHaQg0NGZdiDZzhnqHsqG86V7HD1cqYosLiPE4cSPSIMc1ZflWINK ABAalCsBksrdWBf6eyGFKnf46HS6LXXHj7vD6G7dTrxs9o+q6K7xt8/tJ01CypGepibQ hGQlFNNz1ULEroi4vDKeMgKBcNIGtyGUc1eaVpsU+wpm9/0hN691AcHvk5NmqdCDwhB+ 7gCQ==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@lists.sourceforge.net header.s=beta header.b=kugKkC9g; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=gOEuLpo7; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=LLi46jQ1; dkim=neutral (body hash did not verify) header.i=@unstable.cc header.s=MBO0001 header.b=zQkg3XQU; 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 46e09a7af769-7ee49ed8ba2si11227255a34.134.2026.07.27.13.07.36 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Mon, 27 Jul 2026 13:07:36 -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=kugKkC9g; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=gOEuLpo7; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=LLi46jQ1; dkim=neutral (body hash did not verify) header.i=@unstable.cc header.s=MBO0001 header.b=zQkg3XQU; 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=ny4MRHVcSK6yira5JNqkiDKWuMPmr1qC8fPpjYZjYCM=; b=kugKkC9gRbdyyOYt3yWCpWKGUU E1I1vIq3j+DQfl6dlWFa5FE7oM1DpnWeVfiISN7PV8MEMjAaSHIZi9w/RxwLPaIMH+wtzdpJaOl33 ZQKJMzdeBVbpo26sgv9A/HgbNHaGPHkUvEzOWx0Av+PJY5tx4GF3L/3aaO9rSBTKbkYY=; Received: from [127.0.0.1] (helo=sfs-ml-2.v29.lw.sourceforge.com) by sfs-ml-2.v29.lw.sourceforge.com with esmtp (Exim 4.95) (envelope-from ) id 1woRbo-00064v-CU; Mon, 27 Jul 2026 20:07:33 +0000 Received: from [172.30.29.66] (helo=mx.sourceforge.net) by sfs-ml-2.v29.lw.sourceforge.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.95) (envelope-from ) id 1woRbi-00063m-FR for openvpn-devel@lists.sourceforge.net; Mon, 27 Jul 2026 20:07:27 +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=poOp9vJOUTetKP7O4RcdXH5uZmAmZchCPEQH41D6Hlo=; b=gOEuLpo7E03wyRVO9inydZwnd2 w4tdHwFe2Z4Qqs982kJ82Lk1VpRa5Wjp4QoI6oBjB7nsHWtBHl4n+ivGPl/5lXfBrlbsHMKwW5jwD 2dL8EILZHGUgE4tYS67S7FuHFflb8VhBVY2V6yUoHPr12ilG1b7KjJttCvHNXJgTQRPM=; 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=poOp9vJOUTetKP7O4RcdXH5uZmAmZchCPEQH41D6Hlo=; b=LLi46jQ1OZdQ33QEaBN0zmaeqR fdFU0L3VQP+DGVJL5sXVKqgKDuRENZKcLXSk559fTizgmYkHyxW/yO500jkWkLNAG5/0rJ5+F/2oE xsh+xPYguuTiibeE9WfMknDD7/Derxb1DMuctJzc4Rg+FlxmkrCSS99N6bmHSOQOF2QE=; Received: from mout-p-202.mailbox.org ([80.241.56.172]) by sfi-mx-2.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.95) id 1woRbi-0001PQ-21 for openvpn-devel@lists.sourceforge.net; Mon, 27 Jul 2026 20:07:27 +0000 Received: from smtp102.mailbox.org (unknown [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-202.mailbox.org (Postfix) with ESMTPS id 4h88lB305JzMlPb; Mon, 27 Jul 2026 22:07:18 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=unstable.cc; s=MBO0001; t=1785182838; 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=poOp9vJOUTetKP7O4RcdXH5uZmAmZchCPEQH41D6Hlo=; b=zQkg3XQUCkEbstRcIrwybt7032YE72LLreYsG7NAdVjs2BcigF9870kTy3jdqf9uOiFsoY yhp+ENv2/uj/oObvFbP5bSXPzRpyYEPRsXPh68Q8Q0q6hfIWsyJf8YnGX9s2h3XNRntRI7 lvMgg1q3mi10jxjPnn26bw+6qB8jSkGpjdR7AR7fW2KJUObKSpUCu1usTCcrlKywvInq0k WxnBKkE8vi8OcSiHd7UGDjAgryO0VdOQ9BhPhR81eiGQ0Dz2CnZky2ce9olTaFizuj/Kbe 0gco930S5cR4E2AOrNJHeYgzLCzXKcfTj5EkwPwNDawNUND9yse/6cf+2nuOaw== From: Antonio Quartulli To: openvpn-devel@lists.sourceforge.net Date: Mon, 27 Jul 2026 22:07:05 +0200 Message-ID: <20260727200705.869169-10-a@unstable.cc> In-Reply-To: <20260727200705.869169-1-a@unstable.cc> References: <20260727200705.869169-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 ovpn_udp{4, 6}_output() resolve a route from a flow key sampled from the peer binding and the transport socket, then cache the result in the per-peer dst_cache. Several of those sources may change conc [...] Content analysis details: (-0.2 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 RCVD_IN_MSPIKE_H5 RBL: Excellent reputation (+5) [80.241.56.172 listed in wl.mailspike.net] -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature 0.0 RCVD_IN_MSPIKE_WL Mailspike good senders X-Headers-End: 1woRbi-0001PQ-21 Subject: [Openvpn-devel] [PATCH ovpn net v3 9/9] ovpn: invalidate the UDP TX dst_cache when the flow key changes 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: 1871899899143133567 X-GMAIL-MSGID: 1871899899143133567 From: Antonio Quartulli ovpn_udp{4,6}_output() resolve a route from a flow key sampled from the peer binding and the transport socket, then cache the result in the per-peer dst_cache. Several of those sources may change concurrently with TX, and the dst_cache epoch (reset_ts vs the per-CPU refresh_ts stamped at get-miss time) only neutralizes the common ordering. Three issues remain: - ovpn_peer_endpoints_update() may either update bind->local in place or replace the whole bind via RCU (float -> new remote, hence new daddr/dport/oif). It already dst_cache_reset()s, but the TX path can still cache a dst it resolved with the pre-update values if its dst_cache_get-miss lands a strictly later jiffy than the reset. - inet_sk(sk)->inet_sport can be reset to 0 by __udp_disconnect() (connect() with AF_UNSPEC) on a socket without SOCK_BINDPORT_LOCK, and sk->sk_mark can change any time via setsockopt(SO_MARK). Neither triggers an ovpn cache reset, so a previously-cached entry resolved with the old value persists until dst obsolescence. Both fields are also read locklessly into the flow key (data race). - A sport of 0 means the transport socket has been disconnected and unhashed; sending a UDP packet from source port 0 is nonsense. In the common dispatcher ovpn_udp_output() (so every TX, including cache hits, runs the check): - Sample inet_sport with READ_ONCE(). If it is 0, emit a one-time netdev_warn_once() and return -EIO so ovpn_udp_send_skb() drops the skb. - Sample sk_mark with READ_ONCE(). - Compare both against the values stored when the dst_cache was last (re-)populated (new per-peer fields dst_cache_sport/dst_cache_mark, zero-initialised by kzalloc_obj() in ovpn_peer_new()). On mismatch dst_cache_reset() the cache and WRITE_ONCE() the new values, so the subsequent dst_cache_get() misses and the lookup re-resolves with the current sport/mark. - Pass sport/mark down to ovpn_udp{4,6}_output(); they use those in the flowi initializer and skip the per-function sampling. The post-lookup re-check in the v4/v6 paths is retained, but only for the bind/local race the original commit addressed (rcu_access_pointer on peer->bind and READ_ONCE/ovpn_peer_local_ipv6 on bind->local); the sport/mark comparison is dropped from there because the entry check now catches it. sk_protocol is immutable post-creation and is intentionally read plain. The in-flight packet is still transmitted with the resolved parameters; only the cache is guarded. No fast-path lock is added. Fixes: 08857b5ec5d9 ("ovpn: implement basic TX path (UDP)") Signed-off-by: Antonio Quartulli --- drivers/net/ovpn/peer.h | 8 +++++ drivers/net/ovpn/udp.c | 70 +++++++++++++++++++++++++++++++++++------ 2 files changed, 68 insertions(+), 10 deletions(-) diff --git a/drivers/net/ovpn/peer.h b/drivers/net/ovpn/peer.h index c0994c606554..17d57b12fa5e 100644 --- a/drivers/net/ovpn/peer.h +++ b/drivers/net/ovpn/peer.h @@ -46,6 +46,12 @@ * @tcp.sk_cb.ops: pointer to the original prot_ops object (TCP only) * @crypto: the crypto configuration (ciphers, keys, etc..) * @dst_cache: cache for dst_entry used to send to peer + * @dst_cache_sport: inet_sport observed when the dst_cache was last + * (re-)populated; compared on every TX to detect changes + * (e.g. connect(AF_UNSPEC)) and invalidate the cache + * @dst_cache_mark: sk_mark observed when the dst_cache was last + * (re-)populated; compared on every TX to detect changes + * via setsockopt(SO_MARK) and invalidate the cache * @bind: remote peer binding * @keepalive_interval: seconds after which a new keepalive should be sent * @keepalive_xmit_exp: future timestamp when next keepalive should be sent @@ -102,6 +108,8 @@ struct ovpn_peer { } tcp; struct ovpn_crypto_state crypto; struct dst_cache dst_cache; + __be16 dst_cache_sport; + u32 dst_cache_mark; struct ovpn_bind __rcu *bind; unsigned long keepalive_interval; unsigned long keepalive_xmit_exp; diff --git a/drivers/net/ovpn/udp.c b/drivers/net/ovpn/udp.c index 17d65d1595ed..ca502c920f54 100644 --- a/drivers/net/ovpn/udp.c +++ b/drivers/net/ovpn/udp.c @@ -143,7 +143,7 @@ static int ovpn_udp_encap_recv(struct sock *sk, struct sk_buff *skb) */ static int ovpn_udp4_output(struct ovpn_peer *peer, struct ovpn_bind *bind, struct dst_cache *cache, struct sock *sk, - struct sk_buff *skb) + struct sk_buff *skb, __be16 sport, u32 mark) { struct rtable *rt; struct flowi4 fl = { @@ -152,10 +152,10 @@ static int ovpn_udp4_output(struct ovpn_peer *peer, struct ovpn_bind *bind, */ .saddr = READ_ONCE(bind->local.ipv4.s_addr), .daddr = bind->remote.in4.sin_addr.s_addr, - .fl4_sport = inet_sk(sk)->inet_sport, + .fl4_sport = sport, .fl4_dport = bind->remote.in4.sin_port, .flowi4_proto = sk->sk_protocol, - .flowi4_mark = sk->sk_mark, + .flowi4_mark = mark, }; int ret; @@ -196,7 +196,17 @@ static int ovpn_udp4_output(struct ovpn_peer *peer, struct ovpn_bind *bind, ret); goto err; } - dst_cache_set_ip4(cache, &rt->dst, fl.saddr); + /* only cache the result if the bind is still current: a concurrent + * ovpn_peer_endpoints_update() may have replaced the bind (float) or + * updated bind->local in place, in which case ovpn already reset the + * cache and re-caching here would reinstate a stale route. sport/mark + * are validated at TX entry by ovpn_udp_output(). + */ + if (rcu_access_pointer(peer->bind) == bind && + READ_ONCE(bind->local.ipv4.s_addr) == fl.saddr) + dst_cache_set_ip4(cache, &rt->dst, fl.saddr); + else + dst_cache_reset(cache); transmit: udp_tunnel_xmit_skb(rt, sk, skb, fl.saddr, fl.daddr, 0, @@ -221,17 +231,18 @@ static int ovpn_udp4_output(struct ovpn_peer *peer, struct ovpn_bind *bind, */ static int ovpn_udp6_output(struct ovpn_peer *peer, struct ovpn_bind *bind, struct dst_cache *cache, struct sock *sk, - struct sk_buff *skb) + struct sk_buff *skb, __be16 sport, u32 mark) { struct dst_entry *dst; + struct in6_addr local; int ret; struct flowi6 fl = { .daddr = bind->remote.in6.sin6_addr, - .fl6_sport = inet_sk(sk)->inet_sport, + .fl6_sport = sport, .fl6_dport = bind->remote.in6.sin6_port, .flowi6_proto = sk->sk_protocol, - .flowi6_mark = sk->sk_mark, + .flowi6_mark = mark, .flowi6_oif = bind->remote.in6.sin6_scope_id, }; @@ -267,7 +278,18 @@ static int ovpn_udp6_output(struct ovpn_peer *peer, struct ovpn_bind *bind, &bind->remote.in6, ret); goto err; } - dst_cache_set_ip6(cache, dst, &fl.saddr); + /* only cache the result if the bind is still current: a concurrent + * ovpn_peer_endpoints_update() may have replaced the bind (float) or + * updated bind->local in place, in which case ovpn already reset the + * cache and re-caching here would reinstate a stale route. sport/mark + * are validated at TX entry by ovpn_udp_output(). + */ + ovpn_peer_local_ipv6(peer, bind, &local); + if (rcu_access_pointer(peer->bind) == bind && + ipv6_addr_equal(&local, &fl.saddr)) + dst_cache_set_ip6(cache, dst, &fl.saddr); + else + dst_cache_reset(cache); transmit: /* user IPv6 packets may be larger than the transport interface @@ -306,12 +328,40 @@ static int ovpn_udp_output(struct ovpn_peer *peer, struct dst_cache *cache, struct sock *sk, struct sk_buff *skb) { struct ovpn_bind *bind; + __be16 sport; + u32 mark; int ret; /* set sk to null if skb is already orphaned */ if (!skb->destructor) skb->sk = NULL; + sport = READ_ONCE(inet_sk(sk)->inet_sport); + if (unlikely(!sport)) { + /* the transport UDP socket has been disconnected (e.g. via + * connect(AF_UNSPEC)): inet_sport == 0 means the socket has + * been unhashed and sending from source port 0 is nonsense; + * refuse and tell the operator + */ + netdev_warn_once(peer->ovpn->dev, + "UDP transport socket has no source port; was it disconnected?\n"); + return -EIO; + } + mark = READ_ONCE(sk->sk_mark); + + /* userspace can change sk_mark (via setsockopt(SO_MARK)) and + * inet_sport (via connect(AF_UNSPEC)) at any time without notifying + * ovpn; if either differs from what the dst_cache was last populated + * with, invalidate the cache now so a hit doesn't return a dst + * resolved with the old value + */ + if (READ_ONCE(peer->dst_cache_sport) != sport || + READ_ONCE(peer->dst_cache_mark) != mark) { + dst_cache_reset(cache); + WRITE_ONCE(peer->dst_cache_sport, sport); + WRITE_ONCE(peer->dst_cache_mark, mark); + } + rcu_read_lock(); bind = rcu_dereference(peer->bind); if (unlikely(!bind)) { @@ -323,11 +373,11 @@ static int ovpn_udp_output(struct ovpn_peer *peer, struct dst_cache *cache, switch (bind->remote.in4.sin_family) { case AF_INET: - ret = ovpn_udp4_output(peer, bind, cache, sk, skb); + ret = ovpn_udp4_output(peer, bind, cache, sk, skb, sport, mark); break; #if IS_ENABLED(CONFIG_IPV6) case AF_INET6: - ret = ovpn_udp6_output(peer, bind, cache, sk, skb); + ret = ovpn_udp6_output(peer, bind, cache, sk, skb, sport, mark); break; #endif default: