CVE-2026-64044 ovpn: respect peer refcount in CMD_NEW_PEER error path
A use-after-free in the Linux kernel OVPN module allows local attackers to execute arbitrary code or escalate privileges via TCP peer handling.
- Exploited in the wild
- Not known
- Login needed
- Any signed-in user
- Attackable
- Local or same network only
- Victim action needed
- Not needed
- Fix
- Available
What is CVE-2026-64044?
CVE-2026-64044 is a high-severity use after free vulnerability in Linux kernel, published on 19 Jul 2026. It can only be exploited from the same machine or local network, with no action from the victim.
Official description
In the Linux kernel, the following vulnerability has been resolved:
ovpn: respect peer refcount in CMD_NEW_PEER error path
ovpn_nl_peer_new_doit()'s error path calls ovpn_peer_release() directly rather than ovpn_peer_put(), bypassing the kref. The accompanying comment ("peer was not yet hashed, thus it is not used in any context") holds for UDP but not for TCP.
For UDP, the ovpn_socket union uses the .ovpn arm and never points back at a peer; UDP encap_recv looks up peers via the not-yet-populated hashtables, so the new peer is unreachable until ovpn_peer_add() publishes it.
For TCP, ovpn_socket_new() sets ovpn_sock->peer and ovpn_tcp_socket_attach() publishes ovpn_sock via rcu_assign_sk_user_data(). From that moment until ovpn_socket_release() detaches in the error path, the TCP fd is fully wired: userspace recvmsg / sendmsg / close / poll on the fd, as well as the strparser-driven ovpn_tcp_rcv() path, can reach the peer through sk_user_data -> ovpn_sock->peer and bump its refcount via ovpn_peer_hold().
ovpn_tcp_socket_wait_finish() (called inside ovpn_socket_release()) drains strparser and the tx work, but does not synchronize with userspace syscall callers that already hold a peer reference. If ovpn_nl_peer_modify() or ovpn_peer_add() returns an error while such a caller is in flight - notably an ovpn_tcp_recvmsg() blocked in __skb_recv_datagram() on peer->tcp.user_queue - the direct ovpn_peer_release() destroys the peer while the caller still holds the reference, and the eventual ovpn_peer_put() from that caller operates on freed memory.
Replace the direct destructor call with ovpn_peer_put() so the kref correctly defers destruction until the last reference is dropped. In the common case where no concurrent user is present, behaviour is unchanged: the kref hits zero immediately and ovpn_peer_release_kref() runs the same destructor.
With this conversion ovpn_peer_release() has no callers outside peer.c - ovpn_peer_release_kref() in the same translation unit is the only remaining user - so make it static and drop its declaration from peer.h.
Which versions are affected by CVE-2026-64044?
It affects 1 product.
Products include Linux kernel.
How do I fix CVE-2026-64044?
Apply the vendor's patch.
Upgrade to the fixed version. These bugs are found with fuzzing and sanitisers and avoided by memory-safe languages. More about Use after free.
Is CVE-2026-64044 being exploited?
There is no known exploitation of CVE-2026-64044 in the wild and no public exploit code.
Other vulnerabilities in Linux kernel
Sources
Also known as BELL-CVE-2026-64044, DEBIAN-CVE-2026-64044, GHSA-52jg-m8r4-36g9, UBUNTU-CVE-2026-64044.