CVE-2026-63978
Gravedad CVSS v3.1:
CRÍTICA
Tipo:
No Disponible / Otro tipo
Fecha de publicación:
19/07/2026
Última modificación:
30/07/2026
Descripción
*** Pendiente de traducción *** In the Linux kernel, the following vulnerability has been resolved:<br />
<br />
net/handshake: Drain pending requests at net namespace exit<br />
<br />
The arguments to list_splice_init() in handshake_net_exit() are<br />
reversed. The call moves the local empty "requests" list onto<br />
hn->hn_requests, leaving the local list empty, so the subsequent<br />
drain loop runs zero iterations. Pending handshake requests that<br />
had not yet been accepted are not torn down when the net namespace<br />
is destroyed; each one keeps a reference on a socket file and on<br />
the handshake_req allocation.<br />
<br />
Pass the source and destination in the documented order<br />
(list_splice_init(list, head) moves list onto head) so the pending<br />
list is transferred to the local scratch list and drained through<br />
handshake_complete().<br />
<br />
Fixing the splice direction exposes a list-corruption race. After<br />
the splice each req->hr_list still has non-empty link pointers,<br />
threading the stack-local scratch list rather than hn_requests.<br />
A concurrent handshake_req_cancel() -- for example, from sunrpc&#39;s<br />
TLS timeout on a kernel socket whose netns reference was not<br />
taken -- finds the request through the rhashtable, calls<br />
remove_pending(), and sees !list_empty(&req->hr_list).<br />
__remove_pending_locked() then list_del_init()s an entry off the<br />
scratch list while the drain iterates, corrupting it. The same<br />
call arriving after the drain loop has run list_del() on an<br />
entry hits LIST_POISON instead.<br />
<br />
Have remove_pending() check HANDSHAKE_F_NET_DRAINING under<br />
hn_lock and report not-found when drain is in progress. The<br />
drain has already taken ownership; handshake_complete()&#39;s existing<br />
test_and_set on HANDSHAKE_F_REQ_COMPLETED still arbitrates<br />
between drain and cancel for who calls the consumer&#39;s hp_done. Use<br />
list_del_init() rather than list_del() in the drain so req->hr_list<br />
does not carry LIST_POISON after drain releases the entry.<br />
<br />
The DRAINING guard in remove_pending() makes cancel return false,<br />
but cancel still falls through to test_and_set_bit on<br />
HANDSHAKE_F_REQ_COMPLETED and drops the request&#39;s hr_file reference.<br />
Without another pin, if that is the last reference, sk_destruct frees<br />
the request while it is still linked on the drain loop&#39;s local list.<br />
Pin each request&#39;s hr_file under hn_lock before releasing the list,<br />
and drop that drain pin after the loop finishes with the request.
Impacto
Puntuación base 3.x
9.80
Gravedad 3.x
CRÍTICA



