From patchwork Fri Aug 28 14:50:25 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ralf Lici X-Patchwork-Id: 5293 Return-Path: Delivered-To: patchwork@openvpn.net Received: by 2002:a05:7000:c317:b0:87d:ab56:3700 with SMTP id jk23csp51078mab; Fri, 28 Aug 2026 07:50:57 -0700 (PDT) X-Forwarded-Encrypted: i=2; AHgh+RpPlF+dYvK2r3lKuWsheLAIIilqaECcpnlDotpj+RwI0TUL0d0k7DBGJ81nURGsplfkDdz9JaGfXAI=@openvpn.net X-Received: by 2002:a05:6808:4fe8:b0:4b3:8d45:aa2b with SMTP id 5614622812f47-4b398446f03mr8458971b6e.16.1787928657210; Fri, 28 Aug 2026 07:50:57 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1787928657; cv=none; d=google.com; s=arc-20260327; b=SBzmyPFDc+asYIh7eLYq+nLA+h6WPbmqRwm0e4EZpjsz2SIIlS23fZh2UtcUBiwpDj zGn9iViT4f35AWIbK+7UnDDARR8bV0F34NiRqloY00OZy01GLhMMRKlGMAs/8NVo8AaV apuZndlFXQ9VGl1AuafqqL1nbCsqZCyUeJaYRo3hosFn2VTsrA9L5Ziyc8EmHcuTbjI/ hCH+YRnVcj5M5++8ivtcSm3LxPxxaHpo1W35HQNEXZ8kON839dzFfyUQ2D+0izXXLDn+ mGEMXVlq2CMsoxMD7Nv39DT7LCjGQDzYgeRrSOelWPyzjHU9/sx2/AkC093gE7KyH9Ah y6wQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20260327; h=errors-to:content-transfer-encoding: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=ELx5LRO3lDOlRkDR+ouAd3zdPw3UmhzB+p/Cb62Gc14=; fh=4NbAC/LsuMLI0S0hprUlLSLCiHwg6SCAifhH718Jh0Q=; b=ol9KwEues6dAIvldn0AhUrX0YCSsZbmGTkc6mGWpLugJ2AB+zxIjWYzV+JC5SW0yp1 s6/3Y7OMH5qjWHNz4/mUqJfa0Z05gDKOZ+D3XazFLSodM0iZKU9t+Aw/gGQCnD1+6EOw /IJw2moirkzWm4eVCwSOCIT83otSrJSiSyEiCgka14+9wnzVS6lD2/CLXC1M+3g7TnL2 5kgCEInpp01qZNkEaLVFWHR0HnYjqan+iY/RjrSSenqdznKuCoygSQzFDYaqy5d5hywS 6tswzdPI0B7TIzuiSsUYlc55AQ3C2QPwFl/SmKqjWD/xWQInluzu3zLd0nEno6zJVH6r 9dxw==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@lists.sourceforge.net header.s=beta header.b=c8wf5KZt; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=SqOk8xm1; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=EwWDxtkn; dkim=neutral (body hash did not verify) header.i=@mandelbit.com header.s=MBO0001 header.b=ltq9CUzV; 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-4b3a1b32bb4si2588582b6e.89.2026.08.28.07.50.56 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Fri, 28 Aug 2026 07:50:57 -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=c8wf5KZt; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=SqOk8xm1; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=EwWDxtkn; dkim=neutral (body hash did not verify) header.i=@mandelbit.com header.s=MBO0001 header.b=ltq9CUzV; 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: 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:Cc:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=ELx5LRO3lDOlRkDR+ouAd3zdPw3UmhzB+p/Cb62Gc14=; b=c8wf5KZthxGgf92K875/R+sLh8 jfSlEQ9rn+rIQmqP6YcNU/Av3QxxkLsMe8yqNuV06xNjr+Gjiw9LFag+9cIJ4CoYWvv15qyM9EvQz hDgKMBIMlaTZ2BObNjScQJ1ReZ/ZkMvwn3JAac0YXGS+cpsQFfmV9ZfgJ3/r9/ROBkII=; 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 1wzxuu-000461-FZ; Fri, 28 Aug 2026 14:50:53 +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 1wzxus-00045s-Fw for openvpn-devel@lists.sourceforge.net; Fri, 28 Aug 2026 14:50:51 +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:To:From:Sender:Reply-To:Cc: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=VYn7N7+p3t22KtbOVVZD7mPOoWipWB0Ve99bGZcjiRM=; b=SqOk8xm1GifM4/8dZFDe8UWHRf ZBYsKHP6prMT0fYKUCPonD1ejoQLeMBMCB5ZNnf5ISatti6UAJ8Xoy3Yo+dVbFPLTSvB2r2dsZy0t f8RZDQUxmnIuWcbaxE5VFPoKEjsQfNg/X1487jCOPnusrfU7sVJ8xY7YZMt+9O6NYAsU=; 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:To:From:Sender:Reply-To:Cc: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=VYn7N7+p3t22KtbOVVZD7mPOoWipWB0Ve99bGZcjiRM=; b=EwWDxtknsGFUD6kQs3vntBOKOZ fplSB2e8hkxk1vhXBqFmmwV3EG3cKJKRmXJUXwbB1iN3y1+hmjNbA60LPcXLVzxZAKnjuTamIuuNZ zyaHIWcuuljW45ajAuEcaUdQhABzhdlx2enq0x17BIhDWtEhF4+vKr0IMXkWC8ndoCW0=; Received: from mout-b-110.mailbox.org ([195.10.208.55]) by sfi-mx-2.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.95) id 1wzxus-000860-JH for openvpn-devel@lists.sourceforge.net; Fri, 28 Aug 2026 14:50:51 +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-b-110.mailbox.org (Postfix) with ESMTPS id 4hWhC65HZGzNlfS for ; Fri, 28 Aug 2026 16:50:42 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mandelbit.com; s=MBO0001; t=1787928642; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=VYn7N7+p3t22KtbOVVZD7mPOoWipWB0Ve99bGZcjiRM=; b=ltq9CUzVsEuZmxeveqmIoPGU1yx8fRyKhMAVr6OCoUNPN/MkQ7BNt3bELTWoT5tFMpXsng Tt02ufFZOAlHaw/vlAWuo3xrjtwrwRiL9UFCM/znL282fP4Ojq63ITillUJ2jJ17lVRzZS 9V8Bj/O8byK6K09dQpeSB59buTA6qdXUX/O7XZ+oUqfkz3gGwgfCXuM6vmJ3KamyU+376/ 8z/RQb8czypAPSEDMH9hP8kdBSkW9WHk2DuDH1LQW6RgDnhs3SYbZXfuIPz7qB7BgtoiAf shyEmYvCapaZ8YurUNedtjnHD6a+rGjEafbSzNl4VrpMLq4mNE7NVGEnwjmv0A== Authentication-Results: outgoing_mbo_mout; dkim=none; spf=pass (outgoing_mbo_mout: domain of ralf@mandelbit.com designates 2001:67c:2050:b231:465::102 as permitted sender) smtp.mailfrom=ralf@mandelbit.com From: Ralf Lici To: openvpn-devel@lists.sourceforge.net Date: Fri, 28 Aug 2026 16:50:25 +0200 Message-ID: In-Reply-To: References: MIME-Version: 1.0 X-Rspamd-Queue-Id: 4hWhC65HZGzNlfS 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: UDP route lookup runs without peer->lock while the bind is protected by RCU. The route key is snapshotted separately. Either can change while the lookup is in progress. The TX path currently checks only the route key before publishing the looked-up dst. If the bind changes but the route key does not, a dst resolved from the old endpoint can be installed in the cache [...] 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 Message has at least one valid DKIM or DK signature -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 X-Headers-End: 1wzxus-000860-JH Subject: [Openvpn-devel] [PATCH ovpn net v3 4/6] ovpn: validate peer state before caching UDP dst 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: , Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox X-GMAIL-THRID: 1874779079725256323 X-GMAIL-MSGID: 1874779079725256323 UDP route lookup runs without peer->lock while the bind is protected by RCU. The route key is snapshotted separately. Either can change while the lookup is in progress. The TX path currently checks only the route key before publishing the looked-up dst. If the bind changes but the route key does not, a dst resolved from the old endpoint can be installed in the cache after the bind replacement. Compare both the bind pointer and the route key under peer->lock before updating the cache. The RCU read-side critical section keeps the old bind alive throughout the lookup, so pointer identity is sufficient to detect a replacement. Fixes: f0281c1d3732 ("ovpn: add support for updating local or remote UDP endpoint") Signed-off-by: Ralf Lici --- Changes since v2 https://lore.kernel.org/openvpn-devel/082540583b9145d89e1cdd5a74c485ea3a53d285.1785308184.git.ralf@mandelbit.com/ - Split former 4/5 into this plus the next two patches. (Sabrina) - No functional changes. No changes since v1 https://lore.kernel.org/openvpn-devel/082540583b9145d89e1cdd5a74c485ea3a53d285.1785253480.git.ralf@mandelbit.com/ drivers/net/ovpn/udp.c | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/drivers/net/ovpn/udp.c b/drivers/net/ovpn/udp.c index c6d591cb7ff4..eeef4a7229f5 100644 --- a/drivers/net/ovpn/udp.c +++ b/drivers/net/ovpn/udp.c @@ -173,6 +173,35 @@ static void ovpn_dst_cache_check_key(struct ovpn_peer *peer, spin_unlock_bh(&peer->lock); } +/** + * ovpn_dst_cache_current - check whether a route lookup matches peer state + * @peer: the peer owning the bind and dst cache + * @bind: the RCU bind used for the route lookup + * @key: the route key used for the route lookup + * + * Check that @bind is still the current peer bind and that @key still matches + * the peer route key. The caller must hold @peer->lock. The TX path keeps + * @bind inside an RCU read-side critical section, so pointer identity is enough + * to detect whether the bind was replaced while the route lookup was running. + * + * Return: true if the lookup result still matches the current peer state and + * may update the dst cache. + */ +static bool ovpn_dst_cache_current(const struct ovpn_peer *peer, + const struct ovpn_bind *bind, + const struct ovpn_route_key *key) +{ + const struct ovpn_bind *curr_bind; + + lockdep_assert_held(&peer->lock); + + curr_bind = rcu_dereference_protected(peer->bind, + lockdep_is_held(&peer->lock)); + + return curr_bind == bind && + ovpn_route_key_equal(key, &peer->route_key); +} + /** * ovpn_udp4_output - send IPv4 packet over udp socket * @peer: the destination peer @@ -240,7 +269,7 @@ static int ovpn_udp4_output(struct ovpn_peer *peer, struct ovpn_bind *bind, /* avoid storing a stale cache */ spin_lock_bh(&peer->lock); - if (likely(ovpn_route_key_equal(key, &peer->route_key))) + if (likely(ovpn_dst_cache_current(peer, bind, key))) dst_cache_set_ip4(cache, &rt->dst, fl.saddr); spin_unlock_bh(&peer->lock); @@ -313,7 +342,7 @@ static int ovpn_udp6_output(struct ovpn_peer *peer, struct ovpn_bind *bind, /* avoid storing a stale cache */ spin_lock_bh(&peer->lock); - if (likely(ovpn_route_key_equal(key, &peer->route_key))) + if (likely(ovpn_dst_cache_current(peer, bind, key))) dst_cache_set_ip6(cache, dst, &fl.saddr); spin_unlock_bh(&peer->lock);