git: 6905fd01cb64 - main - if_ovpn: ensure we're in vnet context when calling sorele()
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 14 Nov 2022 08:36:59 UTC
The branch main has been updated by kp: URL: https://cgit.FreeBSD.org/src/commit/?id=6905fd01cb64ca2853b8312880f18a6ae2068099 commit 6905fd01cb64ca2853b8312880f18a6ae2068099 Author: Kristof Provost <kp@FreeBSD.org> AuthorDate: 2022-11-10 12:54:09 +0000 Commit: Kristof Provost <kp@FreeBSD.org> CommitDate: 2022-11-14 08:36:44 +0000 if_ovpn: ensure we're in vnet context when calling sorele() We reference count to ensure we don't release the socket while we still have data in flight. That means that we can end up releasing the socket from ovpn_encrypt_tx_cb(). We must have a vnet context set when calling sorele() (which asserts this from within sofree()), so move the CURVNET_SET()/CURVNET_RESTORE() to ensure this is the case. While here also add a couple of assertions to make this more obvious, and to ease future debugging. Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D37326 --- sys/net/if_ovpn.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/sys/net/if_ovpn.c b/sys/net/if_ovpn.c index 94d12fa25f1a..6ce5d07dc230 100644 --- a/sys/net/if_ovpn.c +++ b/sys/net/if_ovpn.c @@ -410,6 +410,8 @@ ovpn_peer_release_ref(struct ovpn_kpeer *peer, bool locked) { struct ovpn_softc *sc; + CURVNET_ASSERT_SET(); + atomic_add_int(&peer->refcount, -1); if (atomic_load_int(&peer->refcount) > 0) @@ -427,6 +429,8 @@ ovpn_peer_release_ref(struct ovpn_kpeer *peer, bool locked) } } + OVPN_ASSERT(sc); + /* The peer should have been removed from the list already. */ MPASS(ovpn_find_peer(sc, peer->peerid) == NULL); @@ -633,6 +637,7 @@ _ovpn_del_peer(struct ovpn_softc *sc, uint32_t peerid) int i; OVPN_WASSERT(sc); + CURVNET_ASSERT_SET(); for (i = 0; i < OVPN_MAX_PEERS; i++) { if (sc->peers[i] == NULL) @@ -1441,17 +1446,19 @@ ovpn_encrypt_tx_cb(struct cryptop *crp) int tunnel_len; int ret; + CURVNET_SET(sc->ifp->if_vnet); + NET_EPOCH_ENTER(et); + if (crp->crp_etype != 0) { crypto_freereq(crp); ovpn_peer_release_ref(peer, false); + NET_EPOCH_EXIT(et); + CURVNET_RESTORE(); OVPN_COUNTER_ADD(sc, lost_data_pkts_out, 1); m_freem(m); return (0); } - NET_EPOCH_ENTER(et); - CURVNET_SET(sc->ifp->if_vnet); - MPASS(crp->crp_buf.cb_type == CRYPTO_BUF_MBUF); tunnel_len = m->m_pkthdr.len - sizeof(struct ovpn_wire_header); @@ -1461,12 +1468,12 @@ ovpn_encrypt_tx_cb(struct cryptop *crp) OVPN_COUNTER_ADD(sc, tunnel_bytes_sent, tunnel_len); } - CURVNET_RESTORE(); - NET_EPOCH_EXIT(et); - crypto_freereq(crp); ovpn_peer_release_ref(peer, false); + NET_EPOCH_EXIT(et); + CURVNET_RESTORE(); + return (0); }