[PATCH] ovpn: Fix use-after-free when releasing peers in unlock_ovpn()

From: Wentao Liang

Date: Thu Sep 17 2026 - 08:09:06 EST


unlock_ovpn() walks the release list with llist_for_each_entry() and
drops the last reference of each peer in the loop body. Advancing to the
next entry then reads peer->release_entry.next from an object that has
already been scheduled for freeing, which is a use-after-free. Use
llist_for_each_entry_safe() so the next pointer is read before the peer
is released.

Fixes: 80747caef33d ("ovpn: introduce the ovpn_peer object")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Wentao Liang <vulab@xxxxxxxxxxx>
---
drivers/net/ovpn/peer.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ovpn/peer.c b/drivers/net/ovpn/peer.c
index a09d61296425..12ebc5affdd0 100644
--- a/drivers/net/ovpn/peer.c
+++ b/drivers/net/ovpn/peer.c
@@ -26,11 +26,11 @@ static void unlock_ovpn(struct ovpn_priv *ovpn,
struct llist_head *release_list)
__releases(&ovpn->lock)
{
- struct ovpn_peer *peer;
+ struct ovpn_peer *peer, *tmp;

spin_unlock_bh(&ovpn->lock);

- llist_for_each_entry(peer, release_list->first, release_entry) {
+ llist_for_each_entry_safe(peer, tmp, release_list->first, release_entry) {
ovpn_socket_release(peer);
ovpn_peer_put(peer);
}
--
2.34.1