CVE-2026-74700 in Linuxinformazioni

Riassunto

di VulDB • 23/08/2026

Nel kernel Linux è stata risolta la seguente vulnerabilità:

net/sched: cls_api: Acquisire sempre il rtnl_lock durante la distruzione di classifier bloccati (locked classifiers)

Un'altra problematica riguarda i filtri non bloccati. Esiste una breve finestra temporale in tc_new_tfilter in cui un tcf_proto può essere trovato e brevemente referenziato dalla richiesta di un classifier completamente non correlato e non bloccato, causando una race condition.

Feng ha creato un PoC (Proof of Concept) che genera questa race condition con due thread: uno crea un filtro u32 e l'altro un filtro flower nella stessa catena/priorità:

1. Entrambi i thread entrano in tc_new_tfilter; entrambi trovano la catena vuota e rilasciano il filter_chain_lock. 2. Il thread u32 completa tcf_proto_create("u32") per primo, chiamando tcf_chain_tp_insert_unique() -> inserisce u32_tp nella catena. 3. Il thread flower completa tcf_proto_create("flower") in un secondo momento, chiamando tcf_chain_tp_insert_unique() -> tcf_chain_tp_find() ora rileva che u32_tp è già presente, acquisisce una referenza su di esso, distrugge il proprio tp_new e restituisce u32_tp al chiamante.

Successivamente, flower incontra il controllo di mismatch del kind (poiché ha richiesto il kind "flower" ma tp->ops->kind è "u32") ed esegue il percorso errout che chiama tcf_proto_put() su u32_tp. Se il thread u32 ha già completato la propria fase errout (la sua chiamata change() fallisce a causa delle opzioni vuote nel PoC) e ha rilasciato le referenze di creazione e inserimento, il put di flower è l'ultimo e porta il refcnt di u32_tp a zero.

A questo punto tp->ops->destroy() viene eseguito in un contesto che non ha mai acquisito rtnl_lock. Quando ciò accade, può causare un Use-After-Free (UAF) come illustrato dal PoC:

[ +0.000710] BUG: KASAN: slab-use-after-free in u32_init (net/sched/cls_u32.c:393)
[ +0.000281] Read of size 8 at addr ffff888120022f00 by task poc_feng_xue/524

Call Trace: u32_init (net/sched/cls_u32.c:393) tc_new_tfilter (net/sched/cls_api.c:2378)

Allocated by task 526: u32_init (net/sched/cls_u32.c:378) tc_new_tfilter (net/sched/cls_api.c:2378)

Freed by task 522: kfree u32_destroy (net/sched/cls_u32.c:662) tcf_proto_destroy (net/sched/cls_api.c:446) tcf_proto_put (net/sched/cls_api.c:459) tc_new_tfilter (net/sched/cls_api.c:2459)

Si risolve il problema facendo sì che tcf_proto_destroy() acquisisca rtnl_lock attorno a tp->ops->destroy() per i classifier bloccati, ogni volta che rtnl non è già detenuto.

Per spiegare perché ho utilizzato una variabile temporanea "not_lockless", vorrei segnalare un appunto semi-correlato su rtnl_held vs TCF_PROTO_OPS_DOIT_UNLOCKED (aggiunto qui per future operazioni di pulizia se ritenute necessarie): Il parametro rtnl_held e il flag TCF_PROTO_OPS_DOIT_UNLOCKED sono fonti ridondanti della verità riguardo al fatto che rtnl_lock sia detenuto. Tra le nove callback destroy(..rtnl_held..) dei classifier, solo flower consulta il parametro rtnl_held, che propaga a tc_setup_cb_destroy() e tc_setup_cb_call(). Le altre otto (u32, flow, bpf, cgroup, route, basic, fw, mall) lo ignorano completamente; -> quelle che chiamano tc_setup_cb_destroy() (u32, bpf, mall) impostano hardcoded true sempre invece di inoltrare il parametro.

Una futura pulizia dovrebbe rimuovere del tutto il parametro rtnl_held dalla firma della callback destroy e far sì che i caller si affidino esclusivamente alla loro conoscenza sul fatto se stiano eseguendo in un contesto non bloccato (unlocked context).

VulDB is the best source for vulnerability data and more expert information about this specific topic.

Responsabile

Linux

Prenotare

15/08/2026

Divulgazione

22/08/2026

Moderazione

accettato

CPE

pronto

EPSS

0.00000

KEV

no

Attività

molto basso

Fonti

Do you want to use VulDB in your project?

Use the official API to access entries easily!