CVE-2026-64044

Source
https://cve.org/CVERecord?id=CVE-2026-64044
Import Source
https://storage.googleapis.com/cve-osv-conversion/osv-output/CVE-2026-64044.json
JSON Data
https://api.osv.dev/v1/vulns/CVE-2026-64044
Downstream
Published
2026-07-19T15:39:29.869Z
Modified
2026-07-22T05:29:47.634800624Z
Severity
  • 7.8 (High) CVSS_V3 - CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H CVSS Calculator
Summary
ovpn: respect peer refcount in CMD_NEW_PEER error path
Details

In the Linux kernel, the following vulnerability has been resolved:

ovpn: respect peer refcount in CMDNEWPEER error path

ovpnnlpeernewdoit()'s error path calls ovpnpeerrelease() directly rather than ovpnpeerput(), 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 ovpnsocket union uses the .ovpn arm and never points back at a peer; UDP encaprecv looks up peers via the not-yet-populated hashtables, so the new peer is unreachable until ovpnpeeradd() publishes it.

For TCP, ovpnsocketnew() sets ovpnsock->peer and ovpntcpsocketattach() publishes ovpnsock via rcuassignskuserdata(). From that moment until ovpnsocketrelease() 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 ovpntcprcv() path, can reach the peer through skuserdata -> ovpnsock->peer and bump its refcount via ovpnpeerhold().

ovpntcpsocketwaitfinish() (called inside ovpnsocketrelease()) drains strparser and the tx work, but does not synchronize with userspace syscall callers that already hold a peer reference. If ovpnnlpeermodify() or ovpnpeeradd() returns an error while such a caller is in flight - notably an ovpntcp_recvmsg() blocked in _skbrecvdatagram() on peer->tcp.userqueue - the direct ovpnpeerrelease() destroys the peer while the caller still holds the reference, and the eventual ovpnpeerput() from that caller operates on freed memory.

Replace the direct destructor call with ovpnpeerput() 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 ovpnpeerrelease_kref() runs the same destructor.

With this conversion ovpnpeerrelease() has no callers outside peer.c - ovpnpeerrelease_kref() in the same translation unit is the only remaining user - so make it static and drop its declaration from peer.h.

Database specific
{
    "osv_generated_from": "https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/64xxx/CVE-2026-64044.json",
    "cna_assigner": "Linux"
}
References

Affected packages

Git / git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git

Affected ranges

Type
GIT
Repo
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
Events
Introduced
11851cbd60ea1e5abbd97619d69845ead99303d6
Fixed
8298834912d76dbc82c12b6b4ab7590ed2bb8ae5
Fixed
0c3ef71879c0264de6c42463031d9e057da87840
Fixed
1fef6614673ff0846d30acdeeaf3cf98bb5f6116

Database specific

source
"https://storage.googleapis.com/cve-osv-conversion/osv-output/CVE-2026-64044.json"

Linux / Kernel

Package

Name
Kernel

Affected ranges

Type
ECOSYSTEM
Events
Introduced
6.16.0
Fixed
6.18.34
Type
ECOSYSTEM
Events
Introduced
6.19.0
Fixed
7.0.11

Database specific

source
"https://storage.googleapis.com/cve-osv-conversion/osv-output/CVE-2026-64044.json"