Ленивое восстановление состояния FPU
Ленивое восстановление состояния FPU (англ. Lazy FPU state leak, также ленивое сохранение/восстановление состояния сопроцессора с плавающей запятой, англ. Lazy FP State Restore, LazyFP[1][2], идентификатор CVE-2018-3665[3]) — это уязвимость безопасности «умеренного» уровня серьёзности[4], затрагивающая процессоры Intel Core (начиная с микроархитектуры Sandy Bridge) и Intel Xeon[5][6][7]. Уязвимость обусловлена сочетанием дефектов в реализации спекулятивного исполнения процессоров и особенностями того, как некоторые операционные системы выполняют переключение контекста для FPU (floating point unit)[1]. Эксплуатация этой уязвимости позволяет локальному процессу получить содержимое регистров FPU, принадлежащих другому процессу. Эта уязвимость связана с обнаруженными в январе 2018 года проблемами Spectre и Meltdown. Процессоры AMD и Intel Atom не подвержены данной уязвимости[5][6].
О наличии уязвимости компания Intel объявила 13 июня 2018 года; она была обнаружена сотрудниками компаний Amazon, Cyberus Technology и SYSGO.
Помимо вычислений с плавающей запятой, регистры FPU используются для других целей, например, для хранения криптографических данных при работе с набор инструкций AES (реализован во многих процессорах Intel)[2]. Это означает, что уязвимость может привести к компрометации криптографических ключей[2].
Механизм
Регистры модуля с плавающей запятой и SIMD-регистры (широкие регистры команд параллельной обработки данных) обладают значительным размером и используются не всеми задачами (или потоками) в системе. Для ускорения переключения контекста большинство современных микропроцессоров поддерживают ленивое восстановление состояния FPU. Вместо полного сохранения состояния при переключении контекста операционная система может отметить FPU как «не доступный» в расчёте на то, что новая задача не будет использовать сопроцессор. Если предположение оказалось верным, время экономится; иначе, первая инструкция FPU или SIMD вызовет исключение (trap) в операционную систему, которая сохранит состояние для предыдущей задачи и загрузит множество регистров для текущей.
В процессорах с внеочередным исполнением команд ситуация осложняется: состояние «FPU не доступен» обнаруживается не мгновенно. Более того, это технически невозможно без потерь производительности, так как одновременно могут выполняться несколько потенциально ошибочных инструкций, а процессор должен отработать первую возникшую ошибку для симуляции последовательного исполнения. Какая именно ошибка — это становится известно только на этапе «ретайра» (завершения) инструкции. Процессор производит спекулятивное выполнение инструкции, используя содержимое регистров предыдущей задачи, а затем обнаруживает, что FPU был недоступен. Хотя архитектурное состояние возвращается к началу ошибочной инструкции, с помощью FPU можно провести загрузку из памяти (memory load), тем самым занеся данные в кэш процессора. Эксплуатация строится так же, как у семейств уязвимостей Spectre: содержимое кэша не является архитектурным состоянием (кэш влияет только на скорость, а не на корректность), так что данные в нём не сбрасываются. Адрес, использовавший часть регистров FPU предыдущей задачи, позже определяется по времени доступа к различным адресам памяти.
Эту уязвимость можно использовать и без возникновения исключений со стороны операционной системы. Разместив обращение к FPU внутри теневого исполнения ошибочного перехода (например, с помощью retpoline), процессор выполнит вредоносный код спекулятивно, затем «откатится» к неверно предсказанной ветви и не вызовет ловушку/переключение контекста ОС. Это позволяет атакующему быстро повторять операцию и прочитывать содержимое всех регистров FPU и SIMD.
Уязвимость позволяет получить полный снимок состояния регистров FPU, включая расширенные наборы, такие как AVX-512. Увеличенный размер регистров AVX-512 делает утечку более значимой, позволяя извлечь до 2 КБ данных[2][1].
Связь со Spectre и Meltdown
Уязвимость LazyFP относится к классу атак по сторонним каналам и, подобно Spectre и Meltdown, использует механизм спекулятивного выполнения команд[2].[8] Ключевое отличие LazyFP заключается в объекте атаки. Если Meltdown нацелена на чтение данных из защищённой основной памяти ядра, а Spectre позволяет получить доступ к памяти других процессов, то LazyFP направлена на извлечение данных из регистров блока вычислений с плавающей запятой (FPU)[9].[10] Кроме того, различаются способы устранения уязвимостей. В отличие от Meltdown и Spectre, для защиты от LazyFP не требуются обновления микрокода процессора. Проблема решается исключительно на уровне операционной системы или гипервизора путём отключения «ленивого» режима и перехода на «энергичное» (eager) восстановление состояния FPU при переключении контекста[11].[12]
Меры противодействия
Эту уязвимость можно устранить на уровне операционной системы или гипервизора, если по каждому переключению процесса выполнять немедленное («энергичное», eager) восстановление состояния FPU[13][14]. В этом случае обновления микропрограмм процессора не требуются. В новых поколениях процессоров Intel (12—14-е поколения) аппаратных изменений, специфичных для этой уязвимости, не вводилось, защита полностью обеспечивается на уровне ОС[10][14]. Влияние на производительность от перехода на eager-режим на современных системах оценивается как незначительное[14][15]. Некоторые операционные системы изначально не применяли ленивое восстановление FPU по умолчанию, что защищало их на уязвимых аппаратных платформах, даже если сама аппаратная проблема присутствовала[13]. Для ОС Linux с ядром версии 3.7 и новее можно явно активировать «жадное» (eager) восстановление регистров FPU с помощью параметра ядра eagerfpu=on[2]. Многие производители системного ПО и дистрибутивы, включая Linux-дистрибутивы[16], OpenBSD[17], FreeBSD (выпущен патч в июне 2018 года)[18], Windows (исправления для Windows 10 вышли в июле 2018 года, а Windows 11 защищена по умолчанию)[10] и Xen[7], выпустили исправления, устраняющие уязвимость.
Примечания
Литература
- Julian Stecklina, Thomas Prescher. LazyFP: Leaking FPU Register State using Microarchitectural Side-Channels (англ.). arXiv (19 июня 2018). Дата обращения: 18 июня 2018.
- Prescher, Thomas; Stecklina, Julian; Galowicz, Jacek Intel LazyFP vulnerability: Exploiting lazy FPU state switching (англ.). Cyberus Technology. Дата обращения: 18 июня 2018. Архивировано 9 ноября 2020 года.
- Lazy FP state restore (англ.). Intel (13 июня 2018). Дата обращения: 18 июня 2018.