CVE-2026-98256
signal: предотвращение гонки при exec()
- Опубликовано
- 6 окт. 2026 г.
- Обновлено
- 19 окт. 2026 г.
- Назначение CNA
- Linux
- Наблюдены доказательства
- 4 нояб. 2026 г.
Первичный CVSS
nvd · CVSS 3.1
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:HНизкий · следующие 30 дней
- Процентиль
- 3,7 %
- Дата модели
- 4 нояб. 2026 г.
EPSS – это статистическая оценка, а не достоверность или мера воздействия. Объедините это с CVSS, статусом KEV, воздействием и вашей средой.
Резюме
В ядре Linux устранена следующая уязвимость: signal: предотвращение гонки при exec() Hyunwoo отладил следующий отчёт 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 Выяснилось, что это происходит при exec() не-лидера, как объяснил Hyunwoo: de_thread() вызывает exchange_tids() до release_task(leader), поэтому struct pid, удерживаемый таймером SIGEV_THREAD_ID, созданным для tid лидера, теперь указывает на поток, вызвавший execve(). pid_task() возвращает этот поток, и lock_task_sighand() на нём завершается успешно. Если сигнал таймера заблокирован, его sigqueue остаётся в очереди в task::pending лидера. Следующее срабатывание этого таймера может затем выполниться, пока release_task() сбрасывает очередь. posixtimer_send_sigqueue() проверяет, поставлен ли sigqueue в очередь, с помощью простого list_empty(), который читает только list_head::next. list_del_init() не является атомарной операцией, а INIT_LIST_HEAD() записывает list_head::next перед list_head::prev, поэтому проверка может пройти между этими операциями. list_add_tail() ставит элемент в очередь в task::pending живого потока, и последующая запись list_head::prev из сброса перезаписывает ссылку list_head::prev, только что установленную list_add_tail(). __flush_itimer_signals() также это не отменяет. Когда list_head::prev указывает на сам элемент, его list_del_init() лишь повторно записывает те же значения, поэтому элемент не удаляется из списка. Он остаётся там после сброса последней ссылки и освобождения таймера через RCU, и list_add_tail() последующего tgkill() следует по этой list_head::prev в освобождённый таймер. Эта проблема проявилась с недавним коммитом, который вынес сброс sigqueue за пределы области, удерживаемой блокировкой sighand. Hyonwoo предложил исправить это с помощью list_del_init_careful(), но это лишь маскирует проблему. После некоторых обсуждений и различных попыток её решить Eric указал, что нет причин сбрасывать task::pending поздно в release_task(), и это следует делать уже в exit_signals(). Поскольку ничто не может собрать и доставить сигналы, поставленные в очередь pending умирающей задачи, нет причин откладывать это дальше. Но необходимо гарантировать, что после этого момента в неё не могут быть поставлены никакие сигналы. exit_signals() устанавливает PF_EXITING в task::flags, что можно использовать как индикатор для этого. Исправление заключается в следующем: - Предотвращение постановки в очередь сигналов, приватных для задачи (PIDTYPE_PID), когда у задачи установлен PF_EXITING, в __send_signal_locked() и в posixtimer_send_sigqueue(). - Защита неблокированной установки PF_EXITING в exit_signals() для случая пустой группы задач и случая выхода группы с помощью блокировки sighand - Сброс сигналов task::pending прямо там. Оптимизировать это, переместив весь список pending в список на стеке под блокировкой sighand и освободив сигналы без удержания блокировки. Было довольно много обсуждений о неблокирующем сбросе и случае exec() не-лидера в системах со слабой упорядоченностью памяти. Проблема в том, что третья сторона, пытающаяся отправить сигнал posix-таймера, полагается на поиск по PID для нахождения целевой задачи, и этот поиск может дать нового лидера, когда сигнал изначально был направлен старому лидеру. В случае, если сигнал был поставлен в очередь старому лидеру, неблокирующий сброс вызвал опасения по поводу следующей ситуации: old_leader new_leader third party A: flush_list() // list_del_in ---обрезано---
Ответственное использование
Используйте информацию об уязвимостях только в тех системах, которыми вы владеете или имеете право тестировать. Kitploit ссылается на метаданные общедоступных исследований и не хранит код эксплойта или вредоносные полезные данные.