PT-2026-61295 · Linux · Linux
CVE-2026-63978
·
Published
2026-07-19
·
Updated
2026-07-19
CVSS v3.1
9.8
Critical
| Vector | AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H |
In the Linux kernel, the following vulnerability has been resolved:
net/handshake: Drain pending requests at net namespace exit
The arguments to list splice init() in handshake net exit() are
reversed. The call moves the local empty "requests" list onto
hn->hn requests, leaving the local list empty, so the subsequent
drain loop runs zero iterations. Pending handshake requests that
had not yet been accepted are not torn down when the net namespace
is destroyed; each one keeps a reference on a socket file and on
the handshake req allocation.
Pass the source and destination in the documented order
(list splice init(list, head) moves list onto head) so the pending
list is transferred to the local scratch list and drained through
handshake complete().
Fixing the splice direction exposes a list-corruption race. After
the splice each req->hr list still has non-empty link pointers,
threading the stack-local scratch list rather than hn requests.
A concurrent handshake req cancel() -- for example, from sunrpc's
TLS timeout on a kernel socket whose netns reference was not
taken -- finds the request through the rhashtable, calls
remove pending(), and sees !list empty(&req->hr list).
remove pending locked() then list del init()s an entry off the
scratch list while the drain iterates, corrupting it. The same
call arriving after the drain loop has run list del() on an
entry hits LIST POISON instead.
Have remove pending() check HANDSHAKE F NET DRAINING under
hn lock and report not-found when drain is in progress. The
drain has already taken ownership; handshake complete()'s existing
test and set on HANDSHAKE F REQ COMPLETED still arbitrates
between drain and cancel for who calls the consumer's hp done. Use
list del init() rather than list del() in the drain so req->hr list
does not carry LIST POISON after drain releases the entry.
The DRAINING guard in remove pending() makes cancel return false,
but cancel still falls through to test and set bit on
HANDSHAKE F REQ COMPLETED and drops the request's hr file reference.
Without another pin, if that is the last reference, sk destruct frees
the request while it is still linked on the drain loop's local list.
Pin each request's hr file under hn lock before releasing the list,
and drop that drain pin after the loop finishes with the request.
Fix
Found an issue in the description? Have something to add? Feel free to write us 👾
Related Identifiers
Affected Products
Linux