Подробный гайд по устранению ошибки parsec_file_mprotect в Astra Linux SE

Подробный гайд по устранению ошибки parsec_file_mprotect в Astra Linux SE. Разбор причин блокировки mprotect, настройки ядра parsec.execstack и решений.

2026.10.02                  


Подробный гайд по устранению ошибки parsec_file_mprotect в Astra Linux SEПодробный гайд по устранению ошибки parsec_file_mprotect в Astra Linux SE Ошибке связана с Astra Linux Special Edition и модулем безопасности PARSEC (не путать с приложением Parsec для удалённого доступа).


1. Что это за ошибка

Сообщение в журнале аудита выглядит так:

type=AVC msg=audit(1734413451.012:20444): parsec=denied fn=parsec_file_mprotect requested=x pid=9108 comm="a.out"

Эта ошибка означает, что модуль безопасности PARSEC, встроенный в ядро Astra Linux Special Edition, заблокировал попытку программы разрешить исполнение кода в области памяти, выделенной для стека. Другими словами, программа попыталась выполнить системный вызов mprotect() с флагом PROT_EXEC для стековой области, и получила отказ.




Часто сопровождается пользовательской ошибкой:

cannot enable executable stack as shared object requires: Permission denied

2. Почему это происходит

2.1. Механизм защиты

Начиная с оперативного обновления 1.7.6 (БЮЛЛЕТЕНЬ № 2024-0830SE17), в Astra Linux Special Edition был включён механизм защиты от исполнения областей памяти в стеке программ.

Этот механизм:

  • Делает невозможным выполнение кода из разделяемых библиотек на страницах памяти, помеченных «только для данных», включая страницы стека.
  • Не предотвращает размещение эксплойта в памяти, но не позволяет установить разрешение на исполнение кода эксплойта.
  • Управляется параметром ядра parsec.execstack, доступным начиная с обновления 1.7.6.

2.2. Что делает PARSEC

PARSEC — это модуль ядра, реализующий мандатное управление доступом (МРД) на уровне ядра. Он контролирует системные вызовы, включая mprotect(), и при обнаружении попытки сделать стек исполняемым — блокирует операцию и записывает событие в журнал аудита.


2.3. Какие программы подвержены

Ошибка возникает у ПО, которое:

  • Скомпилировано с флагом компоновщика -z execstack.
  • Использует JIT-компиляцию или динамическую генерацию кода.
  • Содержит устаревшие библиотеки, требующие исполняемый стек.
  • Примеры: некоторые версии Wine, старые игры, проприетарные драйверы, СКЗИ (например, «Континент-АП»), Guardant-защита.

3. Диагностика

3.1. Проверка журнала аудита

Убедитесь, что ошибка действительно связана с mprotect:

sudo /usr/sbin/ausearch -m AVC | grep mprotect

Ожидаемый вывод:

type=AVC msg=audit(...): parsec=denied fn=parsec_file_mprotect requested=x pid=XXXX comm="имя_программы"

3.2. Проверка текущего значения параметра

Посмотрите текущее значение параметра загруженного ядра:

cat /sys/module/parsec/parameters/execstack
  • 0 — защита включена (по умолчанию).
  • 1 — защита выключена.

3.3. Трассировка системных вызовов

Для выявления конкретного вызова mprotect(), вызывающего ошибку, используйте strace:

strace -f -e trace=mprotect ./ваша_программа 2>&1 | grep -i denied

3.4. Проверка ELF-заголовков

Проверьте, требует ли бинарный файл исполняемый стек:

readelf -l /путь/к/бинарнику | grep GNU_STACK

Если вывод содержит RWE (Read, Write, Execute) — программа требует исполняемый стек.

# Проверка разделяемых библиотек
readelf -l /путь/к/библиотеке.so | grep GNU_STACK

4. Решения

Решение 1: Отключение контроля исполнения стека (временное)

ВНИМАНИЕ:

Данное изменение снижает защищённость операционной системы. Применяйте только при невозможности других решений и осознанно.

Шаг 1. Откройте конфигурацию GRUB:

sudo nano /etc/default/grub

Шаг 2. Найдите строку GRUB_CMDLINE_LINUX_DEFAULT и добавьте параметр parsec.execstack=1:

GRUB_CMDLINE_LINUX_DEFAULT="parsec.mac=1 quiet net.ifnames=0 parsec.execstack=1"

Примечание:

parsec.mac=0 полностью отключает мандатное управление доступом. Если вам нужна только разблокировка стека — оставьте parsec.mac=1.


Шаг 3. Обновите конфигурацию загрузчика:

sudo update-grub

Шаг 4. Перезагрузите компьютер:

sudo reboot

Шаг 5. После перезагрузки проверьте:

cat /sys/module/parsec/parameters/execstack
# Должно быть: 1

Решение 2: Перекомпиляция ПО без execstack (рекомендуемое)

Если вы разработчик или можете пересобрать ПО, уберите флаг -z execstack из параметров компоновщика:



# Вместо:
gcc -z execstack -o program program.c

# Используйте:
gcc -z noexecstack -o program program.c

Или просто не передавайте -z execstack — по умолчанию в современных инструментах стек неисполняемый.

Для проверки и исправления уже собранных ELF-файлов используйте execstack:

# Проверить
execstack -q /путь/к/бинарнику

# Очистить флаг исполняемого стека
sudo execstack -c /путь/к/бинарнику

Решение 3: Использование paxctl / patchelf (для отдельных бинарников)

Если нельзя пересобрать, но можно модифицировать бинарник:

# Установить утилиту
sudo apt install execstack

# Снять флаг исполняемого стека
sudo execstack -c /путь/к/проблемной_библиотеке.so

Решение 4: Обращение к разработчику ПО

Чек-лист действий от Astra Linux:

  1. Исключить использование ПО, генерирующего ошибку, как потенциально небезопасного.
  2. Обратиться к разработчикам для доработки ПО с целью устранения небезопасных вызовов mprotect().
  3. Только при невозможности вышеуказанного — отключить контроль (Решение 1).

5. Рекомендации для разработчиков

При разработке ПО для Astra Linux Special Edition:

Что делать Что НЕ делать
Компилировать без -z execstack Не использовать -z execstack при сборке
Использовать mmap() с PROT_READ\|PROT_WRITE для данных Не вызывать mprotect() с PROT_EXEC для стека
Для JIT — выделять память через mmap(PROT_READ\|PROT_WRITE\|PROT_EXEC) отдельно Не размещать исполняемый код в стеке
Тестировать на Astra Linux с parsec.execstack=0 Не игнорировать предупреждения линкера

Для JIT-компиляторов правильный паттерн:

// Выделяем отдельную область памяти для кода
void *code = mmap(NULL, size, PROT_READ | PROT_WRITE,
                  MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);

// Записываем код
memcpy(code, generated_code, size);

// Делаем исполняемым (это НЕ стек — PARSEC не блокирует)
mprotect(code, size, PROT_READ | PROT_EXEC);

6. Возврат к безопасной конфигурации

После обновления или замены проблемного ПО обязательно верните защиту:

Шаг 1. Откройте /etc/default/grub:

sudo nano /etc/default/grub

Шаг 2. Уберите parsec.execstack=1 или замените на 0:

GRUB_CMDLINE_LINUX_DEFAULT="parsec.mac=1 quiet net.ifnames=0 parsec.execstack=0"

Шаг 3. Обновите и перезагрузите:

sudo update-grub
sudo reboot

Шаг 4. Проверьте:

cat /sys/module/parsec/parameters/execstack
# Должно быть: 0

7. Сводная таблица параметров PARSEC

Параметр Назначение Значения По умолчанию
parsec.execstack Защита от исполнения стека 0 (вкл.) / 1 (выкл.) 0
parsec.mac Мандатное управление доступом 0 / 1 1
parsec.max_ilev Максимальный уровень целостности 0–4294967295 63
parsec.enable_exec_on_fuse Запуск с FUSE-файловых систем 0 / 1 0

Актуальные значения всех параметров доступны в /sys/module/parsec/parameters/


8. Связанные ошибки и дополнительные материалы

  • Ошибка Permission denied при работе с СКЗИ «Континент-АП» на Astra Linux 1.7.6+ — требует parsec.execstack=1
  • Ошибка Permission denied для libprotectstorage64.so (Guardant) — аналогичная причина
  • Ошибка mprotect failed in ExecutableAllocator::makeExecutable в Qt/Chromium-приложениях на Red Hat 9 / Astra Linux
  • Полное описание параметров модуля PARSEC — wiki.astralinux.ru, pageId=27361844
  • Описание механизма защиты — wiki.astralinux.ru, pageId=338008842

Информация предоставлена в ознакомительных целях. Применение описанных настроек в системах, должно осуществляться только после согласования с ответственными за информационную безопасность и в соответствии с требованиями ФСТЭК, ФСБ и иных уполномоченных органов.


Статью подготовил: Аверко Денис Сергеевич @Nymexis г. Омск (специалист по ЗИ)

Комментарии

Загрузка...
Если комментарии не загружаются, можете попробовать отключить блокировщик рекламы для этого сайта