Введение
Функция безопасности операционной системы, связанная с памятью.
W^X ("write xor execute", произносится W xor X) — это функция безопасности в операционных системах и виртуальных машинах. Это политика защиты памяти, согласно которой каждая страница в адресном пространстве процесса или ядра может быть либо записываемой, либо исполняемой, но не одновременно. Без такой защиты программа может записывать (как данные "W") инструкции ЦП в область памяти, предназначенную для данных, а затем выполнять (как исполняемый код "X"; или читать и выполнять "RX") эти инструкции. Это может быть опасно, если запись в память выполняет вредоносная программа. W^X — это термин, используемый в Unix-подобных системах для обозначения строгого применения общей концепции защиты исполняемого пространства, контролируемой посредством системного вызова. W^X относительно прост в реализации на архитектурах процессоров, поддерживающих детальные разрешения на уровне страниц, таких как SPARC и SPARC64 от Sun, x86 64 от AMD, PA RISC от Hewlett Packard, Alpha от HP (первоначально Digital Equipment Corporation) и ARM. Термин W^X также применяется к разрешениям на запись/исполнение в файловой системе для снижения уязвимостей, связанных с записью в файлы (аналогично уязвимостям в памяти), и для предотвращения сохранения злоумышленниками доступа к системе. Ограничения файловых разрешений также могут устранить недостатки в реализации W^X, вызванные файлами, отображенными в память. Полный запрет на использование произвольного машинного кода также может снизить уязвимости ядра и процессора, которые не проявляются при использовании существующего кода на компьютере. Менее радикальный подход заключается в блокировке файла на время его отображения в исполняемой памяти, что достаточно для предотвращения обхода защиты после проверки.
Совместимость
Некоторые ранние процессоры Intel 64 не имели бита NX, необходимого для W^X, но он появился в более поздних чипах. На более ограниченных процессорах, таких как Intel i386, W^X требует использования предела сегмента кода CS в качестве "границы", точки в адресном пространстве, выше которой исполнение запрещено и располагаются данные, а ниже которой оно разрешено и размещаются исполняемые страницы. Эта схема использовалась в Exec Shield. Как правило, требуются изменения в компоновщике для разделения данных и кода (например, трамплинов, необходимых для функций времени выполнения компоновщика и библиотек). Переключатель, разрешающий смешивание, обычно называется execstack в Unix-подобных системах.
W^X также может создавать небольшую проблему для компиляции "на лету", когда интерпретатор генерирует машинный код и затем запускает его. Простое решение, используемое большинством, включая Firefox, заключается в том, чтобы сделать страницу исполняемой после того, как интерпретатор завершит запись машинного кода, используя в Windows или в Unix-подобных операционных системах. Другое решение заключается в отображении одного и того же региона памяти на две страницы: одну с правами RW (чтение-запись), а другую с правами RX (чтение-исполнение). В конце 2014 и начале 2015 года W^X был добавлен в ядро OpenBSD для архитектуры AMD64. В начале 2016 года W^X был полностью реализован в ядре AMD64 NetBSD и частично в ядре i386. Компьютеры macOS, работающие на процессорах Apple Silicon, обеспечивают соблюдение W^X для всех программ. Компьютеры Mac на базе Intel обеспечивают соблюдение политики только для программ, использующих режим Hardened Runtime операционной системы. Начиная с Firefox 46 в 2016 году, виртуальная машина Firefox для JavaScript также реализует политику W^X. Начиная с .NET 6.0 в 2021 году, .NET теперь использует W^X.