mirror of
https://github.com/torvalds/linux.git
synced 2026-07-28 01:55:51 +02:00
ovpn: fix use after free in unlock_ovpn()
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.
Fixes: 80747caef3 ("ovpn: introduce the ovpn_peer object")
Signed-off-by: Marco Baffo <marco@mandelbit.com>
Signed-off-by: Antonio Quartulli <antonio@openvpn.net>
This commit is contained in:
parent
0bd9cfebc1
commit
e1ad6fe5db
|
|
@ -26,11 +26,12 @@ 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);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user