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

pti=off

На вычислительной нагрузке мало; больнее всего syscall/interrupt‑heavy нагрузке. В тестах Red Hat весь тогдашний комплект Meltdown+Spectre после оптимизации давал примерно 1–8%, CPU‑heavy задачи — около 1–2%.

2018

Spectre v1 CVE-2017-5753

точечные барьеры и проверки в уязвимых местах кода

nospectre_v1 в ядрах, где параметр поддерживается

Единого процента практически нет: защита вставляется в конкретные опасные места. Обычно заметно дешевле глобальных переключений адресных пространств и predictor flush.

2018 → сейчас

Spectre v2 / BHI CVE-2017-5715 и потомки

retpoline, eIBRS/IBRS, IBPB, STIBP, RSB filling, BHB clearing

spectre_v2=off, отдельно spectre_bhi=off

На старых Haswell/Broadwell весь комплект 2018 года после retpoline давал 1–8%, у частых kernel/userspace transitions — порядка 4–8%. Современные CPU обычно обходятся дешевле благодаря аппаратным механизмам.

2018

L1TF / Foreshadow

инверсия PTE, изменение таблиц страниц, очистка кэша первого уровня перед входом в виртуальную машину; для полной изоляции — отключение многопоточности

l1tf=off

Защита bare metal через PTE inversion у Red Hat дала 0%. Условный flush при VM‑entry обычно не измерялся, максимум около 3–4%. Flush на каждом VM‑entry доходил до 14%, а без свежего микрокода — до 27%.

2019

MDS / ZombieLoad / RIDL / Fallout

очистка внутренних буферов процессора; для полной защиты между потоками — отключение многопоточности

mds=off; для TAA иногда также нужен tsx_async_abort=off

Обычно несколько процентов, но особенно чувствительны syscall/context‑switch/I/O нагрузки. Полная защита может стоить существенно больше из‑за отключения SMT; поэтому честного единого процента здесь нет. Linux прямо разделяет mds=full и полный вариант mds=full,nosmt.

2022

Retbleed CVE-2022-29900/29901

защитные подмены возвратов, контроль глубины вызовов и очистка предсказателя

retbleed=off

Одна из самых дорогих защит: авторы Retbleed измеряли падение производительности на 14–39% на затронутых AMD Zen 1/1+/2 и Intel 6–8 поколений. Позднее часть этих потерь удалось сократить оптимизациями.

2023

Zenbleed CVE-2023-20593, AMD Zen 2

обновлённый микрокод; при его отсутствии Linux включает программный обход

штатного удобного zenbleed=off нет

В тестах программного workaround отдельные encoder/render workloads теряли до ~15%, большая часть обычных приложений и игр — почти ничего. Микрокод предпочтительнее программного workaround.

2023

Downfall / GDS CVE-2022-40982

микрокод запрещает опасную спекуляцию при векторном чтении памяти

gather_data_sampling=off

Intel говорит о минимальном влиянии для большинства программ, но gather‑heavy код может терять до 50%. Это один из лучших примеров, почему среднее значение здесь бессмысленно.

2023

Inception / SRSO CVE-2023-20569

защищённый механизм возврата; альтернативно — очистка предсказателя

spec_rstack_overflow=off

Огромный разброс. Для тяжёлых вариантов защиты опубликованы случаи до −54% MariaDB, около +29% времени компиляции ядра, тогда как Blender и браузер теряли около процента. IBPB часто оказывался самым дорогим; штатный Safe RET обычно дешевле.

2024

RFDS CVE-2023-28746

микрокод и очистка внутренних буферов при возврате в пользовательский режим и перед входом в виртуальную машину

reg_file_data_sampling=off

В тестах Raptor Lake большинство нагрузок потеряли немного; nginx — около 4%, context switch вырос со 126 до 139 тактов, то есть примерно на 10% именно для этой микрооперации.

2025

ITS — Indirect Target Selection CVE-2024-28956

новый микрокод плюс aligned branch/return thunks

indirect_target_selection=off; есть интересный vmexit

Хороших универсальных публичных измерений пока недостаточно. Цена зависит от того, сколько реально приходится заменять indirect branch/RET; Linux умеет применять защиту только для VM‑сценария через vmexit.

2025

TSA — Transient Scheduler Attacks, AMD

очистка состояния на границах безопасности; можно отдельно защищать user/kernel и VM

tsa=off, либо tsa=user, tsa=vm

Репрезентативного набора сравнительных бенчмарков пока нет. Это как раз случай, где модель угроз полезнее попытки найти магическую среднюю цифру.

2025

VMSCAPE

условный IBPB после выхода из потенциально враждебной VM перед возвратом в host userspace

vmscape=off

Исследователи сообщали о небольшом/практически незаметном среднем overhead благодаря условному IBPB; цена растёт с частотой VMEXIT и переходов в userspace. В Linux защита специально не делает IBPB там, где он не нужен.

2026

TONTOU / Safe RET Interrupt

обновлённый Linux + существующая SRSO/Safe RET защита

фактически отключается вместе с SRSO: spec_rstack_overflow=off

Пока неизвестно. Отдельных нормальных бенчмарков свежего исправления ещё нет.

Список, конечно, неполный. Здесь сознательно нет десятков более узких вариантов 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%, всё сложить и получить стоимость безопасности.

Так это не работает.

Правильный эксперимент для конкретного сервера гораздо проще:

  1. Оставить штатный mitigations=auto.

  2. Прогнать настоящую нагрузку.

  3. Отключить только заведомо ненужные attack vectors.

  4. Повторить тест.

  5. И только ради контрольной точки попробовать 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. Процессор так и не стал устройством, в котором спекуляцию удалось один раз исправить и забыть. Зато мы постепенно научились гораздо точнее понимать, от кого именно её приходится защищать — и сколько готовы за эту защиту платить.

Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.
Как Вы защищаетесь от подобных атак
0%Слежу, обновляют микрокод, выполняю рекомендации0
50%Верю, что само себя настроит и защитит1
0%Мне неважно0
0%Против такой защиты: шанс залета всегда есть, но я верю, что он невелик, а потеря скорости будет0
50%Специально отключаю: мне нужно выжимать из железа максимум1
Проголосовали 2 пользователя. Воздержавшихся нет.