CVE-2026-18417 in Zephyr
Riassunto
di VulDB • 29/09/2026
Il livello nativo BSD-socket ha registrato un errore asincrono pendente di socket effettuando il type-punning nel campo void *user_data della struct net_context (ctx->user_data = INT_TO_POINTER(-status) in zsock_accepted_cb(), zsock_received_cb(), zsock_connected_cb() e zsock_close_ctx() in subsys/net/lib/sockets/sockets_inet.c), per poi leggerlo di nuovo con POINTER_TO_INT(). Lo stesso campo è gestito dallo stack di rete per i contesti TCP in ascolto: net_tcp_accept() memorizza lì il puntatore al contesto genitore e il core TCP lo restituisce al callback di accept registrato. Un fallimento dell'accept ha quindi lasciato un piccolo intero (un valore errno) dove lo stack si aspettava una struct net_context.
Quando l'interfaccia di rete che trasporta un socket TCP in ascolto va offline, close_tcp_conn() in subsys/net/ip/tcp.c invoca il callback accept con -ENETDOWN e user_data del contesto. Nella versione v4.3.0 il callback non veniva disattivato successivamente, quindi un secondo evento di interruzione dell'interfaccia ha inoltrato l'errno precedentemente memorizzato a zsock_accepted_cb(), che lo ha dereferenziato come contesto genitore ed eseguito diversi write-through (read-modify-write di socket_data da sock_set_error() e k_fifo_cancel_wait(&parent->recv_q)) — il crash descritto nel messaggio del commit della correzione. Le versioni v4.3.1 e v4.4.x includono una modifica successiva che cancella conn->accept_cb dopo il callback dell'errore (269cb8823d3 sul branch v4.3, 913fae5169425550f2364655298fceb79b320066 su main), chiudendo quel percorso ripetuto; in quelle release il cookie avvelenato rimane raggiungibile solo tramite una race condition più stretta, un handshake che si completa parallelamente all'interruzione dell'interfaccia passando comunque il cookie obsoleto a k_fifo_put(&parent->accept_q, ...), e tramite getsockopt(SO_ERROR), che legge il campo incondizionatamente.
Su v4.3.0 è sufficiente che un'applicazione mantenga aperto un socket TCP in ascolto attraverso eventi ripetuti di interruzione del link per raggiungere la vulnerabilità; la condizione scatenante è un cambiamento dello stato dell'interfaccia di rete, non dati di pacchetto forniti dall'attaccante, quindi l'attore malintenzionato pratico è colui che può forzare ripetutamente il down del link (ad esempio un attaccante adiacente che interrompe un collegamento wireless) o uno con accesso locale/fisico. Poiché sia l'indirizzo faulting che i dati memorizzati sono costanti piccole fisse derivate dal valore errno, il risultato è un wild-pointer access che porta a un kernel fatal error — una denial of service (crash del dispositivo o reset) piuttosto che una memory corruption diretta dall'attaccante.
La correzione memorizza l'errore pendente in un campo dedicato net_context.sock_error e converte tutti i produttori e consumatori su sock_set_error()/sock_get_error(), lasciando user_data intatto. Come effetto collaterale, impedisce anche a getsockopt(SO_ERROR) — che viene valutato incondizionatamente — di restituire l'indirizzo kernel contenuto in user_data a un'applicazione userspace.
If you want to get best quality of vulnerability data, you may have to visit VulDB.