PRCTL(2)

ИМЯ
prctl - операции над процессом

ОБЗОР
#include <sys/prctl.h>

int prctl(int option, unsigned long arg2, unsigned long arg3,
          unsigned long arg4, unsigned long arg5);

ОПИСАНИЕ
Первый аргумент prctl() задаёт тип операции (типы определены в <linux/prctl.h>, значения остальных аргументов зависят от указываемого типа. Первый аргумент может принимать следующие значения:

PR_CAP_AMBIENT (начиная с Linux 4.3)
    Читает или изменяет наружный набор мандатов вызывающей нити согласно значению arg2, которое должно быть одним из следующих:

    PR_CAP_AMBIENT_RAISE
        Мандат, указанный в arg3, добавляется в наружный набор. Указанный мандат уже должен присутствовать в разрешающем и наследуемом наборе. Эта операция неприменима, если установлен бит безопасности SECBIT_NO_CAP_AMBIENT_RAISE.

    PR_CAP_AMBIENT_LOWER
        Мандат, указанный в arg3, удаляется из наружного набора.

    PR_CAP_AMBIENT_IS_SET
        Вызов prctl() возвращает 1, если мандат в arg3 присутствует в наружном наборе и 0, если нет.

    PR_CAP_AMBIENT_CLEAR_ALL
        Все мандаты будут удалены из наружного набора. Для этой операции требуется указать в arg3 значение 0.

    В всех перечисленных выше операциях значения arg4 и arg5 должны быть равны 0.

PR_CAPBSET_READ (начиная с Linux 2.6.25)
    Возвращает 1 (как результат функции), если мандат, указанный в arg2, есть в списке мандатов вызывающей нити (capability bounding set), или 0, если нет. Константы мандатов определены в <linux/capability.h>. Значениями списка мандатов определяется, может ли процесс получить мандат через установку набора файловых прав при последующем вызове execve(2).

    Если мандат, указанный в arg2, некорректен, то вызов завершится с ошибкой EINVAL.

PR_CAPBSET_DROP (начиная с Linux 2.6.25)
    Если вызывающая нить имеет мандат CAP_SETPCAP в своём пользовательском пространстве имён, то мандат, указанный в arg2, удаляется из списка мандатов вызывающей нити. Любой потомок вызывающей нити унаследует новый сокращённый список мандатов.

    Вызов завершается с ошибками: EPERM, если вызывающая нить не имеет мандата CAP_SETPCAP; EINVAL, если в arg2 указан недопустимый мандат; EINVAL, если файловые мандаты не включены в ядре, в этом случае списки мандатов не поддерживаются.

PR_SET_CHILD_SUBREAPER (начиная с Linux 3.4)
    Если значение arg2 не равно 0, то в вызвавшем процессе устанавливается атрибут «сборщика потомков» (child subreaper); если значение arg2 равно 0, то атрибут удаляется.

    Сборщик потомков выполняет функцию init(1) для своих потомков. При завершении осиротевшего процесса (т. е. прямой предок уже завершил выполнение), его родителем станет ближайший действующий сборщик-предок. После этого вызов getppid() в осиротевшем процессе будет возвращать PID процесса-сборщика, и когда осиротевший процесс завершит работу, сборщик получит сигнал SIGCHLD и сможет запустить wait(2) для получения состояния завершения потомка.

    Установка данного бита не наследуется потомками, создаваемыми fork(2) и clone(2). Данное значение сохраняется после execve(2).

    Назначение процесса-сборщика полезно в инфраструктуре управления сеансами, где иерархическая группа процессов управляется процессом-сборщиком, которому нужно сообщать, когда один из процессов — например, служба, выполнившая двойное создание (fork) — завершается (возможно для того, чтобы её можно было перезапустить). Некоторые инфраструктуры init(1) (например, systemd(1)) используют a процесс-сборщик для этих целей.

PR_GET_CHILD_SUBREAPER (начиная с Linux 3.4)
    Возвращает значение атрибута «сборщика потомков» вызывающего в расположение, указанное (int *) arg2.

PR_SET_DUMPABLE (начиная с Linux 2.3.20)
    Установить состояние флага «дампа», определяющего создание файла core вызывающего процесса после доставки сигнала, чьё поведение по умолчанию вызывает создание файла core.

    В ядрах по 2.6.12 включительно, значение arg2 должно быть равно 0 (SUID_DUMP_DISABLE, от процесса не остаётся дампа) или 1 (SUID_DUMP_USER, после процесса остаётся дамп). Между ядрами 2.6.13 и 2.6.17, также было разрешено значение 2, означающее что от любого исполняемого файла, обычно дампа не остаётся, но суперпользователь может это сделать; для улучшения безопасности эта возможность была удалена (смотрите также описание /proc/sys/fs/suid_dumpable в proc(5)).

    Обычно, значение этого флага равно 1. Однако, оно сбрасывается в текущее значение, содержащееся в файле /proc/sys/fs/suid_dumpable (которое по умолчанию равно 0), в следующих случаях:

    *   Изменён эффективный идентификатор пользователя или группы процесса.

    *   Изменён процессный идентификатор пользователя или группы файловой системы (смотрите credentials(7)).

    *   Процесс выполняет (execve(2)) программу с установленным битом set-user-ID или set-group-ID, что приводит к изменению идентификатора эффективного пользователя или эффективной группы.

    *   Процесс выполняет (execve(2)) программу, которая имеет файловые мандаты (смотрите capabilities(7)), но только если полученные разрешенные мандаты превосходят уже разрешенные для процесса.

    Процессы, для которых невозможен дамп, нельзя присоединить через операцию ptrace2() PTRACE_ATTACH; подробности смотрите в ptrace(2).

    Если для процесса невозможен дамп, то на владение файлами в каталоге процесса /proc/[pid] действуют правила, описанные в proc(5).

PR_GET_DUMPABLE (начиная с Linux 2.3.20)
    Возвращает (как результат функции) текущее состояние флага дампа вызывающего процесса.

PR_SET_ENDIAN (начиная с Linux 2.6.18, только для PowerPC)
    Устанавливает порядок байт вызывающего процесса равным значению arg2, которое может быть одним из: PR_ENDIAN_BIG, PR_ENDIAN_LITTLE или PR_ENDIAN_PPC_LITTLE (для PowerPC псевдо обратный порядок (pseudo little endian)).

PR_GET_ENDIAN (начиная с Linux 2.6.18, только для PowerPC)
    Записывает значение порядка байт вызывающего процесса по адресу, указанному в (int *) arg2.

PR_SET_FP_MODE (начиная с Linux 4.0, только на MIPS)
    На архитектуре MIPS код пользовательского пространства можно собирать используя ABI, который позволяет компоновку с кодом, имеющем более ограничительные требования для плавающей запятой (FP). Например, код пользовательского пространства может собираться для цели O32 FPXX ABI и компоноваться с кодом, собранным с одним из более ограничительных FP32 или FP64 ABI. При этом требование всего процесса устанавливается в более ограничительный режим плавающей запятой.

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

    В аргументе (unsigned int) arg2 указывается битовая маска, описывающая используемый режим плавающей запятой:

    PR_FP_MODE_FR
        Если это бит сброшен (так называемый режим FR=0 или FR0), то ширина 32 регистров плавающей запятой равна 32, а 64-битные регистры представляются в виде пары регистров (с чётными и нечётными номерами; регистры с чётными номерами содержат 32 младших бита, а с нечётными номерами 32 старших бита).

        Если этот бит установлен (есть поддержка в оборудовании), то ширина 32 регистров плавающей запятой равна 64 (так называемый режим FR=1 или FR1). Заметим, что современные реализации MIPS (MIPS R6 и новее) поддерживают только режим FR=1.

        Приложения, использующие O32 FP32 ABI, могут работать только когда этот бит сброшен (FR=0; или они могут использоваться с включённым FRE, смотрите ниже). Приложения, использующие O32 FP64 ABI (и O32 FP64A ABI, существующий для предоставления возможности работы с существующим кодом FP32; смотрите ниже), могут работать только когда этот бит установлен (FR=1). Приложения, использующие O32 FPXX ABI, могут работать и с FR=0 и с FR=1.

    PR_FP_MODE_FRE
        Включает эмуляцию 32-битного режима плавающей запятой. Когда этот режим включён, эмуляция 32-битных операций с плавающей запятой выполняется генерацией исключения на каждую инструкцию, использующую 32-битный формат, и ядро обрабатывает инструкцию программно (проблема заключается в несоответствии обработке регистров с нечётными номерами, которые содержатся в 32 старших битах 64-битных регистров с чётными номерами при режиме FR=0 и в 32 младших битах 64-битах регистров с нечётными номерами при режиме FR=1). При включении этого бита необходимо, чтобы код с O32 FP32 ABI работал с кодом O32 FPXX или O32 FP64A ABI (для которого требуется режим FR=1 FPU) или когда он выполняется на новой аппаратуре (MIPS R6 и новее), в которой нет поддержки режима FR=0, когда используется двоичный файл с FP32 ABI.

        Заметим, что этот режим приобретает смысл только, если FPU в 64-битном режиме (FR=1).

        Также заметим, что использование эмуляции по определению уменьшает производительность и её нужно, по возможности, избегать.

    В N32/N64 ABI всегда используется 64-битный режим плавающей запятой, поэтому эмуляция FPU не требуется и FPU всегда работает в режиме FR=1.

    Данный параметр, в основном, предназначен для динамического компоновщика (ld.so(8)).

    Аргументы arg3, arg4 и arg5 игнорируются.

PR_GET_FP_MODE (начиная с Linux 4.0, только на MIPS)
    Возвращает текущий режим плавающей запятой (смотрите описание PR_SET_FP_MODE).

    При успешном выполнении возвращается битовая маска, представляющая текущий режим плавающей запятой.

    Аргументы arg2, arg3, arg4 и arg5 игнорируются.

PR_SET_FPEMU (начиная с Linux 2.4.18, 2.5.9, только для ia64)
    Устанавливает значение управляющих эмуляцией плавающей точки бит равным значению arg2. Для негласной (silently) эмуляции операций с плавающей точкой передайте PR_FPEMU_NOPRINT; при указании PR_FPEMU_SIGFPE операции с плавающей точкой не эмулируются, а посылается сигнал SIGFPE.

PR_GET_FPEMU (начиная с Linux 2.4.18, 2.5.9, только для ia64)
    Записывает значение управляющих бит эмуляции плавающей точки по адресу, указанному в (int *) arg2.

PR_SET_FPEXC (начиная с Linux 2.4.21, 2.5.32, только для PowerPC)
    Устанавливает режим исключений плавающей точки равным arg2. Значение PR_FP_EXC_SW_ENABLE включает использование FPEXC для исключений плавающей точки, PR_FP_EXC_DIV — исключение деления на ноль, PR_FP_EXC_OVF — исключение переполнения, PR_FP_EXC_UND — исключение исчерпания, PR_FP_EXC_RES — исключение неточного результата, PR_FP_EXC_INV — исключение недопустимой операции, PR_FP_EXC_DISABLED отключает исключения плавающей точки, PR_FP_EXC_NONRECOV включает режим асинхронного невосстанавливаемого исключения, PR_FP_EXC_ASYNC включает режим асинхронного восстанавливаемого исключения, PR_FP_EXC_PRECISE включает режим исключения точности.

PR_GET_FPEXC (начиная с Linux 2.4.21, 2.5.32, только для PowerPC)
    Записывает значение режима исключений плавающей точки по адресу, указанному в (int *) arg2.

PR_SET_KEEPCAPS (начиная с Linux 2.2.18)
    Устанавливает флаг вызывающей нити «оставить мандаты». Он описан в capabilities(7). Значение arg2 должно быть или 0 (сбросить флаг) или 1 (установить флаг). Значение флага «оставить мандаты» будет сброшено в 0 при последующих вызовах execve(2).

PR_GET_KEEPCAPS (начиная с Linux 2.2.18)
    Возвращает (как результат функции) текущее состояние флага «оставить мандаты» вызывающей нити. Описание флага смотрите в capabilities(7).

PR_MCE_KILL (начиная с Linux 2.6.32)
    Устанавливает политику удаления (kill) при обнаружении повреждения памяти машинной проверкой для вызывающей нити. Если значение arg равно PR_MCE_KILL_CLEAR, то политика удаления (kill) сбрасывается и используется системная установка по умолчанию. (Значение системной установки по умолчанию определено в /proc/sys/vm/memory_failure_early_kill; смотрите proc(5).) Значение arg2, равное PR_MCE_KILL_SET, указывает использовать политику удаления, заданную в нити. В этом случае значение arg3 определяет политику: раннее удаление (PR_MCE_KILL_EARLY), позднее удаление (PR_MCE_KILL_LATE) или системная установка по умолчанию (PR_MCE_KILL_DEFAULT). При раннем удалении нить получает сигнал SIGBUS сразу же при аппаратном обнаружении повреждения памяти в её адресном пространстве. В режиме позднего удаления процесс будет удалён только когда обратится к повреждённой странице. Более подробную информацию о сигнале SIGBUS смотрите в sigaction(2). Политика наследуется потомками. Значения остальных неиспользуемых аргументов prctl() должны быть равны нулю для совместимости в будущем.

PR_MCE_KILL_GET (начиная с Linux 2.6.32)
    Возвращает значение политики удаления при машинной проверке для текущего процесса. Значения всех неиспользуемых аргументов prctl() должны быть равны нулю.

PR_SET_MM (начиная с Linux 3.3)
    Изменяет определённые поля дескриптора карты памяти ядра вызывающего процесса. Обычно, значения этих полей задаются ядром или динамическим загрузчиком (подробней смотрите ld.so(8)), и обычные приложения не должны использовать эту возможность. Однако, есть случаи (самоизменяющиеся программы), где для программы может оказаться полезным изменение своей карты памяти.

    Вызывающий процесс должен иметь мандат CAP_SYS_RESOURCE. Значения аргумента arg2 описаны далее, а в arg3 задаётся новое значение.Аргументы, arg4 и arg5, если не используются, должны быть равно нулю.

    Начиная с Linux 3.10, данное свойство доступно всегда. До Linux 3.10 это свойство доступно только, если ядро собрано с параметром CONFIG_CHECKPOINT_RESTORE.

    PR_SET_MM_START_CODE
        Устанавливает адрес памяти, выше которого располагается код программы, который может выполняться. Соответствующая область памяти должна быть доступна на чтение и выполнение, но не на запись или быть общедоступной (подробности смотрите в mprotect(2) и mmap(2)).

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

    PR_SET_MM_START_DATA
        Устанавливает адрес памяти, выше которого располагаются инициализированные и не инициализированные (bss) данные. Соответствующая область памяти должна быть доступна на чтение и запись, но не на выполнение или быть в общем доступе.

    PR_SET_MM_END_DATA
        Устанавливает адрес памяти, ниже которого располагаются инициализированные и не инициализированные (bss) данные. Соответствующая область памяти должна быть доступна на чтение и запись, но не на выполнение или быть в общем доступе.

    PR_SET_MM_START_STACK
        Устанавливает начальный адрес стека. Соответствующая область памяти должна быть доступна на чтение и запись.

    PR_SET_MM_START_BRK
        Устанавливает адрес памяти, выше которого можно расширять программную кучу с помощью вызова brk(2). Адрес должен быть больше конечного адреса текущего программного сегмента данных. Также, суммарный размер полученной кучи и сегмента данных не может превышать ограничитель ресурса RLIMIT_DATA (смотрите setrlimit(2)).

    PR_SET_MM_BRK
        Устанавливает текущее значение brk(2). Требования к адресу те же, что и в параметре PR_SET_MM_START_BRK.

    Начиная с Linux 3.5 доступны следующие параметры:

    PR_SET_MM_ARG_START
        Задаёт адрес, выше которого размещена командная строка программы.

    PR_SET_MM_ARG_END
        Задаёт адрес, ниже которого размещена командная строка программы.

    PR_SET_MM_ENV_START
        Задаёт адрес, выше которого размещено окружение программы.

    PR_SET_MM_ENV_END
        Задаёт адрес, ниже которого размещено окружение программы.

        Адрес, передаваемый с PR_SET_MM_ARG_START, PR_SET_MM_ARG_END, PR_SET_MM_ENV_START и PR_SET_MM_ENV_END, должен принадлежать области стека процесса. То есть, соответствующая память должна быть доступна на чтение, запись и (в зависимости от настройки ядра) у неё должен быть установлен атрибут MAP_GROWSDOWN (смотрите mmap(2)).

    PR_SET_MM_AUXV
        Задаёт новый вспомогательный вектор (auxiliary vector). В аргументе arg3 должен передаваться адрес вектора. В аргументе arg4 — размер вектора.

    PR_SET_MM_EXE_FILE
        Заменяет символьную ссылку /proc/pid/exe новой, указывающей на новый исполняемый файл, задаваемый файловым дескриптором в аргументе arg3. Файловый дескриптор должен быть получен с помощью обычного вызова open(2).

        Для изменения символьной ссылки необходимо отключить (unmap) все существующие исполняемые области памяти, включая созданные самим ядром (например, ядро, обычно, создаёт, как минимум, исполняемую область памяти для раздела ELF .text).

        Второе ограничение в том, что такие переходы можно выполнить только один раз за время существования процесса. Дальнейшие попытки будут отброшены. Это должно помочь системным администраторам отследить необычные переходы символьных ссылок во всех работающих процессах системы.

    Начиная с Linux 3.18 доступны следующие параметры:

    PR_SET_MM_MAP
        Предоставляет однократный доступ ко всем адресам, переданным в struct prctl_mm_map (определена в <linux/prctl.h>). В аргументе arg4 должен указываться размер структуры.

        Эта возможность доступна только, если ядро собрано с параметром CONFIG_CHECKPOINT_RESTORE.

    PR_SET_MM_MAP_SIZE
        Возвращает размер struct prctl_mm_map, который ожидает ядро. Это позволяет пользователю подобрать совместимую структуру. Аргумент arg4 должен быть указателем на unsigned int.

        Эта возможность доступна только, если ядро собрано с параметром CONFIG_CHECKPOINT_RESTORE.

PR_MPX_ENABLE_MANAGEMENT, PR_MPX_DISABLE_MANAGEMENT (начиная с Linux 3.19)
    Включает или выключает управление таблицами границ Memory Protection eXtensions (MPX) из ядра. Аргументы arg2, arg3, arg4 и arg5 должны быть равно 0.

    MPX — полуаппаратный механизм проверки границ указателей. Он состоит из набора регистров, хранящих информацию о границах и наборе специальных префиксов инструкций, которые указывают ЦП, в каких инструкциях нужно проверить границы. Число регистров ограничено и когда указателей становится больше чем регистров, их содержимое нужно «засыпать» в набор таблиц. Эти таблицы называются «таблицами границ» (bounds tables), а для управления их заполнением и освобождением из ядра существуют операции MPX prctl().

    Когда управление разрешено, ядро начинает следить за выделением и освобождением таблиц границ. Это делается через ловлю исключений #BR, которые возникают при первом использовании отсутствующей таблицы границ и в результате доставляется исключение в пользовательское пространство, там выделяется таблица и заполняется каталог границ с расположением новой таблицы. Для освобождения ядро проверяет есть ли таблицы границ для нераспределённой памяти и освобождает их если есть.

    Перед включением управления MPX с помощью PR_MPX_ENABLE_MANAGEMENT приложение сначала должно выделить буфер в пользовательском пространстве для каталог границ и поместить расположение этого каталоге в регистр bndcfgu.

    Эти вызовы завершаются ошибкой, если ЦП или ядро не поддерживают MPX. Поддержка MPX в ядре включается параметром настройки CONFIG_X86_INTEL_MPX. Вы можете проверить наличие поддержки MPX в ЦП прочитав бит «mpx» в CPUID следующей командой:

      cat /proc/cpuinfo | grep ' mpx '

    Нить может не переключиться в «длинный» режим (64-битный) при включённом MPX.

    Эти вызовы влияют на все нити процесса.

    Потомок fork(2) наследует состояние управления MPX. Во время execve(2) управление MPX сбрасывается в состояние, как если бы выполнился вызов PR_MPX_DISABLE_MANAGEMENT.

    Дополнительную информацию по Intel MPX смотрите в файле исходного кода ядра Documentation/x86/intel_mpx.txt.

PR_SET_NAME (начиная с Linux 2.6.9)
    Назначает имя вызывающей нити, используя значение памяти, переданное в указателе (char *) arg2. Имя может быть не более 16, включая завершающий байт null (если длина строки, включая завершающий null, превышает 16 байт, то строка просто обрезается). Это то же атрибут, который можно установить через pthread_setname_np(3) и получить с помощью pthread_getname_np(3). Также этот атрибут доступен через /proc/self/task/[tid]/comm, где tid — имя вызывающей нити.

PR_GET_NAME (начиная с Linux 2.6.11)
    Записывает имя вызывающей нити в буфер, указанный в (char *) arg2. Буфер должен быть не более 16 байт; полученная строка будет завершаться null.

PR_SET_NO_NEW_PRIVS (начиная с Linux 3.5)
    Устанавливает в вызывающей нити бит no_new_privs равным arg2. Если значение no_new_privs равно 1, то execve(2) не выдаст прав никому, кто бы не мог это сделать без вызова execve(2) (например, без битов прав режима set-user-ID и set-group-ID и файловых мандатов). После того, как бит установлен, сбросить его нельзя. Значение бита наследуется потомками, созданными с помощью fork(2) и clone(2), и сохраняется при execve(2).

    Начиная с Linux 4.10, значения бита нити no_new_privs отражено в поле NoNewPrivs файла /proc/[pid]/status.

    Дополнительную информацию смотрите в файле исходного кода ядра Documentation/userspace-api/no_new_privs.rst (или в Documentation/prctl/no_new_privstxt до Linux 4.13). Также смотрите seccomp(2).

PR_GET_NO_NEW_PRIVS (начиная с Linux 3.5)
    Возвращает значение (как результат функции) бита no_new_privs в вызывающей нити. Значение 0 соответствует обычному поведению execve(2). Значение 1 показывает, что execve(2) будет работать в ограничивающем права режиме, как описано ранее.

PR_SET_PDEATHSIG (начиная с Linux 2.1.57)
    Устанавливает значение сигнала, приходящего процессу при завершении работы родителя, равным arg2 (это значение может быть от 1..maxsig или 0 для снятия). Этот сигнал получит вызывающий процесс, когда его родитель завершится. Это значение очищается у потомка при выполнении fork(2) и (начиная с Linux 2.4.36 / 2.6.23), если выполняется файл с установленными set-user-ID, set-group-ID или файл, имеющий привязанные мандаты (смотрите capabilities(7)). Это значение сохраняется после вызова execve(2).

    Предупреждение: «родителем» здесь считается нить, создавшая этот процесс. Иначе говоря, сигнал будет послан при завершении нити (например, с помощью pthread_exit(3)), а не всех нитей родительского процесса.

PR_GET_PDEATHSIG (начиная с Linux 2.3.15)
    Записывает текущее значение сигнала о завершении работы родительского процесса по адресу, указанному в (int *) arg2.

PR_SET_PTRACER (начиная с Linux 3.4)
    Имеет смысл, только если включён Yama LSM и в режиме 1 («ограниченный ptrace», значение доступно в /proc/sys/kernel/yama/ptrace_scope). Когда «идентификатор процесса ptracer» передаётся в arg2, вызывающий объявляет, что процесс ptracer может выполнить ptrace(2), как если бы он был прямым предком процесса. Каждая операция PR_SET_PTRACER заменяет предыдущий «идентификатор процесса ptracer». Применение PR_SET_PTRACER с значением arg2 равным 0 очищает «идентификатор процесса ptracer» вызывающего. Если arg2 равно PR_SET_PTRACER_ANY, то ограничения ptrace, предоставленные Yama отключаются для вызывающего процесса.

    Дополнительную информацию смотрите в файле исходного кода ядра Documentation/admin-guide/LSM/Yama.rst (или в Documentation/security/Yama.txt до Linux 4.13).

PR_SET_SECCOMP (начиная с Linux 2.6.23)
    Устанавливает режим безопасных вычислений (seccomp) в вызывающей нити, в котором ограничен список доступных системных вызовов. Новый системный вызов seccomp(2) предоставляет большие возможности чем PR_SET_SECCOMP.

    Режим seccomp выбирается из arg2 (константы seccomp определены в <linux/seccomp.h>).

    Если значение arg2 равно SECCOMP_MODE_STRICT, то в нити доступны только системные вызовы read(2), write(2), _exit(2) (но не exit_group(2)) и sigreturn(2). При запуске других системных вызовов генерируется сигнал SIGKILL. Режим безопасных вычислений полезен для вычислительных приложений, которым может потребоваться выполнить недоверительный байт-код, возможно полученный при чтении из канала или сокета. Эта операция доступна только, если в ядре включён параметр CONFIG_SECCOMP.

    Если значение arg2 равно SECCOMP_MODE_FILTER (начиная с Linux 3.5), то список разрешённых системных вызовов определяется указателем (arg3) на пакетный фильтр Berkeley. Аргумент указывает на struct sock_fprog; в структуре можно описать фильтр и произвольных системных вызовов и их аргументов. Этот режим доступен только, если ядро собрано с параметром CONFIG_SECCOMP_FILTER.

    Если в фильтрах SECCOMP_MODE_FILTER разрешён fork(2), то режим seccomp наследуется потомками, создаваемыми fork(2); если разрешён execve(2), то режим seccomp сохраняется при execve(2). Если в фильтрах разрешены prctl(), то могут быть добавлены дополнительные фильтры; они применяются до тех пор пока не будет найдено запрещение.

    Дополнительную информацию смотрите в файле исходного кода ядра Documentation/userspace-api/seccomp_filter.rst (или в Documentation/prctl/seccomp_filter.txt до Linux 4.13).

PR_GET_SECCOMP (начиная с Linux 2.6.23)
    Возвращает значение (как результат функции) режима безопасных вычислений вызвавшей нити. Если вызывающий не работает в режиме безопасных вычислений, то возвращается 0; если вызывающий находится в режиме ограниченных безопасных вычислений, то вызов prctl() приведёт к отправке процессу сигнала SIGKILL. Если вызывающий работает в режиме фильтрации и данный системный вызов разрешён в фильтрах seccomp, то возвращается 2; в противном случае процесс завершается по сигналу SIGKILL. Эта операция доступна только, если ядро собрано с параметром CONFIG_SECCOMP.

    Начиная с Linux 3.8 в поле Seccomp файла /proc/[pid]/status предоставляется метод получения той же информации, без риска уничтожения процесса; смотрите proc(5).

PR_SET_SECUREBITS (начиная с Linux 2.6.26)
    Устанавливает значение флагов «securebits» вызывающей нити равным значению arg2. Смотрите capabilities(7).

PR_GET_SECUREBITS (начиная с Linux 2.6.26)
    Возвращает (как результат функции) флаги «securebits» вызывающей нити. Смотрите capabilities(7).

PR_SET_THP_DISABLE (начиная с Linux 3.15)
    Задать состояние флага «THP disable» вызывающей нити. Если arg2 не равно нулю, то флаг устанавливается, иначе очищается. Установка этого флага предоставляет метод отключения прозрачных огромных страниц для заданий, код которых нельзя изменить и использование обработчика malloc с madvise(2) невозможно (т. е., место под данные выделено статически). Значение флага «THP disable» наследуется потомком, создаваемым fork(2) и сохраняется после execve(2).

PR_TASK_PERF_EVENTS_DISABLE (начиная с Linux 2.6.31)
    Отключает все счётчики производительности, прикреплённые к вызывающему процессу, не учитывая, были ли они созданы этим процессом или каким-то другим. Счётчики производительности, созданные вызывающим процессом для других процессов, не отключаются. Подробности о счётчиках производительности приведены в файле ядра Linux tools/perf/design.txt.

    Сначала назывался PR_TASK_PERF_COUNTERS_DISABLE; переименован (числовое значение не изменилось) в Linux 2.6.32.

PR_TASK_PERF_EVENTS_ENABLE (начиная с Linux 2.6.31)
    Противоположное действие PR_TASK_PERF_EVENTS_DISABLE; включает счётчики производительности, прикреплённые к вызывающему процессу.

    Сначала назывался PR_TASK_PERF_COUNTERS_ENABLE; переименован в Linux 2.6.32.

PR_GET_THP_DISABLE (начиная с Linux 3.15)
    Возвращает текущее значение (как результат функции) флага «THP disable» вызывающей нити: 1 — флаг установлен; 0 — нет.

PR_GET_TID_ADDRESS (начиная с Linux 3.5)
    Возвращает адрес clear_child_tid, заданный set_tid_address(2) и clone(2) с флагом CLONE_CHILD_CLEARTID, в расположение, указанное в (int **) arg2. Эта возможность доступна только, если ядро собрано с параметром CONFIG_CHECKPOINT_RESTORE. Заметим, что так как системный вызов prctl() не содержит совместимой реализации для AMD64 x32 и MIPS n32 ABI и ядро записывает указатель размером с ядерный, то эта операция требует пользовательский буфер в 8 (не 4) байт в этих ABI.

PR_SET_TIMERSLACK (начиная с Linux 2.6.28)
    Каждая нити имеет два связанных с таймером значения допуска: значение «по умолчанию» и «текущее» значение. Эта операция изменяет «текущее» значение допуска таймера вызывающей нити. Если наносекундное значение из arg2 больше нуля, то оно присваивается «текущему» значению. Если arg2 меньше или равно 0, то «текущий» допуск таймера нити сбрасывается в значение допуска таймера «по умолчанию».

    «Текущий» допуск таймера используется ядром для группировки таймерных окончаний при вызовах нити, которые происходят очень часто; как следствие, таймерные окончания нити могут быть равны до указанной наносекундной задержки (но никогда не будут истекать ранее). Группировка таймерных окончаний может помочь сократить потребление энергии системой, в следствии сокращения количества пробуждений ЦП.

    Таймерные окончания, на которые влияет допуск таймера, устанавливаются select(2), pselect(2), poll(2), ppoll(2), epoll_wait(2), epoll_pwait(2), clock_nanosleep(2), nanosleep(2) и futex(2) (и, следовательно, все библиотечными функциями, реализованными через futex: pthread_cond_timedwait(3), pthread_mutex_timedlock(3), pthread_rwlock_timedrdlock(3), pthread_rwlock_timedwrlock(3) и sem_timedwait(3)).

    Допуск таймера не применяется к нитям, которые планируются в соответствии с политикой реального времени (смотрите sched_setscheduler(2)).

    При создании новой нити этим двум значениям присваивается значение «текущего» допуска создающей нити. После этого нить может подстроить значение своего «текущего» допуска таймера с помощью PR_SET_TIMERSLACK (значение по умолчанию не может быть изменено). Значения допуска таймера для init (PID 1), предка всех процессов, равно 50000 наносекунд (50 микросекунд). Значения допуска таймера сохраняются при вызове execve(2).

    Начиная с Linux 4.6 значение «текущего» допуска таймера любого процесса можно получить и изменить через файл /proc/[pid]/timerslack_ns. Смотрите proc(5).

PR_GET_TIMERSLACK (начиная с Linux 2.6.28)
    Возвращает значение «текущего» допуска (как результат функции) таймера вызывающей нити.

PR_SET_TIMING (начиная с Linux 2.6.0-test4)
    Включает использование обычного статистического временного режима выполнения процесса (process timing) или точного режима на основе меток времени (timestamp-based process timing), при передаче PR_TIMING_STATISTICAL или PR_TIMING_TIMESTAMP в arg2. Действия для PR_TIMING_TIMESTAMP пока не реализованы (попытка установить этот режим приведёт к ошибке EINVAL).

PR_GET_TIMING (начиная с Linux 2.6.0-test4)
    Возвращает (как результат функции) тип используемого в данный момент временного режима выполнения процесса.

PR_SET_TSC (начиная с Linux 2.6.26, только для x86)
    Устанавливает состояние флага, определяющего может ли процесс прочитать счётчик метки времени (timestamp counter). Значение PR_TSC_ENABLE в arg2 разрешает чтение, PR_TSC_SIGSEGV включает генерацию SIGSEGV, если процесс пытается прочитать счётчик метки времени.

PR_GET_TSC (начиная с Linux 2.6.26, только для x86)
    Записывает значение флага, определяющего может ли быть прочитан счётчик метки времени (timestamp counter), по адресу, указанному в (int *) arg2.

PR_SET_UNALIGN
    (только для: ia64, начиная с Linux 2.3.48; parisc, начиная с Linux 2.6.15; PowerPC, начиная с Linux 2.6.18; Alpha, начиная с Linux 2.6.22; sh, начиная с Linux 2.6.34; tile, начиная с Linux 3.12) Устанавливает значение битов контроля доступа выравнивания равным значению arg2. При значении PR_UNALIGN_NOPRINT пользовательский доступ без выравнивания без уведомления исправляется, а при PR_UNALIGN_SIGBUS генерируется сигнал SIGBUS. На Alpha также поддерживается дополнительный флаг со значением 4 (именованная константа отсутствует), который указывает ядру не исправлять невыровненный доступ (аналогично флагу UAC_NOFIX в операции SSI_NVPAIRS системного вызова setsysinfo() на Tru64).

PR_GET_UNALIGN
    (информацию о версиях и архитектурах смотрите в PR_SET_UNALIGN) Записывает значение битов контроля доступа выравнивания по адресу, указанному в (unsigned int *) arg2.

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При успешном выполнении для операций PR_GET_DUMPABLE, PR_GET_KEEPCAPS, PR_GET_NO_NEW_PRIVS, PR_GET_THP_DISABLE, PR_CAPBSET_READ, PR_GET_TIMING, PR_GET_TIMERSLACK, PR_GET_SECUREBITS, PR_MCE_KILL_GET, PR_CAP_AMBIENT+PR_CAP_AMBIENT_IS_SET, и (если возвращается) PR_GET_SECCOMP возвращаются неотрицательные значения, описанные ранее. При успешном выполнении для остальных значений option возвращается 0. При ошибке возвращается -1, а errno устанавливается в соответствующее значение.

ОШИБКИ

EACCES
    Значение option равно PR_SET_SECCOMP и arg2 равно SECCOMP_MODE_FILTER, но процесс не имеет мандата CAP_SYS_ADMIN или установленного атрибута no_new_privs (смотрите обсуждение PR_SET_NO_NEW_PRIVS выше).

EACCES
    Значение option равно PR_SET_MM, а arg3 — PR_SET_MM_EXE_FILE, файл не является исполняемым.

EBADF
    Значение option равно PR_SET_MM, arg3 — PR_SET_MM_EXE_FILE, и файловый дескриптор, переданный в arg4, некорректен.

EBUSY
    Значение option равно PR_SET_MM, arg3 — PR_SET_MM_EXE_FILE, и это вторая попытка изменить символьную ссылку /proc/pid/exe, что запрещено.

EFAULT
    В arg2 указан неправильный адрес.

EFAULT
    Значение option равно PR_SET_SECCOMP, arg2 равно SECCOMP_MODE_FILTER, система была собрана с CONFIG_SECCOMP_FILTER и arg3 содержит некорректный адрес.

EINVAL
    Не распознано значение option.

EINVAL
    Значение option равно PR_MCE_KILL, PR_MCE_KILL_GET или PR_SET_MM, и неиспользуемые аргументы prctl() не равны нулю.

EINVAL
    Неверное значение arg2 для указанной в option операции.

EINVAL
    Значение option равно PR_SET_SECCOMP или PR_GET_SECCOMP, и ядро не собрано с параметром CONFIG_SECCOMP.

EINVAL
    Значение option равно PR_SET_SECCOMP, arg2 равно SECCOMP_MODE_FILTER и ядро было собрано без CONFIG_SECCOMP_FILTER.

EINVAL
    Значение option равно PR_SET_MM и одно из следующего является истиной:

    *   Значение arg4 или arg5 не равно нулю;

    *   Значение arg3 больше TASK_SIZE (ограничение на размер пользовательского адресного пространства для этой архитектуры);

    *   Значение arg2 равно PR_SET_MM_START_CODE, PR_SET_MM_END_CODE, PR_SET_MM_START_DATA, PR_SET_MM_END_DATA или PR_SET_MM_START_STACK, и права на соответствующую область памяти не удовлетворяют требованиям;

    *   Значение arg2 равно PR_SET_MM_START_BRK или PR_SET_MM_BRK, и значение arg3 меньше или равно концу сегмента данных, или было бы превышено ограничение ресурса RLIMIT_DATA.

EINVAL
    Значение option равно PR_SET_PTRACER и значение arg2 не равно 0, PR_SET_PTRACER_ANY или PID существующего процесса.

EINVAL
    Значение option равно PR_SET_PDEATHSIG и значение arg2 не является корректным номером сигнала.

EINVAL
    Значение option равно PR_SET_DUMPABLE и значение arg2 не равно SUID_DUMP_DISABLE или SUID_DUMP_USER.

EINVAL
    Значение option равно PR_SET_TIMING и значение arg2 не равно PR_TIMING_STATISTICAL.

EINVAL
    Значение option равно PR_SET_NO_NEW_PRIVS и значение arg2 не равно 1 или arg3, arg4 или arg5 не равны нулю.

EINVAL
    Значение option равно PR_GET_NO_NEW_PRIVS и значения arg2, arg3, arg4 или arg5 не равны нулю.

EINVAL
    Значение option равно PR_SET_THP_DISABLE и arg3, arg4 или arg5 не равны нулю.

EINVAL
    Значение option равно PR_GET_THP_DISABLE и значения arg2, arg3, arg4 или arg5 не равны нулю.

EINVAL
    Значение option равно PR_CAP_AMBIENT и неиспользуемый аргумент (arg4, arg5 или, в случае PR_CAP_AMBIENT_CLEAR_ALL, arg3) не равен нулю; или arg2 содержит некорректное значение; или arg2 равно PR_CAP_AMBIENT_LOWER, PR_CAP_AMBIENT_RAISE или PR_CAP_AMBIENT_IS_SET и в arg3 указан некорректный мандат.

ENXIO
    Значение option было PR_MPX_ENABLE_MANAGEMENT или PR_MPX_DISABLE_MANAGEMENT и ядро или ЦП не поддерживают управление MPX. Проверьте, что ядро и процессор поддерживают MPX.

EOPNOTSUPP
    Значение option равно PR_SET_FP_MODE и arg2 содержит неправильное или неподдерживаемое значение.

EPERM
    Значение option равно PR_SET_SECUREBITS, и вызывающий не имеет мандата CAP_SETPCAP, или пытается сбросить «заблокированный» флаг, или пытается установить флаг, для которого установлен соответствующий заблокированный флаг (смотрите capabilities(7)).

EPERM
    Значение option равно PR_SET_KEEPCAPS, и у вызывающего установлен флаг SECBIT_KEEP_CAPS_LOCKED (смотрите capabilities(7)).

EPERM
    Значение option равно PR_CAPBSET_DROP, и вызывающий не имеет мандата CAP_SETPCAP.

EPERM
    Значение option равно PR_SET_MM, и вызывающий не имеет мандата CAP_SYS_RESOURCE.

EPERM
    Значение option равно PR_CAP_AMBIENT и arg2 равно PR_CAP_AMBIENT_RAISE, но мандат, указанный в arg3, отсутствует в разрешительном или унаследованном наборе мандатов, или был установлен бит безопасности PR_CAP_AMBIENT_LOWER.

ВЕРСИИ
Системный вызов prctl() впервые появился в Linux 2.1.57.

СООТВЕТСТВИЕ СТАНДАРТАМ
Данный вызов существует только в Linux. В IRIX есть системный вызов prctl() (также представленный в Linux 2.1.44 как irix_prctl на архитектуре MIPS) объявленный как

    ptrdiff_t prctl(int option, int arg2, int arg3);

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

СМОТРИТЕ ТАКЖЕ
signal(2), core(5)