Ad

CVE-2026-72166

NONE EPSS 0.21%
Обновлено 23 августа 2026
Linux
Параметр Значение
Поставщик Linux
Публичный эксплойт Нет

В ядре Linux устранена следующая уязвимость: net/9p: исправлен бесконечный цикл в p9_client_rpc при фатальном сигнале. Когда p9_client_rpc() вызывается с типом P9_TFLUSH и транспортный не имеет однорангового узла (например, транспорт fd, поддерживаемый каналами без сервера 9p), фатальный сигнал вызывает бесконечный цикл: еще раз: err = io_wait_event_killable(req->wq, ...) /* SIGKILL пробуждает задачу и возвращает -ERESTARTSYS */ if (err == -ERESTARTSYS && c->status == Подключено && тип == P9_TFLUSH) { ожидание = 1; Clear_thread_flag (TIF_SIGPENDING); перейти еще раз; } clear_thread_flag() очищает TIF_SIGPENDING перед возвратом к io_wait_event_killable(). signal_pending_state() проверяет TIF_SIGPENDING, находит его нулевым, и задача снова переходит в режим сна. Задача может только разбудить при следующей доставке сигнала, который вызывает signal_wake_up() и устанавливает TIF_SIGPENDING еще раз.

Когда это происходит, цикл повторяется, очищается TIF_SIGPENDING и снова переходит в режим ожидания на неопределенный срок. На практике это вызывается функцией coredump_wait(): когда поток в многопоточный процесс вызывает дамп памяти (например, через SIGSYS из Syscall User Dispatch), coredump_wait() отправляет SIGKILL всем остальным потокам и ждет, пока они вызовут mm_release(). Если один из этих потоков заблокирован в p9_client_rpc() через транспорт fd без однорангового узла он входит в Цикл P9_TFLUSH и никогда не вызывает mm_release(), поэтому coredump_wait() останавливается. навсегда: ИНФО: задача syz.0.18:676 заблокирована более чем на 143 секунды.

Не испорчен 6.12.77+ #1 задача: syz.0.18 состояние: D стек: 27600 pid: 676 tgid: 673 ppid: 630 флаги: 0x00000004 Отслеживание вызова: <ЗАДАЧА> context_switch kernel/sched/core.c:5344 [встроенный] __schedule+0xcb4/0x5d50 ядро/sched/core.c:6724 __schedule_loop ядро/sched/core.c:6801 [встроенный] расписание+0xe5/0x350 ядро/sched/core.c:6816 Schedule_timeout+0x253/0x290 ядро/время/timer.c:2593 do_wait_for_common kernel/sched/completion.c:95 [встроенный] __wait_for_common+0x409/0x600 ядро/sched/completion.c:116 wait_for_common kernel/sched/completion.c:127 [встроенный] wait_for_completion_state+0x1d/0x40 ядро/sched/completion.c:264 coredump_wait fs/coredump.c:448 [встроенный] do_coredump+0x854/0x4350 фс/coredump.c:629 get_signal+0x1425/0x2730 ядро/signal.c:2903 Arch_do_signal_or_restart+0x81/0x880 Arch/x86/kernel/signal.c:337 exit_to_user_mode_loop kernel/entry/common.c:111 [встроенный] exit_to_user_mode_prepare include/linux/entry-common.h:328 [встроенный] __syscall_exit_to_user_mode_work kernel/entry/common.c:207 [встроенный] syscall_exit_to_user_mode+0xf9/0x160 kernel/entry/common.c:218 do_syscall_64+0x102/0x220 Arch/x86/entry/common.c:84 запись_SYSCALL_64_after_hwframe+0x77/0x7f </TASK> Исправлено: проверьте Fatal_signal_pending() перед очисткой TIF_SIGPENDING в P9_TFLUSH цикл повтора. В этот момент TIF_SIGPENDING все еще установлен, поэтому Fatal_signal_pending() работает правильно. Если ожидается фатальный сигнал, перейдите к Recalc_sigpending, чтобы восстановить TIF_SIGPENDING и вернуться -ERESTARTSYS вызывающему абоненту.

Тот же дефект присутствует в стабильных ядрах начиная с версии 5.4. На тех ядрах бесконечный цикл прерывается ранее вторым сигналом SIGKILL от родительский процесс (например, kill_and_wait() повторяет попытку после таймаута), что приводит к процессу-зомби и задержке завершения работы, а не к постоянное зависание D-состояния, но основной недостаток тот же. Найден Центром проверки Linux (linuxtesting.org) с помощью Syzkaller.

Показать оригинальное описание (EN)

In the Linux kernel, the following vulnerability has been resolved: net/9p: fix infinite loop in p9_client_rpc on fatal signal When p9_client_rpc() is called with type P9_TFLUSH and the transport has no peer (e.g. fd transport backed by pipes with no 9p server), a fatal signal causes an infinite loop: again: err = io_wait_event_killable(req->wq, ...) /* SIGKILL wakes the task, returns -ERESTARTSYS */ if (err == -ERESTARTSYS && c->status == Connected && type == P9_TFLUSH) { sigpending = 1; clear_thread_flag(TIF_SIGPENDING); goto again; } clear_thread_flag() clears TIF_SIGPENDING before jumping back to io_wait_event_killable(). signal_pending_state() checks TIF_SIGPENDING, finds it zero, and the task goes to sleep again. The task can only wake on the next signal delivery that calls signal_wake_up() and sets TIF_SIGPENDING again. When that happens the loop repeats, clears TIF_SIGPENDING, and sleeps again indefinitely. This is triggered in practice by coredump_wait(): when a thread in a multi-threaded process causes a coredump (e.g. via SIGSYS from Syscall User Dispatch), coredump_wait() sends SIGKILL to all other threads and waits for them to call mm_release(). If one of those threads is blocked in p9_client_rpc() over an fd transport with no peer, it enters the P9_TFLUSH loop and never calls mm_release(), so coredump_wait() stalls forever: INFO: task syz.0.18:676 blocked for more than 143 seconds. Not tainted 6.12.77+ #1 task:syz.0.18 state:D stack:27600 pid:676 tgid:673 ppid:630 flags:0x00000004 Call Trace: <TASK> context_switch kernel/sched/core.c:5344 [inline] __schedule+0xcb4/0x5d50 kernel/sched/core.c:6724 __schedule_loop kernel/sched/core.c:6801 [inline] schedule+0xe5/0x350 kernel/sched/core.c:6816 schedule_timeout+0x253/0x290 kernel/time/timer.c:2593 do_wait_for_common kernel/sched/completion.c:95 [inline] __wait_for_common+0x409/0x600 kernel/sched/completion.c:116 wait_for_common kernel/sched/completion.c:127 [inline] wait_for_completion_state+0x1d/0x40 kernel/sched/completion.c:264 coredump_wait fs/coredump.c:448 [inline] do_coredump+0x854/0x4350 fs/coredump.c:629 get_signal+0x1425/0x2730 kernel/signal.c:2903 arch_do_signal_or_restart+0x81/0x880 arch/x86/kernel/signal.c:337 exit_to_user_mode_loop kernel/entry/common.c:111 [inline] exit_to_user_mode_prepare include/linux/entry-common.h:328 [inline] __syscall_exit_to_user_mode_work kernel/entry/common.c:207 [inline] syscall_exit_to_user_mode+0xf9/0x160 kernel/entry/common.c:218 do_syscall_64+0x102/0x220 arch/x86/entry/common.c:84 entry_SYSCALL_64_after_hwframe+0x77/0x7f </TASK> Fix: check fatal_signal_pending() before clearing TIF_SIGPENDING in the P9_TFLUSH retry loop. At that point TIF_SIGPENDING is still set, so fatal_signal_pending() works correctly. If a fatal signal is pending, jump to recalc_sigpending to restore TIF_SIGPENDING and return -ERESTARTSYS to the caller. The same defect is present in stable kernels back to 5.4. On those kernels the infinite loop is broken earlier by a second SIGKILL from the parent process (e.g. kill_and_wait() retrying after a timeout), resulting in a zombie process and a shutdown delay rather than a permanent D-state hang, but the underlying flaw is the same. Found by Linux Verification Center (linuxtesting.org) with Syzkaller.