Предотвращение доступа из режима супервизора

Предотвращение доступа из режима супервизора (англ. Supervisor Mode Access Prevention, SMAP) — это функция некоторых реализаций процессоров, таких как Intel: Broadwell (микроархитектура), которая позволяет программам, работающим в режиме супервизора, при необходимости задавать отображения памяти в пользовательское пространство таким образом, чтобы доступ к этим отображениям из режима супервизора вызывал исключение. Это усложняет злоумышленникам использование зловредных программ для «обмана» ядра с целью выполнения инструкций или работы с данными пользовательских программ[1][2].

История

Предотвращение доступа из режима супервизора было разработано как дополнение к механизму предотвращения выполнения из режима супервизора (SMEP). SMEP позволяет препятствовать непреднамеренному выполнению кода пользовательского пространства режимом супервизора, в то время как SMAP расширяет эту защиту на чтение и запись данных[2].

Преимущества

Без механизма предотвращения доступа из режима супервизора код, выполняющийся в режиме супервизора, обычно обладает полным доступом на чтение и запись к отображениям памяти пользовательского пространства (см. возможность получения полного доступа). Это привело к созданию ряда эксплойтов и методик повышения привилегий, основанных на принуждении ядра к неосознанному доступу к пользовательской памяти[3].

Операционные системы могут блокировать такие эксплойты, используя SMAP для того, чтобы любые непреднамеренные обращения к пользовательской памяти вызывали ошибки страниц. Кроме того, SMAP может выявлять дефектный код ядра, не использующий корректные процедуры доступа к пользовательской памяти[1].

Однако использование SMAP в операционной системе может приводить к росту объёма кода ядра и снижению производительности при доступе к пользовательской памяти из режима супервизора. Для намеренного доступа режиму супервизора требуется временно отключать SMAP, что тоже замедляет выполнение[4].

Технические особенности

О поддержке SMAP процессорами сигнализирует расширенный лист возможностей CPUID.

SMAP активируется, когда пагинация памяти включена и установлен бит SMAP в регистре CR4. Для явного доступа к пользовательской памяти SMAP можно временно отключать, устанавливая флаг AC (Auxiliary Carry — контроль выравнивания) в регистре EFLAGS. Для простой установки и сброса этого флага применяются инструкции stac («установить AC») и clac («сбросить AC»)[5].

Когда бит SMAP в CR4 установлен, явные чтения и записи памяти по пользовательским страницам из кода с уровнем привилегий ниже 3 всегда приводят к исключению страницы, если флаг AC в EFLAGS не установлен. Неявные обращения (например, операции с таблицами дескрипторов) по пользовательским страницам вызовут исключение страницы при включённом SMAP, вне зависимости от состояния флага AC в EFLAGS[5].

Поддержка в операционных системах

Поддержка SMAP в ядре Linux была реализована H. Peter Anvin[1]. Эта функция была включена в основную ветку ядра Linux начиная с версии 3.7 и по умолчанию активируется для процессоров, поддерживающих SMAP[4].

FreeBSD поддерживает механизм предотвращения выполнения из режима супервизора (SMEP) с 2012 года[6], а поддержку SMAP — с 2018 года[7].

В OpenBSD поддержка SMAP и связанного механизма SMEP реализована с 2012 года[8]. Первая версия с включённой поддержкой — OpenBSD 5.3[9].

В NetBSD поддержка SMEP была реализована Максимом Вийяром (Maxime Villard) в декабре 2015 года[10]; поддержка SMAP также добавлена Максимом Вийяром в августе 2017 года[11]. Первая версия NetBSD с поддержкой и SMEP, и SMAP — NetBSD 8.0[12].

В Haiku поддержка механизма предотвращения выполнения из режима супервизора (SMEP) реализована Жеромом Дювалем (Jérôme Duval) в январе 2018 года[13].

macOS поддерживает SMAP по крайней мере начиная с выхода версии macOS 10.13 в 2017 году[14].

Примечания

  1. 1 2 3 Jonathan Corbet. Supervisor mode access prevention (англ.). LWN.net. LWN.net (26 сентября 2012). Дата обращения: 9 июля 2024. Архивировано 30 октября 2017 года.
  2. 1 2 David Mulnix. Intel Xeon Processor D Product Family Technical Overview: Supervisor Mode Access Protection (SMAP) 4 (англ.). Intel. Intel (22 мая 2015). Дата обращения: 9 июля 2024. Архивировано 14 июля 2015 года.
  3. Jonathan Corbet. Fun with NULL pointers, part 1 (англ.). LWN.net. LWN.net (20 июля 2009). Дата обращения: 9 июля 2024. Архивировано 11 июня 2012 года.
  4. 1 2 Michael Larabel. Intel SMAP Comes To Try To Better Secure Linux (англ.). Phoronix. Phoronix (2 октября 2012). Дата обращения: 9 июля 2024. Архивировано 3 октября 2012 года.
  5. 1 2 Intel 64 and IA-32 Architectures Software Developer's Manual, Volume 3A: System Programming Guide, Part 1 (англ.). Intel. Intel (июль 2017). Дата обращения: 9 июля 2024. Архивировано 12 июля 2017 года.
  6. Константин Белоусов. Revision 242433 (англ.) (1 ноября 2012). Дата обращения: 9 июля 2024. Архивировано 21 января 2018 года.
  7. Константин Белоусов. Revision 336876 (англ.) (29 июля 2018). Дата обращения: 9 июля 2024. Архивировано 30 июля 2018 года.
  8. Stuart Henderson. Re: Does OpenBSD have SMEP and SMAP implementation? or MPX? (англ.). marc.info (26 марта 2017). Дата обращения: 9 июля 2024. Архивировано 3 августа 2020 года.
  9. OpenBSD 5.3 (англ.). OpenBSD. OpenBSD (1 мая 2013). Дата обращения: 9 июля 2024. Архивировано 17 мая 2014 года.
  10. Significant changes from NetBSD 7.0 to 8.0 (англ.). NetBSD. NetBSD (12 октября 2017). Дата обращения: 9 июля 2024. Архивировано 13 октября 2017 года.
  11. Maxime Villard. amd64: smap support (англ.) (23 августа 2017). Дата обращения: 9 июля 2024. Архивировано 24 августа 2017 года.
  12. Announcing NetBSD 8.0 (July 17, 2018) (англ.). NetBSD. NetBSD (17 июля 2018). Дата обращения: 9 июля 2024. Архивировано 31 июля 2018 года.
  13. kernel: support for Intel SMAP and SMEP on x86_64. (англ.). Haiku. Haiku (30 января 2018). Дата обращения: 9 июля 2024. Архивировано 7 февраля 2019 года.
  14. /osfmk/x86_64/idt64.s.auto.html (англ.). Apple. Apple (25 сентября 2017). Дата обращения: 9 июля 2024. Архивировано 6 сентября 2020 года.