Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 09 Dec 2025 14:19:51 +0000
From:      Kristof Provost <kp@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 5e2bbfe387f7 - main - if_ovpn: use epoch to free peers
Message-ID:  <69383007.282ee.46025830@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help

The branch main has been updated by kp:

URL: https://cgit.FreeBSD.org/src/commit/?id=5e2bbfe387f7eac8f802c4b6ad2114f0e17bb5f2

commit 5e2bbfe387f7eac8f802c4b6ad2114f0e17bb5f2
Author:     Kristof Provost <kp@FreeBSD.org>
AuthorDate: 2025-12-09 10:55:30 +0000
Commit:     Kristof Provost <kp@FreeBSD.org>
CommitDate: 2025-12-09 14:17:48 +0000

    if_ovpn: use epoch to free peers
    
    Avoid a possible use-after-free in the rx path.
    ovpn_decrypt_rx_cb() calls ovpn_finish_rx() which releases the lock,
    but continues to use the peer.
    Ensure that the peer cannot be freed until we're sure all potential
    users have stopped using it (i.e. have left net_epoch).
    
    Reported by:    Kevin Day <kevin@your.org>
    MFC after:      1 week
    Sponsored by:   Rubicon Communications, LLC ("Netgate")
---
 sys/net/if_ovpn.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/sys/net/if_ovpn.c b/sys/net/if_ovpn.c
index 674df4d17eb4..ae09a1ce9db8 100644
--- a/sys/net/if_ovpn.c
+++ b/sys/net/if_ovpn.c
@@ -161,6 +161,7 @@ struct ovpn_kpeer {
 	struct callout		 ping_rcv;
 
 	counter_u64_t		 counters[OVPN_PEER_COUNTER_SIZE];
+	struct epoch_context	 epoch_ctx;
 };
 
 struct ovpn_counters {
@@ -568,6 +569,15 @@ ovpn_notify_float(struct ovpn_softc *sc, uint32_t peerid,
 	return (0);
 }
 
+static void
+_ovpn_free_peer(struct epoch_context *ctx) {
+	struct ovpn_kpeer *peer = __containerof(ctx, struct ovpn_kpeer,
+	    epoch_ctx);
+
+	uma_zfree_pcpu(pcpu_zone_4, peer->last_active);
+	free(peer, M_OVPN);
+}
+
 static void
 ovpn_peer_release_ref(struct ovpn_kpeer *peer, bool locked)
 {
@@ -606,8 +616,8 @@ ovpn_peer_release_ref(struct ovpn_kpeer *peer, bool locked)
 
 	callout_stop(&peer->ping_send);
 	callout_stop(&peer->ping_rcv);
-	uma_zfree_pcpu(pcpu_zone_4, peer->last_active);
-	free(peer, M_OVPN);
+
+	NET_EPOCH_CALL(_ovpn_free_peer, &peer->epoch_ctx);
 
 	if (! locked)
 		OVPN_WUNLOCK(sc);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?69383007.282ee.46025830>