CVE-2026-98256
signal: prevenire la race condition di exec()
- Pubblicato
- 6 ott 2026
- Aggiornato
- 19 ott 2026
- Assegnazione CNA
- Linux
- Evidenza osservata
- 4 nov 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
- 3,7%
- Data del modello
- 4 nov 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à: signal: Prevenire la race di exec() Hyunwoo ha eseguito il debug del seguente splat KASAN UAF: BUG: KASAN: slab-use-after-free in __send_signal_locked+0xb27/0xba0 Write of size 8 at addr ffff888007ed80c8 by task poc/79 ... Call Trace: __send_signal_locked+0xb27/0xba0 do_send_sig_info+0xa7/0x160 do_send_specific+0x76/0xa0 __x64_sys_tgkill+0x193/0x270 ... Allocated by task 80: do_timer_create+0x1a4/0x1030 __x64_sys_timer_create+0x145/0x190 ... Freed by task 12: kmem_cache_free_bulk+0x1f8/0x4a0 kvfree_rcu_bulk+0x14f/0x1c0 kfree_rcu_work+0x128/0x1a0 ... Last potentially related work creation: kvfree_call_rcu+0x39/0x390 __flush_itimer_signals+0x211/0x320 flush_itimer_signals+0x47/0x90 begin_new_exec+0xa6b/0x28c0 È emerso che ciò accade con un exec() non-leader, come ha spiegato Hyunwoo: de_thread() chiama exchange_tids() prima di release_task(leader), quindi la struct pid mantenuta da un timer SIGEV_THREAD_ID creato sul tid del leader ora punta al thread che ha chiamato execve(). pid_task() restituisce quel thread e lock_task_sighand() su di esso ha successo. Se il segnale del timer è bloccato, il suo sigqueue rimane in coda su task::pending del leader. La successiva scadenza di quel timer può quindi essere eseguita mentre release_task() svuota la coda. posixtimer_send_sigqueue() verifica se il sigqueue è già in coda con un semplice list_empty(), che legge solo list_head::next. list_del_init() non è atomico e INIT_LIST_HEAD() memorizza list_head::next prima di list_head::prev, quindi il controllo può passare nel mezzo. list_add_tail() accoda la voce su task::pending del thread attivo, e la scrittura di list_head::prev da parte dello svuotamento sovrascrive poi il collegamento list_head::prev che list_add_tail() ha appena impostato. __flush_itimer_signals() non annulla nemmeno questo. Con list_head::prev che punta alla voce stessa, il suo list_del_init() memorizza solo gli stessi valori di nuovo, quindi la voce non viene rimossa dalla lista. È ancora lì dopo che l'ultimo riferimento è stato rilasciato e il timer è stato liberato da RCU, e il list_add_tail() di una successiva tgkill() segue quel list_head::prev nel timer liberato. Questo problema è emerso con il recente commit che ha spostato lo svuotamento del sigqueue fuori dalla regione protetta dal lock sighand. Hyonwoo ha proposto di risolverlo usando list_del_init_careful(), ma ciò si limita a mascherare il problema. Dopo alcune discussioni e vari tentativi di risolverlo, Eric ha fatto notare che non c'è motivo di svuotare task::pending in ritardo in release_task() e che dovrebbe essere già fatto in exit_signals(). Poiché nulla può raccogliere e consegnare i segnali accodati nella coda pending di un task morente, non c'è motivo di ritardarlo ulteriormente. Ma bisogna garantire che nessun segnale possa essere accodato dopo quel punto. exit_signals() imposta PF_EXITING in task::flags, che può essere usato come indicatore per questo. Lo si corregge: - Impedendo l'accodamento dei segnali per i segnali privati del task (PIDTYPE_PID) quando il task ha PF_EXITING impostato in __send_signal_locked() e in posixtimer_send_sigqueue(). - Proteggendo con il lock sighand l'impostazione non bloccata di PF_EXITING in exit_signals() per il caso di task group vuoto e di uscita del gruppo. - Svuotando proprio lì i segnali di task::pending. Ottimizzando ciò spostando l'intera lista pending su un list head sullo stack sotto il lock sighand e liberando i segnali senza il lock mantenuto. Ci sono state parecchie discussioni sullo svuotamento lockless e sul caso di exec non-leader su sistemi con ordinamento debole. Il problema è che una terza parte che tenta di inviare un segnale di timer posix si basa sulla ricerca del PID per trovare il task di destinazione e tale ricerca potrebbe risultare nel nuovo leader quando il segnale era originariamente diretto al vecchio leader. Nel caso in cui il segnale sia stato accodato sul vecchio leader, lo svuotamento lockless ha sollevato una preoccupazione riguardo alla seguente situazione: old_leader new_leader third party A: flush_list() // list_del_in ---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.