git: a841961da752 - main - if_ovpn: free crp, mbuf, and release refcount on crypto_dispatch() failure
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 10 Aug 2026 13:23:08 UTC
The branch main has been updated by kp:
URL: https://cgit.FreeBSD.org/src/commit/?id=a841961da75218ddd5b4e9e784c9fe5148ffe781
commit a841961da75218ddd5b4e9e784c9fe5148ffe781
Author: LuisCastellanos-dev <ing.castellanosdz@gmail.com>
AuthorDate: 2026-08-10 13:09:22 +0000
Commit: Kristof Provost <kp@FreeBSD.org>
CommitDate: 2026-08-10 13:09:30 +0000
if_ovpn: free crp, mbuf, and release refcount on crypto_dispatch() failure
When crypto_dispatch() or crypto_dispatch_async() returns non-zero,
the registered callback is never invoked. In both ovpn_transmit_to_peer()
and ovpn_udp_input(), if_ovpn.c did not free the cryptop request, release
the peer/sc reference count, or free the mbuf on dispatch failure.
This results in three simultaneous leaks per failed dispatch:
- crp allocated via crypto_getreq() is never freed
- peer->refcount (encrypt) or sc->refcount (decrypt) incremented but
never decremented
- mbuf passed to crypto_use_mbuf() is never freed
The leaks are reachable under memory pressure when the OCF scheduler
returns ENOMEM from crypto_dispatch(). The registered callbacks
(ovpn_encrypt_tx_cb, ovpn_decrypt_rx_cb) correctly handle crp_etype
for crypto operation failures; this fix addresses the separate
dispatch-level failure path where no callback is invoked.
Found during code review following FreeBSD-SA-26:52.if_wg.
Reviewed by: kp
Differential Revision: https://reviews.freebsd.org/D58754
---
sys/net/if_ovpn.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/sys/net/if_ovpn.c b/sys/net/if_ovpn.c
index 19fab11f3dde..28e60efaeaa5 100644
--- a/sys/net/if_ovpn.c
+++ b/sys/net/if_ovpn.c
@@ -2188,6 +2188,9 @@ ovpn_transmit_to_peer(struct ifnet *ifp, struct mbuf *m,
else
ret = crypto_dispatch(crp);
if (ret) {
+ crypto_freereq(crp);
+ ovpn_peer_release_ref(peer, false);
+ m_freem(m);
OVPN_COUNTER_ADD(sc, lost_data_pkts_out, 1);
if_inc_counter(sc->ifp, IFCOUNTER_OERRORS, 1);
}
@@ -2636,6 +2639,9 @@ ovpn_udp_input(struct mbuf *m, int off, struct inpcb *inp,
else
ret = crypto_dispatch(crp);
if (ret != 0) {
+ crypto_freereq(crp);
+ atomic_add_int(&sc->refcount, -1);
+ m_freem(m);
OVPN_COUNTER_ADD(sc, lost_data_pkts_in, 1);
if_inc_counter(sc->ifp, IFCOUNTER_IERRORS, 1);
}