CVE-2026-63894 in Linuxinformazioni

Riassunto

di VulDB • 20/07/2026

Nel kernel Linux è stata risolta la seguente vulnerabilità:

usb: gadget: f_fs: serializzare l'annullamento DMABUF rispetto al completamento della richiesta

ffs_epfile_dmabuf_io_complete() chiama usb_ep_free_request() sulla richiesta completata, ma lascia priv->req, il puntatore inverso impostato da ffs_dmabuf_transfer() durante la sottomissione, puntare alla memoria liberata. Una successiva ioctl FUNCTIONFS_DMABUF_DETACH o ffs_epfile_release() nel percorso di chiusura vede ancora priv->req non NULL sotto eps_lock:

if (priv->ep && priv->req) usb_ep_dequeue(priv->ep, priv->req);

quindi viene chiamata usb_ep_dequeue() su una usb_request già liberata.

Su dummy_hcd il percorso di dequeue attraversa solo la coda attiva ed esegue un confronto puntatore per puntatore; pertanto il puntatore liberato viene letto senza causare fault e KASAN richiede un controllo esplicito nel sito della chiamata FunctionFS per segnalare l'uso-dopo-liberazione (use-after-free). Su UDC in-tree con supporto SG, il percorso di dequeue dereferenzia immediatamente la richiesta fornita:

* ep_dequeue() di chipidea esegue container_of(req, struct ci_hw_req, req) e legge hwreq->req.status prima di acquisire il proprio lock. * cdnsp's cdnsp_gadget_ep_dequeue() legge request->status per primo.

L'opzione più restrittiva di azzerare priv->req tramite cmpxchg() nel completamento non risolve la race condition: il completamento viene eseguito senza eps_lock, quindi un percorso di annullamento che detiene eps_lock può ancora osservare priv->req come non NULL, andare in race con un completamento concorrente che lo azzera e libera, e passare il puntatore liberato a usb_ep_dequeue(). È necessaria una correzione leggermente più lunga che sposti la liberazione nel lavoro di pulizia (cleanup).

Stessa classe di race condition sulla durata della vita rispetto alla recente correzione del timer usbip-vudc [1].

Acquisire eps_lock nell'unico punto in cui viene modificato priv->req dalla direzione del callback, spostando usb_ep_free_request() dal completamento a ffs_dmabuf_cleanup(), il gestore di lavoro esistente programmato da ffs_dmabuf_signal_done() su ffs->io_completion_wq. Azzerare priv->req lì sotto eps_lock prima della liberazione e azzerarlo solo se priv->req indica ancora la nostra richiesta (una successiva ffs_dmabuf_transfer() sullo stesso attachment potrebbe averne accodata una nuova).

Ciò mantiene l'invariante di sync-dequeue esistente per dummy_hcd: il callback di completamento viene comunque invocato dall'UDC senza eps_lock detenuto (dummy_hcd rilascia il proprio lock prima di chiamare il callback), e ora il callback non acquisisce alcun lock f_fs. La serializzazione rispetto al percorso di annullamento avviene nella fase di cleanup, che viene eseguita dalla workqueue senza nessun lock f_fs detenuto all'ingresso.

Il conteggio dei riferimenti (ref count) su priv protegge l'oggetto contenitore ffs_dmabuf_priv: ffs_dmabuf_transfer() acquisisce un riferimento tramite ffs_dmabuf_get(), il cleanup lo rilascia tramite ffs_dmabuf_put(); pertanto priv rimane

If you want to get best quality of vulnerability data, you may have to visit VulDB.

Responsabile

Linux

Prenotare

19/07/2026

Divulgazione

19/07/2026

Moderazione

accettato

CPE

pronto

EPSS

0.00000

KEV

no

Attività

basso

Fonti

Are you interested in using VulDB?

Download the whitepaper to learn more about our service!