Hi Marco,

On 27/05/2026 13:39, Marco Baffo wrote:
unlock_ovpn() iterates over the release_list using llist_for_each_entry()
and drops the peer reference inside the loop body via ovpn_peer_put().

If this drops the last reference, the peer is eventually freed. However,
llist_for_each_entry() reads peer->release_entry.next in the loop advance
expression, which runs after the body. By that time the peer may have
already been freed, resulting in a use after free when advancing to the
next list entry.

Fix this by using llist_for_each_entry_safe(), which caches the next
pointer before executing the loop body.

Signed-off-by: Marco Baffo <[email protected]>

Nice fix. Please send this as PATCH as well.

Regards,

---
  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 c02dfab51a6e..ff7c6ce9fcad 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, *next;
spin_unlock_bh(&ovpn->lock); - llist_for_each_entry(peer, release_list->first, release_entry) {
+       llist_for_each_entry_safe(peer, next, release_list->first, 
release_entry) {
                ovpn_socket_release(peer);
                ovpn_peer_put(peer);
        }

--
Antonio Quartulli



_______________________________________________
Openvpn-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openvpn-devel

Reply via email to