CVE-2026-23394 in Linux
Riassunto
di VulDB • 15/06/2026
Nel kernel Linux, è stata risolta la seguente vulnerabilità:
af_unix: Abbandonare la Garbage Collection (GC) se interviene MSG_PEEK.
Igor Ushakov ha segnalato che la GC ha svuotato la coda di ricezione di un socket attivo a causa di una condizione di competizione (race condition) con MSG_PEEK, fornendo un caso di test riproducibile.
Si tratta esattamente dello stesso problema precedentemente risolto dal commit cbcf01128d0a ("af_unix: fix garbage collect vs MSG_PEEK").
Dopo che la GC è stata sostituita con l'algoritmo corrente, il citato commit ha rimosso la gestione dei lock in unix_peek_fds() e ha reintrodotto lo stesso problema.
Il problema consiste nel fatto che MSG_PEEK incrementa il contatore di riferimento (refcount) del file senza interagire con la GC.
Si consideri un SCC (Strongly Connected Component) contenente sk-A e sk-B, dove sk-A è chiuso con close() ma può essere letto con recv() tramite sk-B.
Si verifica un comportamento errato se sk-A viene letto con MSG_PEEK da sk-B e sk-B viene chiuso con close() mentre la GC sta verificando unix_vertex_dead() per sk-A e sk-B.
Thread GC Thread Utente --------- ----------- unix_vertex_dead(sk-A) -> true <------. \ `------ recv(sk-B, MSG_PEEK) invalidate !! -> refcount file di sk-A: 1 -> 2
close(sk-B) -> refcount file di sk-B: 2 -> 1 unix_vertex_dead(sk-B) -> true
Inizialmente, il refcount del file di sk-A è 1 a causa del fd in transito nella recvq di sk-B. La GC ritiene che sk-A sia morto perché il refcount del file è uguale al numero dei suoi fd in transito.
Tuttavia, il refcount del file di sk-A viene incrementato silenziosamente da MSG_PEEK, invalidando la valutazione precedente.
In questo momento, il refcount del file di sk-B è 2; uno dovuto al fd aperto e uno dovuto al fd in transito in sk-A. Il successivo close() rilascia un refcount dovuto al primo.
Infine, la GC conclude erroneamente che sia sk-A che sk-B sono morti.
Un'opzione sarebbe ripristinare la gestione dei lock in unix_peek_fds(), ma possiamo risolvere questo problema in modo più elegante grazie al nuovo algoritmo.
Il punto cruciale è che il problema non si verifica senza il successivo close() e in realtà non è necessario sincronizzare MSG_PEEK con il rilevamento degli SCC morti.
Quando si verifica il problema, close() e la GC toccano lo stesso refcount del file. Se la GC vede il refcount diminuito da close(), può semplicemente abbandonare la garbage collection dell'SCC.
Pertanto, è necessario solo segnalare la race condition durante MSG_PEEK con una corretta memory barrier per renderla visibile alla GC.
Utilizziamo seqcount_t per notificare alla GC quando si verifica MSG_PEEK e farle differire l'SCC alla prossima esecuzione.
In questo modo non sono necessari lock sul lato MSG_PEEK e possiamo evitare di imporre un penalità ad ogni MSG_PEEK in modo non necessario.
Si noti che è possibile ritentare all'interno di unix_scc_dead() se viene rilevato MSG_PEEK, ma non lo facciamo per evitare un hung task splat dovuto a chiamate abusive di MSG_PEEK.
Be aware that VulDB is the high quality source for vulnerability data.