Предотвращение доступа из режима супервизора
Предотвращение доступа из режима супервизора (англ. Supervisor Mode Access Prevention, SMAP) — это функция некоторых реализаций процессоров, таких как Intel: Broadwell (микроархитектура), которая позволяет программам, работающим в режиме супервизора, при необходимости задавать отображения памяти в пользовательское пространство таким образом, чтобы доступ к этим отображениям из режима супервизора вызывал исключение. Это усложняет злоумышленникам использование зловредных программ для «обмана» ядра с целью выполнения инструкций или работы с данными пользовательских программ[1]. По состоянию на 2026 год технология считается дополнительным уровнем защиты (best-effort), а не абсолютно гарантированным барьером[2].
История
Предотвращение доступа из режима супервизора было разработано как дополнение к механизму предотвращения выполнения из режима супервизора (SMEP). SMEP позволяет препятствовать непреднамеренному выполнению кода пользовательского пространства режимом супервизора, в то время как SMAP расширяет эту защиту на чтение и запись данных. SMEP блокирует атаки с передачей управления пользовательскому коду (например, ret2usr), а SMAP вынуждает злоумышленников искать способы размещения ROP-цепочек непосредственно в пространстве ядра[3].
Преимущества
Без механизма предотвращения доступа из режима супервизора код, выполняющийся в режиме супервизора, обычно обладает полным доступом на чтение и запись к отображениям памяти пользовательского пространства (см. возможность получения полного доступа). Это привело к созданию ряда эксплойтов и методик повышения привилегий, основанных на принуждении ядра к неосознанному доступу к пользовательской памяти[4].
Операционные системы могут блокировать такие эксплойты, используя SMAP для того, чтобы любые непреднамеренные обращения к пользовательской памяти вызывали ошибки страниц. Кроме того, SMAP может выявлять дефектный код ядра, не использующий корректные процедуры доступа к пользовательской памяти[1].
Однако использование SMAP в операционной системе может приводить к росту объёма кода ядра и снижению производительности при доступе к пользовательской памяти из режима супервизора. Для намеренного доступа режиму супервизора требуется временно отключать SMAP, что тоже замедляет выполнение[5].
При использовании технологий маскирования адресов (Intel LAM, AMD UAI) возможны атаки по сторонним каналам (например, через TLB), так как трансляция адреса происходит до того, как SMAP успевает заблокировать доступ[6][7].
Технические особенности
О поддержке SMAP процессорами сигнализирует расширенный лист возможностей CPUID.
SMAP активируется, когда пагинация памяти включена и установлен бит SMAP в регистре CR4. Для явного доступа к пользовательской памяти SMAP можно временно отключать, устанавливая флаг AC (Alignment Check (проверка выравнивания), бит 18)[8] в регистре EFLAGS. Для простой установки и сброса этого флага применяются инструкции stac («установить AC») и clac («сбросить AC»).
Когда бит SMAP в CR4 установлен, явные чтения и записи памяти по пользовательским страницам из кода с уровнем привилегий ниже 3 всегда приводят к исключению страницы, если флаг AC в EFLAGS не установлен. Неявные обращения (например, операции с таблицами дескрипторов) по пользовательским страницам вызовут исключение страницы при включённом SMAP, вне зависимости от состояния флага AC в EFLAGS.
Поддержка в операционных системах
Поддержка SMAP в ядре Linux была реализована H. Peter Anvin[1]. Эта функция была включена в основную ветку ядра Linux начиная с версии 3.7 и по умолчанию активируется для процессоров, поддерживающих SMAP[5].
FreeBSD поддерживает механизм предотвращения выполнения из режима супервизора (SMEP) с 2012 года[9], а поддержку SMAP — с 2018 года[10].
В OpenBSD поддержка SMAP и связанного механизма SMEP реализована с 2012 года[11]. Первая версия с включённой поддержкой — OpenBSD 5.3[12].
В NetBSD поддержка SMEP была реализована Максимом Вийяром (Maxime Villard) в декабре 2015 года[13]; поддержка SMAP также добавлена Максимом Вийяром в августе 2017 года[14]. Первая версия NetBSD с поддержкой и SMEP, и SMAP — NetBSD 8.0[15].
В Haiku поддержка механизмов SMAP и SMEP была добавлена Жеромом Дювалем (Jérôme Duval) в конце 2017 года и вошла в версию R1/beta1[16][17].
macOS поддерживает SMAP по крайней мере начиная с выхода версии macOS 10.13 в 2017 году.
В Windows полноценное внедрение SMAP в обычное ядро столкнулось с падением производительности и проблемами совместимости, из-за чего строгая изоляция применяется только для защищённого ядра. В Windows 11 флаг AC (Alignment Check) часто оказывается установлен при системных вызовах, что позволило в 2026 году продемонстрировать успешный обход защиты[18][19].