CVE-2026-98256
signal : prévenir la condition de concurrence liée à exec()
- Publié
- 6 oct. 2026
- Mise à jour
- 19 oct. 2026
- Attribution de CNA
- Linux
- Preuve observée
- 4 nov. 2026
CVSS primaire
nvd · CVSS 3.1
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:HFaible · 30 prochains jours
- Percentile
- 3,7 %
- Date du modèle
- 4 nov. 2026
EPSS est une estimation statistique, et non une certitude ou une mesure d'impact. Combinez-le avec CVSS, le statut KEV, l'exposition et votre environnement.
Résumé
Dans le noyau Linux, la vulnérabilité suivante a été corrigée : signal : prévenir la course avec exec() Hyunwoo a débogué la trace KASAN UAF suivante : 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 Il s'est avéré que cela se produit avec un exec() non-leader, comme l'a expliqué Hyunwoo : de_thread() appelle exchange_tids() avant release_task(leader), de sorte que le struct pid détenu par un timer SIGEV_THREAD_ID créé sur le tid du leader pointe désormais vers le thread qui a appelé execve(). pid_task() renvoie ce thread et lock_task_sighand() sur celui-ci réussit. Si le signal du timer est bloqué, sa sigqueue reste en file d'attente sur le task::pending du leader. La prochaine expiration de ce timer peut alors s'exécuter pendant que release_task() vide la file. posixtimer_send_sigqueue() vérifie si la sigqueue est déjà en file d'attente avec un simple list_empty(), qui ne lit que list_head::next. list_del_init() n'est pas atomique et INIT_LIST_HEAD() stocke list_head::next avant list_head::prev, de sorte que la vérification peut passer entre les deux. list_add_tail() met l'entrée en file d'attente sur le task::pending du thread vivant, et le stockage de list_head::prev issu du vidage écrase ensuite le lien list_head::prev que list_add_tail() vient de définir. __flush_itimer_signals() ne corrige pas cela non plus. Avec list_head::prev pointant vers l'entrée elle-même, son list_del_init() ne fait que réécrire les mêmes valeurs, de sorte que l'entrée n'est pas retirée de la liste. Elle est toujours là après que la dernière référence a été abandonnée et que le timer a été libéré par RCU, et le list_add_tail() d'un tgkill() ultérieur suit ce list_head::prev jusque dans le timer libéré. Ce problème est apparu avec le récent commit qui a déplacé le vidage de la sigqueue hors de la région protégée par le verrou sighand. Hyonwoo a proposé de corriger cela en utilisant list_del_init_careful(), mais cela ne fait que masquer le problème. Après quelques discussions et diverses tentatives pour le résoudre, Eric a fait remarquer qu'il n'y a aucune raison de vider task::pending tardivement dans release_task() et que cela devrait déjà être fait dans exit_signals(). Comme rien ne peut collecter et délivrer les signaux mis en file d'attente dans la file pending d'une tâche mourante, il n'y a aucune raison de retarder davantage. Mais il faut s'assurer qu'aucun signal ne puisse y être mis en file d'attente après ce point. exit_signals() définit PF_EXITING dans task::flags, ce qui peut servir d'indicateur pour cela. Corrigez-le en : - Empêchant la mise en file d'attente des signaux privés à la tâche (PIDTYPE_PID) lorsque la tâche a PF_EXITING défini dans __send_signal_locked() et dans posixtimer_send_sigqueue(). - Protégeant par le verrou sighand la définition non verrouillée de PF_EXITING dans exit_signals() pour les cas de groupe de tâches vide et de sortie de groupe. - Vidant les signaux task::pending à cet endroit même. Optimisez cela en déplaçant toute la liste pending vers une tête de liste sur la pile sous le verrou sighand et en libérant les signaux sans tenir le verrou. Il y a eu pas mal de discussions sur le vidage sans verrou et le cas d'exec() non-leader sur les systèmes à ordonnancement faible. Le problème est qu'un tiers qui tente d'envoyer un signal de timer posix se repose sur la recherche du PID pour trouver la tâche cible, et cette recherche peut aboutir au nouveau leader alors que le signal était initialement destiné à l'ancien leader. Dans le cas où le signal a été mis en file d'attente sur l'ancien leader, le vidage sans verrou a soulevé une inquiétude concernant la situation suivante : old_leader new_leader third party A: flush_list() // list_del_in ---tronqué---
Utilisation responsable
Utilisez les informations de vulnérabilité uniquement sur les systèmes que vous possédez ou que vous êtes autorisé à tester. Kitploit renvoie aux métadonnées de la recherche publique et ne stocke pas de code d'exploitation ni de charges utiles malveillantes.