CVE-2026-64560
posix-cpu-timers: Prevenire la UAF causata dalla race condition exec() di un non-leader
- Pubblicato
- 29 lug 2026
- Aggiornato
- 8 set 2026
- Assegnazione CNA
- Linux
- Evidenza osservata
- 10 ago 2026
CVSS primario
nvd · CVSS 3.1
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:HBasso · prossimi 30 giorni
- Percentile
- 35,5%
- Data del modello
- 21 set 2026
L'EPSS è una stima statistica, non una certezza o una misura di impatto. Combinalo con CVSS, stato KEV, esposizione e ambiente.
Riepilogo
Nel kernel Linux è stata risolta la seguente vulnerabilità: posix-cpu-timers: Previene l'UAF causato dalla race condition exec() non-leader Wongi e Jungwoo hanno decodificato e segnalato una race condition relativa a exec() non-leader che può causare un UAF: sys_timer_delete() exec() posix_cpu_timer_del() // Osserva il vecchio leader p = pid_task(pid, pid_type); de_thread() switch_leader(); release_task(old_leader) __exit_signal(old_leader) sighand = lock(old_leader, sighand); posix_cpu_timers*_exit(); sighand = lock_task_sighand(p) unhash_task(old_leader); sh = lock(p, sighand) old_leader->sighand = NULL; unlock(sighand); (p->sighand == NULL) unlock(sh) return NULL; // Restituisce senza azione if(!sighand) return 0; free_posix_timer(); Questo è "innocuo" a meno che il timer eliminato non fosse armato e accodato in p->signal perché su exec() un timer mirato a TGID viene ereditato. Poiché sys_timer_delete() ha liberato l'oggetto posix timer sottostante, run_posix_cpu_timers() o qualsiasi operazione add/delete sulla timerqueue relativa ad altri timer accederà al nodo timerqueue dell'oggetto liberato, il che comporta un UAF. Esiste un problema simile rispetto a posix_cpu_timer_set(). Per i posix timer regolari restituisce solo transitoriamente -ESRCH allo spazio utente, ma per il caso d'uso in do_cpu_nanosleep() è lo stesso UAF solo che il k_itimer è allocato sullo stack. Inoltre posix_cpu_timer_rearm() non riesce a riarmare il timer, il che significa che smette di scadere. Mentre si discutevano le soluzioni, Frederic ha evidenziato un altro problema: posix_cpu_timer_del(tmr) __exit_signal(p) posix_cpu_timers*_exit(p); unhash_task(p); p->sighand = NULL; sh = lock_task_sighand(p) sighand = p->sighand; if (!sighand) return NULL; lock(sighand); if (!sh) WARN_ON_ONCE(timer_queued(tmr)); Su architetture con ordinamento debole non è garantito che posix_cpu_timer_del() osservi gli store in posix_cpu_timers*_exit() quando p->sighand viene osservato come NULL, il che significa che il WARN() può essere un falso positivo. Risolvere questi problemi: 1) Modificando lo store in __exit_signal() in smp_store_release(). 2) Aggiungendo un smp_acquire__after_ctrl_dep() nel percorso !sighand di lock_task_sighand(). 3) Creando una funzione helper per la ricerca del task e il blocco di sighand che non restituisce quando sighand == NULL. Invece ritenta la ricerca del task e solo se questa fallisce desiste. 4) Usando tale helper nelle tre funzioni interessate. #1/#2 garantisce che il lato lettore che osserva sighand == NULL osservi anche tutti gli store precedenti, cioè gli store in posix_cpu_timers*_exit() e quelli in unhash_task(). #3 garantisce che la situazione exec() non-leader sopra descritta venga gestita correttamente. Quando la ricerca del task restituisce il vecchio leader, ma sighand == NULL, allora ritenta. Nel caso exec() non-leader la successiva ricerca del task osserverà il nuovo leader grazie a #1/#2. Negli scenari di exit() normali la successiva ricerca fallisce. Quando la ricerca del task fallisce, la funzione verifica anche se il timer è ancora accodato ed emette un avviso se è il caso. Purtroppo non c'è nulla che si possa fare al riguardo, ma poiché il task non è più visibile, il timer non dovrebbe più essere accessibile. Questo controllo richiede anche l'ordinamento della memoria, che non è fornito quando la prima ricerca fallisce. Per ottenere ciò, il controllo è preceduto da un smp_rmb() che si accoppia con lo smp_wmb() in write_seqlock() in __exit_signal(). Ciò garantisce che gli store in posix_cpu_timers*_exit() siano visibili. La storia del problema exec() non-leader risale ai primi giorni dei posix CPU timer, che memorizzavano un puntatore al task leader del gruppo nel timer. Ovviamente ciò fallisce quando un exec() non-leader cambia il leader. Il commit e0a70217107e ("posix-cpu-timers: workaround to suppress the problems with mt exec") ha aggiunto un workaround temporaneo per questo nel 2010 che soprav ---troncato---
Utilizzo responsabile
Utilizza le informazioni sulla vulnerabilità solo sui sistemi che possiedi o che sei autorizzato a testare. Kitploit si collega ai metadati della ricerca pubblica e non memorizza codici exploit o payload dannosi.