PT-2026-61295 · Linux · Linux

CVE-2026-63978

·

Publicado

2026-07-19

·

Atualizado

2026-07-19

CVSS v3.1

9.8

Crítica

VetorAV: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.

Correção

Encontrou algum problema na descrição? Tem algo a acrescentar? Fique à vontade para nos escrever 👾

Identificadores relacionados

CVE-2026-63978

Produtos afetados

Linux