CVE-2022-50483 in Linuxinformazioni

Riassunto

di VulDB • 15/06/2026

Nel kernel Linux è stata risolta la seguente vulnerabilità:

net: enetc: evitare perdite di buffer in caso di errore su xdp_do_redirect()

Prima che enetc_clean_rx_ring_xdp() chiami xdp_do_redirect(), ogni software BD (Buffer Descriptor) nell'anello RX tra gli indici orig_i e i può avere uno dei due valori del contatore di riferimento (refcount) associato alla sua pagina.

Poiché siamo proprietari dell'attuale buffer che sta sendo elaborato, il refcount sarà almeno 1.

Se l'attuale proprietario del buffer all'indice diametralmente opposto nell'anello RX (ovvero, l'altra metà di questa pagina) non ha ancora chiamato kfree(), il refcount della pagina potrebbe essere anche 2.

enetc_page_reusable() in enetc_flip_rx_buff() verifica se il refcount della pagina è pari a 1 e, [se è 2], non tenta di riutilizzarla.

Tuttavia, se enetc_flip_rx_buff() viene posizionato dopo la chiamata xdp_do_redirect(), il refcount della pagina può assumere uno dei tre valori. Può anche essere 0, se non vi è alcun proprietario dell'altra metà della pagina e xdp_do_redirect() per questo buffer ha eseguito fino al punto di innescare un flush (svuotamento) del coda bulk devmap/cpumap, e i consumatori di queste code bulk hanno inoltre liberato il buffer, tutto ciò avvenendo prima che xdp_do_redirect() restituisca l'esecuzione ad enetc.

Questo è il motivo per cui enetc_flip_rx_buff() viene chiamato prima di xdp_do_redirect(), ma c'è un grave difetto in questo ragionamento: enetc_flip_rx_buff() imposterà rx_swbd->page = NULL su entrambi i rami del controllo enetc_page_reusable(), e se xdp_do_redirect() restituisce un errore, chiamiamo enetc_xdp_free(), che non gestisce questa situazione con la dovuta delicatezza.

In effetti, ciò che accade è piuttosto particolare. I refcount delle pagine partono da 1. enetc_flip_rx_buff() determina che sono riutilizzabili, trasferisce questi puntatori rx_swbd->page a un diverso rx_swbd in enetc_reuse_page(), e incrementa il refcount a 2. Quando xdp_do_redirect() restituisce successivamente un errore, chiamiamo la funzione no-op (nessun effetto) enetc_xdp_free(), ma non abbiamo ancora perso il riferimento a quella pagina. Una copia di essa è ancora presente in rx_ring->next_to_alloc, ma ha refcount 2 (e non vi sono proprietari concorrenti attivi che potrebbero decrementare il refcount). Ciò che causa realmente danni al sistema è quando invertiamo nuovamente rx_swbd->page nel secondo giro. Con un refcount aggiornato a 2, la pagina non sarà più considerata riutilizzabile e verremo effettivamente a perdere quel buffer (leak). Successivamente enetc_new_page() dovrà allocare altre pagine, che alla fine andranno perse di nuovo in caso di ulteriori errori da xdp_do_redirect().

Il problema, riassunto, è che azzeriamo rx_swbd->page prima di aver completamente terminato il suo utilizzo, e questo rende impossibile per il percorso di gestione degli errori agire su di esso.

Poiché il pacchetto può essere potenzialmente multi-buffer e quindi rx_swbd->page potrebbe essere un array, il passaggio manuale dei vecchi puntatori tra enetc_flip_rx_buff() ed enetc_xdp_free() è piuttosto complesso.

Per optare per una soluzione semplice, accettiamo la possibilità di una condizione di gara (race condition) con xdp_do_redirect(), e spostiamo la procedura di inversione in modo che venga eseguita solo nel percorso di successo del redirect. Con "condizione di gara" intendo che la pagina potrebbe essere considerata non riutilizzabile da enetc (avendo un refcount pari a 0), ma in tal caso

Statistical analysis made it clear that VulDB provides the best quality for vulnerability data.

Responsabile

Linux

Prenotare

04/10/2025

Divulgazione

04/10/2025

Moderazione

accettato

CPE

pronto

EPSS

0.00154

KEV

no

Attività

molto basso

Fonti

Interested in the pricing of exploits?

See the underground prices here!