7 августа 2026 года появилась информация о TONTOU — новой технике атаки на механизмы защиты от Spectre v2. Интересна она не столько скоростью утечки — она как раз невелика, — сколько способом обхода защиты.
Spectre v2 использует ошибочные предсказания косвенных переходов. Процессор ради производительности заранее угадывает, куда пойдёт выполнение, и начинает исполнять инструкции ещё до того, как убедится, что угадал правильно. Если атакующему удаётся «обучить» механизм предсказания нужным образом, процессор может на короткое время начать выполнять код по адресу, выбранному атакующим. Архитектурно результат такого ошибочного выполнения затем отменяется, но побочные эффекты — например, изменения состояния кэша — остаются. По ним можно восстановить данные, которые обычный процесс вообще не должен был иметь возможности прочитать, в том числе данные ядра или другого изолированного контекста.
Исследователи из MIT CSAIL смогли показать интересный момент: между моментом, когда процессор или ядро очищает состояние механизма предсказания переходов, и моментом, когда этим состоянием снова пользуются, неизбежно существует небольшой промежуток. Иногда — всего несколько инструкций. И если в этот момент заставить процессор обработать прерывание, состояние предсказателя можно снова испортить.
Назвали этот класс уязвимостей «TONTOU» — Time‑of‑Neutralization to Time‑of‑Use, по аналогии с хорошо известным классом TOCTOU (Time‑of‑Check to Time‑of‑Use). В TOCTOU объект успевает измениться между проверкой и использованием; здесь то же происходит с состоянием предсказателя — его нейтрализовали, но до следующего использования прерывание успевает снова его изменить.
Что именно сломали
На AMD проблема особенно интересна из‑за Safe RET — программной защиты Linux от SRSO, Speculative Return Stack Overflow, одного из многочисленных потомков Spectre.
Safe RET устроен довольно радикально: возвраты из функций специально заставляют процессор ошибаться предсказанием контролируемым образом. Перед использованием механизма возвратов ядро приводит предсказатель в известное безопасное состояние. Это дешевле, чем применять тяжёлый IBPB при каждом переходе между уровнями привилегий, поэтому Safe RET и выбран в Linux по умолчанию.
До сих пор предполагалось примерно следующее:

TONTOU добавляет в эту картину совсем немного:

На AMD окно удалось сократить до двух инструкций — буквально нескольких десятков наносекунд. Казалось бы, «попасть» в него практически невозможно.
Оказалось, возможно.
Исследователи замедляли исполнение в нужной точке и использовали точно настроенный таймер, чтобы прерывание приходилось именно на этот промежуток. Обычный непривилегированный процесс может создавать таймеры, поэтому какого‑то специального доступа к APIC или ядру для самой идеи атаки не требуется.
И это уже не просто «лабораторный фокус» с ошибочным предсказанием
На AMD исследователи построили работающую цепочку извлечения данных из памяти ядра.
Получилось:
около 5,47 байта в секунду;
точность 91,97%;
в десяти экспериментах поиск и извлечение находившегося в памяти
/etc/shadowудалось выполнить пять раз;один эксперимент занимал в среднем около 18 минут.
То есть перед нами не чтение гигабайтов памяти в секунду и не удалённая дыра в сетевом стеке. Да, атакующему уже нужно исполнять код на машине. Но несколько байт в секунду вполне достаточно, если цель — парольный хэш, ключ или другой небольшой секрет.
MIT получил ошибочные предсказания на четырёх поколениях процессоров Intel и AMD. AMD в бюллетене AMD‑SB-7061 указывает как затронутые Zen 1–Zen 4; непосредственно исследователи продемонстрировали проблему на Zen 1 и Zen 2 и считают применимой технику также к Zen 3 и Zen 4. На Intel атака тоже работает на микроархитектурном уровне, но построение полноценного эксплуатационного сценария сложнее. По состоянию на 7 августа отдельный CVE в бюллетене AMD для этой проблемы не указан. Есть идентификатор самого бюллетеня — AMD‑SB-7061.
Что делать с TONTOU
Исправление уже принято в Linux. Оно вошло в upstream stable‑ветки 7.1.7, 6.18.43, 6.12.102, 6.6.149, 6.1.181, 5.15.214 и 5.10.263. У дистрибутивов исправление, разумеется, может оказаться в ядре с совсем другим номером из‑за backport, поэтому сравнивать только uname -r с этим списком не стоит.
Проверять машину в первую очередь стоит так:
uname -r grep . /sys/devices/system/cpu/vulnerabilities/* cat /sys/devices/system/cpu/vulnerabilities/spec_rstack_overflow
Для SRSO на AMD нормальным вариантом на уязвимом процессоре после установки необходимых исправлений будет строка примерно такого вида:
Mitigation: Safe RET
При этом для полноценной защиты SRSO Linux рекомендует иметь и актуальный микрокод CPU.
Во сколько обойдётся одной свежее исправление TONTOU по производительности, пока сказать нельзя. Уязвимость опубликована только что, нормальных сравнительных тестов patched/unpatched ещё нет, а подставлять сюда цифры от старого Safe RET было бы неправильно: сам Safe RET уже работал до TONTOU, а сейчас изменился способ защиты критического промежутка вокруг прерываний.
Собственно, это хороший повод посмотреть, сколько вообще накопилось подобных защит за восемь лет.
Восемь лет после Spectre
Сразу оговорюсь: проценты ниже нельзя складывать, так как многие защиты перекрываются. Например, одна и та же очистка буферов может закрывать MDS и TAA, а новый процессор вообще выполняет часть старых защит аппаратно. Кроме того, цена очень сильно зависит от того, сколько приложение делает системных вызовов, переключений контекста, VMEXIT, операций ввода‑вывода и косвенных переходов.
Поэтому значения ниже — порядок величины и опубликованные худшие случаи, а не обещание, что условный PostgreSQL потеряет именно столько же на вашем сервере.
Год | Уязвимость | Чем защищаемся | Чем отключить в Linux | Цена |
|---|---|---|---|---|
2018 | Meltdown CVE-2017-5754 | PTI/KPTI, раздельные таблицы страниц kernel/userspace |
| На вычислительной нагрузке мало; больнее всего syscall/interrupt‑heavy нагрузке. В тестах Red Hat весь тогдашний комплект Meltdown+Spectre после оптимизации давал примерно 1–8%, CPU‑heavy задачи — около 1–2%. |
2018 | Spectre v1 CVE-2017-5753 | точечные барьеры и проверки в уязвимых местах кода |
| Единого процента практически нет: защита вставляется в конкретные опасные места. Обычно заметно дешевле глобальных переключений адресных пространств и predictor flush. |
2018 → сейчас | Spectre v2 / BHI CVE-2017-5715 и потомки | retpoline, eIBRS/IBRS, IBPB, STIBP, RSB filling, BHB clearing |
| На старых Haswell/Broadwell весь комплект 2018 года после retpoline давал 1–8%, у частых kernel/userspace transitions — порядка 4–8%. Современные CPU обычно обходятся дешевле благодаря аппаратным механизмам. |
2018 | L1TF / Foreshadow | инверсия PTE, изменение таблиц страниц, очистка кэша первого уровня перед входом в виртуальную машину; для полной изоляции — отключение многопоточности |
| Защита bare metal через PTE inversion у Red Hat дала 0%. Условный flush при VM‑entry обычно не измерялся, максимум около 3–4%. Flush на каждом VM‑entry доходил до 14%, а без свежего микрокода — до 27%. |
2019 | MDS / ZombieLoad / RIDL / Fallout | очистка внутренних буферов процессора; для полной защиты между потоками — отключение многопоточности |
| Обычно несколько процентов, но особенно чувствительны syscall/context‑switch/I/O нагрузки. Полная защита может стоить существенно больше из‑за отключения SMT; поэтому честного единого процента здесь нет. Linux прямо разделяет |
2022 | Retbleed CVE-2022-29900/29901 | защитные подмены возвратов, контроль глубины вызовов и очистка предсказателя |
| Одна из самых дорогих защит: авторы Retbleed измеряли падение производительности на 14–39% на затронутых AMD Zen 1/1+/2 и Intel 6–8 поколений. Позднее часть этих потерь удалось сократить оптимизациями. |
2023 | Zenbleed CVE-2023-20593, AMD Zen 2 | обновлённый микрокод; при его отсутствии Linux включает программный обход | штатного удобного | В тестах программного workaround отдельные encoder/render workloads теряли до ~15%, большая часть обычных приложений и игр — почти ничего. Микрокод предпочтительнее программного workaround. |
2023 | Downfall / GDS CVE-2022-40982 | микрокод запрещает опасную спекуляцию при векторном чтении памяти |
| Intel говорит о минимальном влиянии для большинства программ, но gather‑heavy код может терять до 50%. Это один из лучших примеров, почему среднее значение здесь бессмысленно. |
2023 | Inception / SRSO CVE-2023-20569 | защищённый механизм возврата; альтернативно — очистка предсказателя |
| Огромный разброс. Для тяжёлых вариантов защиты опубликованы случаи до −54% MariaDB, около +29% времени компиляции ядра, тогда как Blender и браузер теряли около процента. IBPB часто оказывался самым дорогим; штатный Safe RET обычно дешевле. |
2024 | RFDS CVE-2023-28746 | микрокод и очистка внутренних буферов при возврате в пользовательский режим и перед входом в виртуальную машину |
| В тестах Raptor Lake большинство нагрузок потеряли немного; nginx — около 4%, context switch вырос со 126 до 139 тактов, то есть примерно на 10% именно для этой микрооперации. |
2025 | ITS — Indirect Target Selection CVE-2024-28956 | новый микрокод плюс aligned branch/return thunks |
| Хороших универсальных публичных измерений пока недостаточно. Цена зависит от того, сколько реально приходится заменять indirect branch/RET; Linux умеет применять защиту только для VM‑сценария через |
2025 | TSA — Transient Scheduler Attacks, AMD | очистка состояния на границах безопасности; можно отдельно защищать user/kernel и VM |
| Репрезентативного набора сравнительных бенчмарков пока нет. Это как раз случай, где модель угроз полезнее попытки найти магическую среднюю цифру. |
2025 | VMSCAPE | условный IBPB после выхода из потенциально враждебной VM перед возвратом в host userspace |
| Исследователи сообщали о небольшом/практически незаметном среднем overhead благодаря условному IBPB; цена растёт с частотой VMEXIT и переходов в userspace. В Linux защита специально не делает IBPB там, где он не нужен. |
2026 | TONTOU / Safe RET Interrupt | обновлённый Linux + существующая SRSO/Safe RET защита | фактически отключается вместе с SRSO: | Пока неизвестно. Отдельных нормальных бенчмарков свежего исправления ещё нет. |
Список, конечно, неполный. Здесь сознательно нет десятков более узких вариантов Spectre, SRBDS, MMIO Stale Data, отдельных SGX/SEV‑проблем и firmware‑only CVE. Иначе вместо небольшой ретроспективы получится справочник по /sys/devices/system/cpu/vulnerabilities.
Но тенденция видна хорошо: сначала мы платили за отдельные защиты, потом защиты начали взаимодействовать друг с другом. Затем появились атаки на сами предположения, лежащие в основе этих защит: Retbleed обошёл retpoline, Inception/SRSO потребовал Safe RET, а теперь TONTOU показывает, что недостаточно даже очистить predictor — необходимо гарантировать, что между очисткой и использованием никто не успеет снова его загрязнить.
Как посмотреть, за что платит конкретно ваш сервер
Linux уже даёт почти всё необходимое:
grep . /sys/devices/system/cpu/vulnerabilities/*
На современном сервере получится что‑то вроде:
.../meltdown:Not affected .../mds:Not affected .../retbleed:Mitigation: ... .../spectre_v1:Mitigation: ... .../spectre_v2:Mitigation: Enhanced / Automatic IBRS; ... .../spec_rstack_overflow:Mitigation: Safe RET ...
Это значительно полезнее, чем смотреть список всех опубликованных CPU CVE: большая часть из них к конкретному процессору просто не относится.
Полезно сохранить также:
lscpu cat /proc/cmdline dmesg | grep -i microcode
И только после этого экспериментировать с параметрами ядра.
Как включить всё
В нормальной ситуации ничего специально включать не требуется: Linux сам выбирает необходимые защиты для обнаруженного CPU.
Явно попросить стандартный защищённый режим можно параметром:
mitigations=auto
Если нужна максимально полная защита в том числе между SMT siblings:
mitigations=auto,nosmt
Второй вариант потенциально самый дорогой: на процессорах, где полная защита MDS, L1TF и некоторых других атак требует отказа от SMT, ядро его отключит.
Но с Linux 6.17 появился вариант лучше, чем mitigations=off
Начинается самая полезная для администратора часть всей истории. Начиная с Linux 6.17 защиты можно выбирать не по названиям очередных уязвимостей, а по реальной модели атаки. Ядро знает пять направлений:
user → kernel;
user → user;
guest → host;
guest → guest;
атаки между SMT threads.
И Linux прямо рекомендует администратору отключать те направления, которых на конкретной машине нет, чтобы вернуть часть производительности. Новые уязвимости в дальнейшем автоматически попадают под соответствующий класс, поэтому список параметров не приходится переписывать после появления каждого нового красивого названия.
Например, физический сервер вообще не запускает KVM и никаких VM на нём не будет:
mitigations=auto,no_guest_host,no_guest_guest
Это гораздо разумнее, чем:
mitigations=off
Мы оставили защиту ядра от локального процесса и процессов друг от друга, но перестали платить за границы безопасности, которых на этой машине не существует.
Если сервер запускает одну собственную VM и между гостями тоже нечего изолировать, модель можно подбирать аналогично.
Есть и:
no_user_kernel no_user_user no_guest_host no_guest_guest no_cross_thread
Причём индивидуальные параметры вроде:
retbleed=off spec_rstack_overflow=off gather_data_sampling=off
имеют приоритет над общей политикой mitigations=.
А когда всё‑таки имеет смысл mitigations=off
Linux позволяет сказать прямо:
mitigations=off
и отключить практически весь набор опциональных CPU mitigations.
На старом железе разница действительно бывает хорошо заметна. Например, для Ryzen 9 3950X в одном большом наборе тестов полностью отключённые mitigations давали в среднем примерно 5,4% относительно штатной конфигурации. Но более тяжёлый вариант Retbleed через IBPB уже опускал систему примерно до 75% полностью незащищённой производительности.
На другой старой машине выигрыш может оказаться 15–20%, а на современном процессоре — попасть в погрешность.
Поэтому я бы не формулировал правило как «сервер мой, значит mitigations=off безопасен».
Главный вопрос другой:
может ли на CPU когда‑нибудь и как‑нибудь выполняться код, которому мы не доверяем?
Ответ простой: если у нас что‑то из
shared hosting;
shell для пользователей;
Kubernetes с чужими workload;
CI runner, выполняющий присланный код;
KVM с чужими VM;
браузер;
плагины и JIT;
сервис, где успешный RCE превращает удалённого атакующего в локальный процесс,
то CPU mitigations имеют вполне реальный смысл.
Даже обычный выделенный nginx/PostgreSQL‑сервер, принадлежащий одной компании, не автоматически относится к категории trusted code: RCE в сетевом сервисе как раз и превращает удалённую ошибку в локальный код, необходимый большинству описанных выше атак.
А вот вычислительный узел с жёстко фиксированным собственным бинарником, без посторонних пользователей, VM, контейнеров с чужим кодом и динамических workload — уже вполне нормальный кандидат для осознанного сравнения с mitigations=off.
Не потому, что уязвимости «ненастоящие», а потому, что отсутствует необходимая для их эксплуатации граница между доверенным и недоверенным кодом.
Как переключать это на практике
На Debian/Ubuntu параметры ядра обычно добавляются в /etc/default/grub.
Например:
sudoedit /etc/default/grub
Было:
GRUB_CMDLINE_LINUX_DEFAULT="quiet"
Стало:
GRUB_CMDLINE_LINUX_DEFAULT="quiet mitigations=auto,no_guest_host,no_guest_guest"
После этого:
sudo update-grub sudo reboot
Для полного отключения:
GRUB_CMDLINE_LINUX_DEFAULT="quiet mitigations=off"
Для возврата к нормальной защите достаточно убрать этот параметр либо явно поставить:
mitigations=auto
На RHEL‑подобных системах удобнее grubby:
sudo grubby --update-kernel=ALL --args='mitigations=auto,no_guest_host,no_guest_guest' sudo reboot
Или:
sudo grubby --update-kernel=ALL --args='mitigations=off' sudo reboot
После загрузки обязательно проверить, что получилось на самом деле:
cat /proc/cmdline grep . /sys/devices/system/cpu/vulnerabilities/*
Как узнать реальную цену защиты
Есть соблазн найти таблицу: Spectre — 5%, Meltdown — 3%, Retbleed — 14%, всё сложить и получить стоимость безопасности.
Так это не работает.
Правильный эксперимент для конкретного сервера гораздо проще:
Оставить штатный
mitigations=auto.Прогнать настоящую нагрузку.
Отключить только заведомо ненужные attack vectors.
Повторить тест.
И только ради контрольной точки попробовать
mitigations=off.
Например, для PostgreSQL интересны не sysbench cpu и не UnixBench, а реальные TPS, p95/p99 latency и CPU time на вашем профиле запросов.
Для nginx — requests/s и latency при вашем TLS, размере ответа и keepalive.
Для storage — именно тот fio, который похож на рабочий I/O.
Для компиляционного сервера — время настоящей сборки.
И если получается:
auto 100% без guest-защит 100.2% mitigations=off 100.5%
то обсуждать здесь особенно нечего.
А если старый Zen 2 показывает:
auto 82% только нужные attack vectors 94% mitigations=off 100%
то уже есть предмет для нормального решения, а не религиозного спора о том, «нужен ли Spectre».
Практика: что поставить на конкретном сервере
Начиная с Linux 6.17 защиты можно настраивать не только по отдельным уязвимостям, но и по направлениям возможной атаки. Ядро различает пять таких случаев: «процесс → ядро», «процесс → процесс», «виртуальная машина → основная система», «виртуальная машина → виртуальная машина» и атаки между соседними аппаратными потоками. Это позволяет отключить только те меры защиты, которые на конкретном сервере не нужны.
Отсюда получаются несколько практических профилей.
Обычный выделенный сервер: nginx, PostgreSQL, почта и тому подобное, виртуальных машин нет
mitigations=auto,no_guest_host,no_guest_guest
Защита процессов и ядра остаётся, а ненужные меры для виртуализации отключаются. Для большинства обычных серверов без KVM это разумный вариант по умолчанию.
KVM‑сервер с одной виртуальной машиной
mitigations=auto,no_guest_guest
Защита основной системы от гостевой остаётся, но защита одной виртуальной машины от другой бессмысленна: второй машины просто нет.
Гипервизор с несколькими виртуальными машинами разных клиентов или разной степени доверия
mitigations=auto,nosmt
Максимальная защита. На некоторых процессорах ядро ради неё отключит одновременную многопоточность, поэтому потери производительности могут быть заметными.
CI‑сервер или сборочная машина, где исполняется чужой код
mitigations=auto,nosmt,no_guest_host,no_guest_guest
Виртуальных машин нет, поэтому соответствующие защиты не нужны. Зато изоляция пользовательского кода, ядра и соседних потоков процессора здесь как раз важна.
Домашняя рабочая станция
mitigations=auto
Обычно ничего трогать не стоит. Ядро само выбирает необходимые защиты для конкретного процессора.
Изолированный вычислительный узел, где выполняется только полностью доверенный код
mitigations=off
Это уже осознанный обмен безопасности на производительность. Такой режим имеет смысл только там, где посторонний код действительно не может исполняться. Для обычного публичного веб‑сервера аргумент «сервер ведь мой» недостаточен: уязвимость с удалённым выполнением кода может дать атакующему возможность исполнять свой код внутри процесса на сервере, а этого уже достаточно для попытки использовать многие процессорные уязвимости.
Посмотреть, что получилось после перезагрузки:
cat /proc/cmdline grep . /sys/devices/system/cpu/vulnerabilities/*
Вместо вывода, или восемь лет спустя
Если кто вспомнит те годы, припомните: когда в начале 2018 года Spectre и Meltdown стали достоянием публики, история выглядела почти катастрофически. Intel знала об уязвимостях ещё с июня предыдущего года, в октябре генеральный директор Intel Брайан Кржанич оформил план продажи принадлежавших ему акций компании (и, кстати, 29 ноября он продал почти всё, что мог продать по корпоративным правилам, оставив себе обязательный минимум). Позже Intel настаивала, что сделка никак не связана с будущим раскрытием уязвимостей, но совпадение выглядело настолько невероятным, что американские сенаторы потребовали отдельной проверки.
Тогда ещё можно было надеяться, что обнаружена только одна, пусть и фундаментальная, ошибка, которую удастся закрыть несколькими обновлениями ядра и микрокода, но получилось иначе. Spectre показал, что ошибочно выполненные процессором инструкции способны оставлять следы, по которым можно восстановить чужие данные. Появился Retpoline, затруднивший атаки через косвенные переходы. Затем Retbleed добрался до возвратов и SRSO, Inception — до предсказания этих возвратов, а Safe RET начал намеренно заставлять процессор ошибаться безопасным для ядра способом.
TONTOU продолжает эту цепочку ещё на один шаг. Оказалось, что недостаточно привести предсказатель в безопасное состояние: между его очисткой и последующим использованием остаются буквально несколько инструкций. Если в этот момент приходит прерывание, обработчик способен снова изменить состояние предсказателя, и тщательно подготовленная защита перестаёт быть такой надёжной, как предполагалось.
За восемь лет стало понятно, почему у этой истории нет простого финального исправления. Производительность современных процессоров во многом держится именно на спекулятивном выполнении: процессор постоянно пытается угадать будущее и сделать работу заранее. Полностью запретить ему это означало бы отказаться от значительной части производительности. Поэтому вместо одной окончательной «заплатки от Spectre» появились микрокод, изменения компиляторов, десятки защит в ядре и всё более точное разделение границ, через которые действительно возможна атака.
И здесь Linux к 2026 году пришёл к довольно здравому результату. Администратору уже необязательно выбирать между «включить все защиты любой ценой» и mitigations=off. Можно описать реальную модель угроз конкретной машины: есть ли на ней чужие процессы, виртуальные машины, недоверенный код или соседние аппаратные потоки, которые требуется изолировать. А затем оставить именно те защиты, которые имеют смысл.
Возможно, это и есть наиболее реалистичный итог всей истории со Spectre. Процессор так и не стал устройством, в котором спекуляцию удалось один раз исправить и забыть. Зато мы постепенно научились гораздо точнее понимать, от кого именно её приходится защищать — и сколько готовы за эту защиту платить.

