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]> --- 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); } -- 2.43.0 _______________________________________________ Openvpn-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/openvpn-devel
