PRCTL - Linux手册页

时间:2019-08-20 17:59:07  来源:igfitidea点击:

Linux程序员手册 第2部分
更新日期: 2020-08-13

名称

prctl-对进程或线程的操作

语法

#include <sys/prctl.h>

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

说明

prctl()处理调用线程或进程行为的各个方面。

请注意,对某些prctl()操作的粗心使用会混淆用户空间运行时环境,因此应谨慎使用这些操作。

调用prctl()时会用一个第一个参数来描述要做什么(用中定义的值),而后一个参数的重要性取决于第一个参数。第一个参数可以是:

PR_CAP_AMBIENT(since Linux 4.3)

Reads or changes the ambient capability set of the calling thread,
according to the value of
arg2,

which must be one of the following:

PR_CAP_AMBIENT_RAISE
arg3中指定的功能已添加到环境集中。指定的功能必须已经存在于流程的允许和可继承集合中。如果设置了SECBIT_NO_CAP_AMBIENT_RAISE安全位,则不允许此操作。
PR_CAP_AMBIENT_LOWER
arg3中指定的功能已从环境集中删除。
PR_CAP_AMBIENT_IS_SET
如果arg3中的功能在环境集中,则prctl()调用返回1,否则返回0。
PR_CAP_AMBIENT_CLEAR_ALL
所有功能将从环境集中删除。此操作需要将arg3设置为零。
在上述所有操作中,必须将arg4和arg5指定为0。
libcap(3)库中以cap_get_ambient(3),cap_set_ambient(3)和cap_reset_ambient(3)的形式提供了位于上述操作之上的高层接口。
PR_CAPBSET_READ(since Linux 2.6.25)
如果arg2中指定的功能在调用线程的功能边界集中,则返回1(作为函数结果),否则返回0。 (功能常数在中定义。)功能限制集指示进程是否可以通过在随后调用execve(2)时通过文件的允许功能集来接收功能。
如果arg2中指定的功能无效,则调用将失败,并显示错误EINVAL。
libcap(3)库中以cap_get_bound(3)的形式提供了位于此操作之上的更高级别的接口。
PR_CAPBSET_DROP(since Linux 2.6.25)
如果调用线程在其用户名称空间中具有CAP_SETPCAP功能,则从调用线程的功能边界集中删除arg2指定的功能。调用线程的所有子代都将继承新缩小的边界集。
调用失败,并显示以下错误:如果调用线程没有CAP_SETPCAP,则为EPERM;否则为0。如果arg2不代表有效能力,则为EINVAL;否则为0。或EINVAL(如果内核中未启用文件功能),在这种情况下,不支持边界集。
libcap(3)库中以cap_drop_bound(3)的形式提供了位于此操作之上的更高级别的接口。
PR_SET_CHILD_SUBREAPER(since Linux 3.4)
如果arg2不为零,则设置调用进程的"子子级"属性;否则,为0。如果arg2为零,则取消设置该属性。
一个子收割者在其后代过程中扮演init(1)的角色。当某个流程成为孤立流程(即其直接父流程终止)时,该流程将重新绑定到最近的尚存祖先次级收割者。随后,在孤立进程中对getppid(2)的调用现在将返回子收割者进程的PID,并且当孤立孤儿终止时,正是子收割者进程将接收SIGCHLD信号,并能够在接收器上等待(2)。发现其终止状态的过程。
fork(2)和clone(2)创建的子代不会继承" child subreaper"属性的设置。该设置在execve(2)中保留。
建立子收货流程在会话管理框架中非常有用,在会话管理框架中,由一个子收货流程管理一组层次的流程,当某个流程(例如,双叉守护程序)终止(也许这样)时,需要通知该流程它可以重新启动该过程)。出于类似的原因,某些init(1)框架(例如systemd(1))采用了子收割过程。
PR_GET_CHILD_SUBREAPER(since Linux 3.4)
在(int *)arg2所指向的位置中返回调用者的"子子收割者"设置。
PR_SET_DUMPABLE(since Linux 2.3.20)
设置" dumpable"属性的状态,该属性确定在传递默认行为是生成核心转储的信号时是否为调用进程生成核心转储。
在2.6.12(含)以下的内核中,arg2必须为0(SUID_DUMP_DISABLE,进程不可转储)或1(SUID_DUMP_USER,进程可转储)。在内核2.6.13和2.6.17之间,还允许使用值2,这导致通常不会被转储的任何二进制文件只能由root读取。出于安全原因,此功能已被删除。 (另请参阅proc(5)中对/ proc / sys / fs /:suid_dumpable的描述。)
Normally, the "dumpable" attribute is set to 1. However, it is reset to the current value contained in the file /proc/sys/fs/:suid_dumpable

(which by default has the value 0),
in the following circumstances:

*
进程的有效用户或组ID已更改。
*
进程的文件系统用户或组ID已更改(请参阅凭据(7))。
*
该过程执行(execve(2))设置用户ID或设置组ID程序,从而导致有效用户ID或有效组ID发生更改。
*
进程执行(execve(2))具有文件功能的程序(请参阅功能(7)),但前提是所获得的允许能力超过了该进程已允许的能力。
无法转储的进程不能通过ptrace(2)PTRACE_ATTACH附加;有关更多详细信息,请参见ptrace(2)。
如果某个进程不可转储,则该进程的/ proc / [pid]目录中文件的所有权将受到proc(5)中所述的影响。
PR_GET_DUMPABLE(since Linux 2.3.20)
返回(作为函数结果)调用进程的dumpable属性的当前状态。
PR_SET_ENDIAN(since Linux 2.6.18, PowerPC only)
将调用过程的字节序设置为arg2中给出的值,该值应为以下之一:PR_ENDIAN_BIG,PR_ENDIAN_LITTLE或PR_ENDIAN_PPC_LITTLE(PowerPC伪小字节序)。
PR_GET_ENDIAN(since Linux 2.6.18, PowerPC only)
在(int *)arg2指向的位置返回调用进程的字节序。
PR_SET_FP_MODE(since Linux 4.0, only on MIPS)
在MIPS体系结构上,可以使用ABI构建用户空间代码,该应用程序允许与具有更多限制性浮点(FP)要求的代码链接。例如,可以将用户空间代码构建为以O32 FPXX ABI为目标,并与为限制性更强的FP32或FP64 ABI之一构建的代码链接。当链接更多限制性代码时,该过程的总体要求是使用限制性更强的浮点模式。
由于内核无法提前知道应以哪种模式执行进程,并且由于这些限制会在进程的整个生命周期内发生变化,因此提供PR_SET_FP_MODE操作以允许从用户空间控制浮点模式。

The
(unsigned int) arg2

argument is a bit mask describing the floating-point mode used:

PR_FP_MODE_FR
当此位未设置(所谓的FR = 0或FR0模式)时,32个浮点寄存器为32位宽,而64位寄存器表示为一对寄存器(偶数和奇数,偶数和偶数)。编号的寄存器包含低32位,而奇数寄存器包含高32位)。
当该位置1(在支持的硬件上)时,32个浮点寄存器的宽度为64位(所谓的FR = 1或FR1模式)。请注意,现代MIPS实现(MIPS R6和更高版本)仅支持FR = 1模式。
使用O32 FP32 ABI的应用程序只能在未设置此位(FR = 0;或者可以在启用FRE的情况下使用,请参见下文)下运行。使用O32 FP64 ABI(和提供用于与现有FP32代码一起运行的功能的O32 FP64A ABI;请参见下文)的应用程序只能在该位置1(FR = 1)时运行。使用O32 FPXX ABI的应用程序可以FR = 0或FR = 1进行操作。
PR_FP_MODE_FRE
启用32位浮点模式的仿真。启用此模式后,它将通过对使用32位格式的每条指令引发保留指令异常来模拟32位浮点运算,然后内核在软件中处理该指令。 (问题在于处理奇数寄存器的差异,即在FR = 0模式下偶数为64位寄存器的高32位,而在FR =模式下为奇数64位寄存器的低32位的部分= 1模式。)当使用O32 FP32 ABI的代码应与兼容O32 FPXX或O32 FP64A ABI(要求FR = 1 FPU模式)的代码一起使用时,或在较新的硬件上执行(MIPS R6起)时,必须启用此位。 ),当使用带有FP32 ABI的二进制文件时,缺少FR = 0模式支持。
请注意,仅当FPU处于64位模式(FR = 1)时,此模式才有意义。
注意,使用仿真本质上会严重影响性能,应尽可能避免使用。
在N32 / N64 ABI中,始终使用64位浮点模式,因此不需要FPU仿真,并且FPU始终以FR = 1模式运行。
此选项主要供动态链接器(ld.so(8))使用。
参数arg3,arg4和arg5被忽略。
PR_GET_FP_MODE(since Linux 4.0, only on MIPS)
返回(作为函数结果)当前浮点模式(有关详细信息,请参见PR_SET_FP_MODE的描述)。
成功后,该调用将返回一个代表当前浮点模式的位掩码。
参数arg2arg3,arg4和arg5被忽略。
PR_SET_FPEMU(since Linux 2.4.18, 2.5.9, only on ia64)
将浮点仿真控制位设置为arg2。传递PR_FPEMU_NOPRINT以静默模拟浮点操作访问,传递PR_FPEMU_SIGFPE不模拟浮点操作并发送SIGFPE。
PR_GET_FPEMU(since Linux 2.4.18, 2.5.9, only on ia64)
在(int *)arg2指向的位置返回浮点仿真控制位。
PR_SET_FPEXC(since Linux 2.4.21, 2.5.32, only on PowerPC)
将浮点异常模式设置为arg2。传递PR_FP_EXC_SW_ENABLE以使用FPEXC进行FP异常启用,PR_FP_EXC_DIV进行浮点除以零,PR_FP_EXC_OVF进行浮点溢出,PR_FP_EXC_UND进行浮点下溢,PR_FP_EXC_RES进行浮点不精确计算,PR_FP_EXC_INC进行无效对于禁用的FP异常,PR_FP_EXC_NONRECOV用于异步不可恢复异常模式,PR_FP_EXC_ASYNC用于异步可恢复异常模式,PR_FP_EXC_PRECISE用于精确异常模式。
PR_GET_FPEXC(since Linux 2.4.21, 2.5.32, only on PowerPC)
在(int *)arg2指向的位置返回浮点异常模式。
PR_SET_IO_FLUSHER(since Linux 5.6)
如果用户进程包含在块层或文件系统I / O路径中,并且可以在处理I / O请求时分配内存,则必须将arg2设置为1。这会将进程置于IO_FLUSHER状态,从而可以对其进行特殊处理。分配内存时取得进展。如果arg2为0,则该进程将清除IO_FLUSHER状态,并将使用默认行为。
调用进程必须具有CAP_SYS_RESOURCE功能。
arg3,arg4和arg5必须为零。
IO_FLUSHER状态由通过fork(2)创建的子进程继承,并在execve(2)中保留。
IO_FLUSHER应用程序的示例包括FUSE守护程序,SCSI设备仿真守护程序和执行错误处理的守护程序,例如多路径路径恢复应用程序。
PR_GET_IO_FLUSHER (Since Linux 5.6)
返回(作为函数结果)调用者的IO_FLUSHER状态。值为1表示呼叫者处于IO_FLUSHER状态; 0表示呼叫者未处于IO_FLUSHER状态。
调用过程必须具有CAP_SYS_RESOURCE功能。
arg2arg3,arg4和arg5必须为零。
PR_SET_KEEPCAPS(since Linux 2.2.18)
设置调用线程的"保留功能"标志的状态。在功能(7)中描述了此标志的作用。 arg2必须为0(清除标志)或1(设置标志)。在随后的execve(2)调用中,"保持能力"值将重置为0。
PR_GET_KEEPCAPS(since Linux 2.2.18)
返回(作为函数结果)调用线程的"保持能力"标志的当前状态。有关此标志的说明,请参见功能(7)。
PR_MCE_KILL(since Linux 2.6.32)
为调用线程设置计算机检查内存损坏终止策略。如果arg2为PR_MCE_KILL_CLEAR,则清除线程内存损坏终止策略,并使用系统范围的默认值。 (系统范围的默认值由/ 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(since Linux 2.6.32)
返回(作为函数结果)当前的每进程计算机检查终止策略。所有未使用的prctl()参数必须为零。
PR_SET_MM(since Linux 3.3)
修改调用进程的某些内核内存映射描述符字段。通常,这些字段由内核和动态加载程序设置(有关更多信息,请参见ld.so(8)),常规应用程序不应使用此功能。但是,在某些情况下(例如自修改程序),程序可能会发现更改自己的内存映射很有用。
调用进程必须具有CAP_SYS_RESOURCE功能。 arg2中的值是以下选项之一,而arg3中提供了该选项的新值。如果未使用,则arg4和arg5参数必须为零。
Before Linux 3.10,

this feature is available only if the kernel is built with the
CONFIG_CHECKPOINT_RESTORE

option enabled.

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_STARTPR_SET_MM_ARG_END,PR_SET_MM_ENV_START和PR_SET_MM_ENV_END传递的地址应属于进程堆栈区域。因此,相应的内存区域必须是可读,可写的,并且(取决于内核配置)具有MAP_GROWSDOWN属性集(请参见mmap(2))。
PR_SET_MM_AUXV
设置一个新的辅助向量。 arg3参数应提供向量的地址。 arg4是向量的大小。
PR_SET_MM_EXE_FILE
用一个指向由arg3参数中提供的文件描述符标识的新可执行文件的新链接替换/ proc / pid / exe符号链接。文件描述符应通过常规的open(2)调用获得。
要更改符号链接,需要取消映射所有现有的可执行存储区域,包括由内核本身创建的区域(例如,内核通常为ELF .text节创建至少一个可执行存储区域)。
在Linux 4.9和更早版本中,PR_SET_MM_EXE_FILE操作只能在进程的生存期内执行一次;尝试第二次执行该操作将导致错误EPERM。出于安全原因(后来被认为是伪造的)实施了此限制,并且在Linux 4.10中取消了此限制,因为某些用户空间应用程序需要多次执行此操作。

从Linux 3.18开始,以下选项可用。

PR_SET_MM_MAP
通过传入struct prctl_mm_map(如中定义)提供对所有地址的一次性访问。 arg4参数应提供结构的大小。
仅当启用CONFIG_CHECKPOINT_RESTORE选项构建内核时,此功能才可用。
PR_SET_MM_MAP_SIZE
返回内核期望的struct prctl_mm_map的大小。这使用户空间可以找到兼容的结构。 arg4参数应为指向无符号int的指针。
仅当启用CONFIG_CHECKPOINT_RESTORE选项构建内核时,此功能才可用。
PR_MPX_ENABLE_MANAGEMENT, PR_MPX_DISABLE_MANAGEMENT(since Linux 3.19, removed in Linux 5.4; only on x86)
启用或禁用内存保护扩展(MPX)边界表的内核管理。 arg2arg3,arg4和arg5参数必须为零。
MPX是一种硬件辅助机制,用于对指针执行边界检查。它由一组存储边界信息的寄存器和一组特殊的指令前缀组成,这些前缀告诉CPU应该在哪些指令上执行边界执行。这些寄存器的数量是有限的,并且当指针多于寄存器时,必须将它们的内容"堆积"到一组表中。这些表称为"边界表",MPX prctl()操作控制内核是否管理它们的分配和释放。
启用管理后,内核将接管边界表的分配和释放。它通过捕获第一次使用缺少边界表而导致的#BR异常来做到这一点,而不是将异常传递给用户空间,而是分配该表并使用新表的位置填充bounds目录。为了释放,内核检查以查看是否存在未分配内存的边界表,如果存在,则释放它们。
在使用PR_MPX_ENABLE_MANAGEMENT启用MPX管理之前,应用程序必须首先为bounds目录分配一个用户空间缓冲区,并将该目录的位置放在bndcfgu寄存器中。
如果CPU或内核不支持mpx,则这些调用将失败。通过CONFIG_X86_INTEL_MPX配置选项启用了对MPX的内核支持。您可以通过查找mpx CPUID位来检查CPU是否支持mpx,就像使用以下命令一样:
cat /proc/cpuinfo | grep aq mpx aq
启用MPX时,线程可能无法进入或退出长(64位)模式。
进程中的所有线程都受这些调用的影响。
fork(2)的子级继承MPX管理的状态。在execve(2)期间,MPX管理将重置为一个状态,就像已调用PR_MPX_DISABLE_MANAGEMENT一样。
有关Intel MPX的更多信息,请参阅内核源文件Documentation / x86 / intel_mpx.txt。
由于缺少工具链支持,因此Linux 5.4和更高版本不支持PR_MPX_ENABLE_MANAGEMENT和PR_MPX_DISABLE_MANAGEMENT。
PR_SET_NAME(since Linux 2.6.9)
使用(char *)arg2指向的位置中的值设置调用线程的名称。该名称最长为16个字节,包括终止的空字节。 (如果字符串的长度(包括终止的空字节)超过16个字节,则该字符串将被静默截断。)这是可以通过pthread_setname_np(3)设置并使用pthread_getname_np(3)检索的相同属性。该属性同样可以通过/ proc / self / task / [tid] / comm访问(请参阅proc(5)),其中[tid]是调用线程的线程ID,由gettid(2)返回。
PR_GET_NAME(since Linux 2.6.11)
在(char *)arg2指向的缓冲区中返回调用线程的名称。缓冲区应允许最多16个字节的空间。返回的字符串将以null终止。
PR_SET_NO_NEW_PRIVS(since Linux 3.5)
将调用线程的no_new_privs属性设置为arg2中的值。在no_new_privs设置为1的情况下,execve(2)承诺不授予特权以执行没有execve(2)调用无法完成的任何操作(例如,呈现set-user-ID和set-group-ID模式位,并且文件功能不起作用)。设置后,就不能取消设置no_new_privs属性。该属性的设置由fork(2)和clone(2)创建的子代继承,并保留在execve(2)中。
从Linux 4.10开始,可以通过/ proc / [pid] / status文件中的NoNewPrivs字段查看线程的no_new_privs属性的值。
有关更多信息,请参阅内核源文件Documentation / userspace-api / no_new_privs.rst(或Linux 4.13之前的Documentation / prctl / no_new_privs.txt)。另请参见seccomp(2)。
PR_GET_NO_NEW_PRIVS(since Linux 3.5)
返回(作为函数结果)调用线程的no_new_privs属性的值。值为0表示常规execve(2)行为。值为1表示execve(2)将在上述特权限制模式下运行。
PR_PAC_RESET_KEYS(since Linux 5.0, only on arm64)
将线程的指针身份验证密钥安全地重置为内核生成的新随机值。
The set of keys to be reset is specified by arg2,

which must be a logical OR of zero or more of the following:

PR_PAC_APIAKEY
指令认证密钥A
PR_PAC_APIBKEY
指令认证密钥B
PR_PAC_APDAKEY
数据认证密钥A
PR_PAC_APDBKEY
数据验证密钥B
PR_PAC_APGAKEY
通用身份验证lqArq密钥。
(是的,确实没有通用的B密钥。)
作为一种特殊情况,如果arg2为零,那么将重置所有键。由于将来可能会添加新键,因此这是在建立干净的执行上下文时完全擦除现有键的推荐方法。请注意,无需准备使用PR_PAC_RESET_KEYS来准备调用execve(2),因为execve(2)会重置所有指针身份验证密钥。
其余参数arg3,arg4和arg5必须全部为零。
如果参数无效,尤其是arg2包含无法识别的设置位或与该平台上不可用的键对应的设置位,则调用将失败,并显示错误EINVAL。
警告:由于编译器或运行时环境可能正在使用某些或所有键,因此成功的PR_PAC_RESET_KEYS可能会使调用过程崩溃。安全使用它的条件是复杂的,并且取决于系统。除非您知道自己在做什么,否则不要使用它。
有关更多信息,请参见内核源文件Documentation / arm64 / pointer-authentication.rst(或Linux 5.3之前的Documentation / arm64 / pointer-authentication.txt)。
PR_SET_PDEATHSIG(since Linux 2.1.57)
将调用进程的父死亡信号设置为arg2(信号值在1..NSIG-1范围内,或在0之前清除)。这是调用进程在其父进程死亡时将获得的信号。
警告:在这种情况下,"父级"被认为是创建此进程的线程。换句话说,信号将在该线程终止时(例如通过pthread_exit(3))发送,而不是在父进程中的所有线程终止之后发送。
父死亡信号在随后终止父线程时以及在每个子调用者进程终止时发送(请参见上面PR_SET_CHILD_SUBREAPER的描述),调用者随后将其重新绑定到父子信号。如果在PR_SET_PDEATHSIG操作之前,父线程和所有祖先子收割者已经终止,则没有父死亡信号发送到调用方。
父死亡信号是过程控制的(请参见signal(7)),如果子代使用sigaction(2)SA_SIGINFO标志安装了处理程序,则该处理程序的siginfo_t参数的si_pid字段包含终止父级的PID处理。
fork(2)的子代清除了父代死亡信号设置。当执行set-user-ID或set-group-ID二进制文件或具有相关功能的二进制文件时,也将清除(自Linux 2.4.36 / 2.6.23起)(请参阅功能(7));否则,此值将在execve(2)中保留。更改以下任何线程凭证时,也会清除父死亡信号设置:有效用户ID,有效组ID,文件系统用户ID或文件系统组ID。
PR_GET_PDEATHSIG(since Linux 2.3.15)
在(int *)arg2指向的位置返回父进程终止信号的当前值。
PR_SET_PTRACER(since Linux 3.4)
仅当启用Yama LSM并处于模式1("受限ptrace",可通过/ proc / sys / kernel / yama / ptrace_scope看到)时,这才有意义。当在arg2中传递" ptracer进程ID"时,调用方将声明ptracer进程可以将调用进程ptrace(2)视为直接进程的祖先。每个PR_SET_PTRACER操作都会替换先前的" ptracer进程ID"。使用arg2设置为0的PR_SET_PTRACER会清除调用方的" ptracer进程ID"。如果arg2为PR_SET_PTRACER_ANY,则对于调用过程将有效禁用Yama引入的ptrace限制。
有关更多信息,请参阅内核源文件Documentation / admin-guide / LSM / Yama.rst(或Linux 4.13之前的Documentation / security / Yama.txt)。
PR_SET_SECCOMP(since Linux 2.6.23)
为调用线程设置安全计算(seccomp)模式,以限制可用的系统调用。最近的seccomp(2)系统调用提供了PR_SET_SECCOMP功能的超集。
通过arg2选择seccomp模式。 (seccomp常量在中定义。)
将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)创建的子代继承;否则,seccomp模式将由fork(2)创建的子代继承。如果允许execve(2),则在execve(2)中保留seccomp模式。如果过滤器允许调用prctl(),则可以添加其他过滤器;它们将按顺序运行,直到看到第一个不允许的结果。
有关更多信息,请参阅内核源文件Documentation / userspace-api / seccomp_filter.rst(或Linux 4.13之前的Documentation / prctl / seccomp_filter.txt)。
PR_GET_SECCOMP(since Linux 2.6.23)
返回(作为函数结果)调用线程的安全计算模式。如果调用者不在安全计算模式下,则此操作返回0;否则,返回0。如果调用方处于严格的安全计算模式,则prctl()调用将导致SIGKILL信号发送到该进程。如果调用方处于过滤器模式,并且seccomp过滤器允许此系统调用,则它返回2;否则,返回2。否则,该进程将被SIGKILL信号杀死。仅当内核配置为启用CONFIG_SECCOMP时,此操作才可用。
从Linux 3.8开始,/ proc / [pid] / status文件的Seccomp字段提供了一种获取相同信息的方法,而不会导致进程被杀死。参见proc(5)。
PR_SET_SECUREBITS(since Linux 2.6.26)
将调用线程的"安全位"标志设置为arg2中提供的值。参见功能(7)。
PR_GET_SECUREBITS(since Linux 2.6.26)
返回(作为函数结果)调用线程的"安全位"标志。参见功能(7)。
PR_GET_SPECULATION_CTRL(since Linux 4.17)
返回(作为函数结果)arg2中指定的推测错误功能的状态。当前,此参数的唯一允许值为PR_SPEC_STORE_BYPASS(否则,调用将失败,并显示错误ENODEV)。
The return value uses bits 0-3 with the following meaning:
PR_SPEC_PRCTL
可以通过PR_SET_SPECULATION_CTRL对每个线程控制缓解。
PR_SPEC_ENABLE
投机功能已启用,缓解功能已禁用。
PR_SPEC_DISABLE
投机功能已禁用,缓解已启用。
PR_SPEC_FORCE_DISABLE
与PR_SPEC_DISABLE相同,但无法撤消。
PR_SPEC_DISABLE_NOEXEC(since Linux 5.1)
与PR_SPEC_DISABLE相同,但是状态将在execve(2)上清除。
如果所有位均为0,则CPU不受推测错误功能的影响。
如果设置了PR_SPEC_PRCTL,则可以对缓解进行每个线程控制。如果未设置,则用于推测错误功能的prctl()将失败。
arg3,arg4和arg5参数必须指定为0;否则,调用将失败,并显示错误EINVAL。
PR_SET_SPECULATION_CTRL(since Linux 4.17)
设置arg2中指定的推测错误功能的状态。推测错误功能设置是每个线程的属性。
Currently, arg2

must be one of:

PR_SPEC_STORE_BYPASS
设置推测存储绕过错误功能的状态。
PR_SPEC_INDIRECT_BRANCH(since Linux 4.20)
设置间接分支推测错误功能的状态。
如果arg2没有上述值之一,则调用失败,并显示错误ENODEV。
The arg3

argument is used to hand in the control value,
which is one of the following:

PR_SPEC_ENABLE
投机功能已启用,缓解已禁用。
PR_SPEC_DISABLE
投机功能已禁用,缓解已启用。
PR_SPEC_FORCE_DISABLE
与PR_SPEC_DISABLE相同,但无法撤消。具有arg2相同值的后续prctl(arg2,PR_SPEC_ENABLE)将失败,并显示错误EPERM。
PR_SPEC_DISABLE_NOEXEC(since Linux 5.1)
与PR_SPEC_DISABLE相同,但是状态将在execve(2)上清除。当前仅支持arg2等于PR_SPEC_STORE_BYPASS。
arg3中任何不受支持的值都将导致调用失败,并显示错误ERANGE。
arg4和arg5参数必须指定为0;否则,调用将失败,并显示错误EINVAL。
还可以通过spec_store_bypass_disable引导参数来控制推测功能。此参数可能会强制执行只读策略,这将导致prctl()调用失败,并显示错误ENXIO。有关更多详细信息,请参见内核源文件Documentation / admin-guide / kernel-parameters.txt。
PR_SVE_SET_VL(since Linux 4.15, only on arm64)
配置线程的SVE向量长度,由(int)arg2指定。参数arg3,arg4和arg5被忽略。
对应于PR_SVE_VL_LEN_MASK的arg2位必须设置为所需的矢量长度(以字节为单位)。这被解释为上限:内核将选择不超过指定值的最大可用向量长度。特别是,为PR_SVE_VL_LEN_MASK位指定SVE_VL_MAX(在中定义)会请求支持的最大矢量长度。
In addition, the other bits of arg2

must be set to one of the following combinations of flags:

0
立即执行更改。在线程中的下一个execve(2)处,矢量长度将重置为/ proc / sys / abi / sve_default_vector_length中配置的值。
PR_SVE_VL_INHERIT
立即执行更改。随后的execve(2)调用将保留新的向量长度。
PR_SVE_SET_VL_ONEXEC
推迟更改,以便在线程中的下一个execve(2)执行该更改。进一步的execve(2)调用会将向量长度重置为/ proc / sys / abi / sve_default_vector_length中配置的值。
PR_SVE_SET_VL_ONEXEC | PR_SVE_VL_INHERIT
推迟更改,以便在线程中的下一个execve(2)执行该更改。进一步的execve(2)调用将保留新的向量长度。
在所有情况下,所有先前未决的延迟更改都将被取消。
如果平台不支持SVE,arg2无法识别或无效,或者对应于PR_SVE_VL_LEN_MASK的arg2位中的值在SVE_VL_MIN..SVE_VL_MAX范围之外或不是16的整数倍,则调用将失败,并显示错误EINVAL。
成功后,将返回一个非负值,该值描述了所选的配置。如果arg2中包含PR_SVE_SET_VL_ONEXEC,则由返回值描述的配置将在下一个execve()处生效。否则,当PR_SVE_SET_VL调用返回时,该配置已经生效。无论哪种情况,该值都以与PR_SVE_GET_VL的返回值相同的方式进行编码。请注意,与PR_SVE_SET_VL_ONEXEC对应的返回值中没有显式标志。
配置(包括任何未决的延迟更改)在fork(2)和clone(2)之间继承。
有关更多信息,请参见内核源文件Documentation / arm64 / sve.rst(或Linux 5.3之前的Documentation / arm64 / sve.txt)。
警告:因为编译器或运行时环境可能正在使用SVE,所以在不带PR_SVE_SET_VL_ONEXEC标志的情况下使用此调用可能会使调用过程崩溃。安全使用它的条件是复杂的,并且取决于系统。除非您真的知道自己在做什么,否则不要使用它。
PR_SVE_GET_VL(since Linux 4.15, only on arm64)
获取线程的当前SVE向量长度配置。
参数arg2arg3,arg4和arg5被忽略。
如果内核和平台支持SVE,则此操作将始终成功,并返回描述当前配置的非负值。对应于PR_SVE_VL_LEN_MASK的位包含当前配置的向量长度(以字节为单位)。与PR_SVE_VL_INHERIT对应的位指示向量长度是否将在execve(2)中继承。
请注意,无法确定是否存在尚未生效的待处理向量长度更改。
有关更多信息,请参见内核源文件Documentation / arm64 / sve.rst(或Linux 5.3之前的Documentation / arm64 / sve.txt)。
PR_SET_TAGGED_ADDR_CTRL(since Linux 5.4, only on arm64)
控件支持将标记的用户空间地址传递到内核(即位56 --- 63并非全为零的地址)。
The level of support is selected by arg2,

which can be one of the following:

0
为了被内核取消引用而传递的地址必须未加标签。
PR_TAGGED_ADDR_ENABLE
可以标记为被内核取消引用而传递的地址,以下概述的例外情况。
其余参数arg3,arg4和arg5必须全部为零。
成功后,将为调用线程设置arg2中指定的模式,返回值为0。如果参数无效,则无法识别arg2中指定的模式,或者内核不支持此功能或通过/ proc /禁用此功能。 sys / abi / tagged_addr_disabled,调用失败,错误为EINVAL。
特别是,如果prctl(PR_SET_TAGGED_ADDR_CTRL,0,0,0,0)失败并显示EINVAL,则传递给内核的所有地址都必须取消标记。
Irrespective of which mode is set, addresses passed to certain interfaces must always be untagged:
*
brk(2),mmap(2),shmat(2),shmdt(2)和mremap(2)的new_address参数。
(在Linux 5.6之前,这些可接受的标记地址,但是行为可能并非您所期望的。不要依赖它。)
*
oqpolymorphiccq接口接受指向任意类型的指针,这些指针转换为void *或其他通用类型,特别是prctl(2),ioctl(2)以及一般而言的setsockopt(2)(仅某些特定的setsockopt(2)选项允许标记地址)。
从一个内核版本升级到更高内核版本时,此排除列表可能会缩小。尽管内核出于向后兼容性的原因可以做出一些保证,但是对于新软件而言,未指定将标记地址传递到这些接口的效果。
此调用设置的模式在fork(2)和clone(2)之间继承。 execve(2)将模式重置为0(即,用户/内核ABI中不允许使用标记的地址)。
有关更多信息,请参见内核源文件Documentation / arm64 / tagged-address-abi.rst。
警告:此调用主要供运行时环境使用。在其他地方成功执行PR_SET_TAGGED_ADDR_CTRL调用可能会使调用过程崩溃。安全使用它的条件是复杂的,并且取决于系统。除非您知道自己在做什么,否则不要使用它。
PR_GET_TAGGED_ADDR_CTRL(since Linux 5.4, only on arm64)
返回调用线程的当前标记地址模式。
参数arg2arg3,arg4和arg5必须全部为零。
如果参数无效,或者内核禁用或不支持此功能,则调用将失败,并显示EINVAL。特别是,如果prctl(PR_GET_TAGGED_ADDR_CTRL,0,0,0,0)失败并显示EINVAL,则肯定不支持此功能,或通过/ proc / sys / abi / tagged_addr_disabled禁用了此功能。在这种情况下,传递给内核的所有地址都必须未加标签。
否则,该调用将返回一个非负值,该值描述当前标记的地址模式,并以与PR_SET_TAGGED_ADDR_CTRL的arg2参数相同的方式进行编码。
有关更多信息,请参见内核源文件Documentation / arm64 / tagged-address-abi.rst。
PR_TASK_PERF_EVENTS_DISABLE(since Linux 2.6.31)
禁用所有附加到调用进程的性能计数器,而不管计数器是由该进程还是另一个进程创建的。调用进程为其他进程创建的性能计数器不受影响。有关性能计数器的更多信息,请参见Linux内核源文件tools / perf / design.txt。
最初称为PR_TASK_PERF_COUNTERS_DISABLE;在Linux 2.6.32中被重命名(保留相同的数值)。
PR_TASK_PERF_EVENTS_ENABLE(since Linux 2.6.31)
与PR_TASK_PERF_EVENTS_DISABLE相反;启用连接到调用过程的性能计数器。
最初称为PR_TASK_PERF_COUNTERS_ENABLE;在Linux 2.6.32中重命名。
PR_SET_THP_DISABLE(since Linux 3.15)
设置调用线程的" THP disable"标志的状态。如果arg2具有非零值,则设置标志,否则将其清除。设置此标志提供了一种方法,用于禁用无法修改代码的作业的透明大页面,并且不能将madvise(2)与malloc挂钩一起使用(即静态分配的数据)。 " THP disable"标志的设置由通过fork(2)创建的子代继承,并保留在execve(2)中。
PR_GET_THP_DISABLE(since Linux 3.15)
返回(作为函数结果)调用线程的" THP disable"标志的当前设置:如果设置了该标志,则为1,否则为0。
PR_GET_TID_ADDRESS(since Linux 3.5)
在(int **)arg2指向的位置返回由set_tid_address(2)和clone(2)CLONE_CHILD_CLEARTID标志设置的clear_child_tid地址。只有在启用CONFIG_CHECKPOINT_RESTORE选项的情况下构建内核时,此功能才可用。请注意,由于prctl()系统调用没有针对AMD64 x32和MIPS n32 ABI的compat实现,并且内核使用内核的指针大小写出了指针,因此该操作期望用户空间缓冲区为8(而不是4)。 )字节在这些ABI上。
PR_SET_TIMERSLACK(since Linux 2.6.28)
每个线程都有两个关联的计时器松弛值:"默认"值和"当前"值。此操作为调用线程设置"当前"计时器松弛值。 arg2是无符号长值,则最大"当前"值为ULONG_MAX,最小"当前"值为1。如果arg2中提供的纳秒值大于零,则将"当前"值设置为该值。如果arg2等于零,则将"当前"计时器松弛度重置为线程的"默认"计时器松弛度值。
内核使用"当前"定时器余量来将调用线程的定时器到期时间彼此接近的分组。因此,线程的计时器到期时间可能最多延迟指定的纳秒数(但永远不会提前到期)。对计时器到期时间进行分组可以通过最大程度地减少CPU唤醒来帮助降低系统功耗。
受计时器松弛影响的计时器到期时间是由select(2),pselect(2),poll(2),ppoll(2),epoll_wait(2),epoll_pwait(2),clock_nanosleep(2),nanosleep(2)设置的,以及futex(2)(以及因此通过futexes实现的库函数,包括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)(所有进程的祖先)的计时器松弛度值为50,000纳秒(50微秒)。计时器松弛值由通过fork(2)创建的子级继承,并在execve(2)中保留。
从Linux 4.6开始,可以通过文件/ proc / [pid] / timerslack_ns检查和更改任何进程的"当前"计时器延迟值。参见proc(5)。
PR_GET_TIMERSLACK(since Linux 2.6.28)
返回(作为函数结果)调用线程的"当前"计时器松弛值。
PR_SET_TIMING(since Linux 2.6.0)
通过将PR_TIMING_STATISTICAL或PR_TIMING_TIMESTAMP传递给arg2,设置是使用(常规的,传统的)统计过程计时还是基于精确时间戳的过程计时。 PR_TIMING_TIMESTAMP当前未实现(尝试设置此模式将产生错误EINVAL)。
PR_GET_TIMING(since Linux 2.6.0)
返回(作为函数结果)当前正在使用的处理计时方法。
PR_SET_TSC(since Linux 2.6.26, x86 only)
设置标志的状态,以确定该进程是否可以读取时间戳计数器。当进程尝试读取时间戳计数器时,将PR_TSC_ENABLE传递给arg2以使其可以被读取,或者将PR_TSC_SIGSEGV传递给SIGSEGV。
PR_GET_TSC(since Linux 2.6.26, x86 only)
在(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起;磁贴,自Linux 3.12起)将未对齐的访问控制位设置为arg2。传递PR_UNALIGN_NOPRINT可以静默修复未对齐的用户访问,传递PR_UNALIGN_SIGBUS可以生成未对齐的用户访问的SIGBUS。 Alpha还支持值为4且没有相应的命名常量的附加标志,该标志指示内核不要修复未对齐的访问(类似于在Tru64上setsysinfo()系统调用的SSI_NVPAIRS操作中提供UAC_NOFIX标志)。
PR_GET_UNALIGN
(有关版本和体系结构的信息,请参见PR_SET_UNALIGN。)返回由(unsigned int *)arg2指向的位置中未对齐的访问控制位。

返回值

上的成功,PR_CAP_AMBIENT + PR_CAP_AMBIENT_IS_SETPR_CAPBSET_READPR_GET_DUMPABLEPR_GET_FP_MODEPR_GET_IO_FLUSHERPR_GET_KEEPCAPSPR_MCE_KILL_GETPR_GET_NO_NEW_PRIVSPR_GET_SECUREBITSPR_GET_SPECULATION_CTRLPR_SVE_GET_VLPR_SVE_SET_VLPR_GET_TAGGED_ADDR_CTRLPR_GET_THP_DISABLEPR_GET_TIMINGPR_GET_TIMERSLACK,和(如果它返回)PR_GET_SECCOMP返回上述的非负值。所有其他选项值成功返回0。如果出错,则返回-1,并正确设置errno。

错误说明

EACCES
选项是PR_SET_SECCOMP,而arg2是SECCOMP_MODE_FILTER,但是该进程不具有CAP_SYS_ADMIN功能或未设置no_new_privs属性(请参见上面对PR_SET_NO_NEW_PRIVS的讨论)。
EACCES
选项是PR_SET_MM,而arg3是PR_SET_MM_EXE_FILE,该文件不可执行。
EBADF
选项是PR_SET_MM,arg3是PR_SET_MM_EXE_FILE,并且在arg4中传递的文件描述符无效。
EBUSY
选项是PR_SET_MM,arg3是PR_SET_MM_EXE_FILE,这是第二次尝试更改/ proc / pid / exe符号链接的尝试,这是禁止的。
EFAULT
arg2是无效的地址。
EFAULT
选项是PR_SET_SECCOMP,arg2是SECCOMP_MODE_FILTER,系统是使用CONFIG_SECCOMP_FILTER构建的,而arg3是无效地址。
EINVAL
option的值无法识别,或在此系统上不受支持。
EINVAL
选项是PR_MCE_KILL或PR_MCE_KILL_GET或PR_SET_MM,未使用的prctl()参数未指定为零。
EINVAL
arg2对于该选项无效。
EINVAL
选项是PR_SET_SECCOMP或PR_GET_SECCOMP,并且内核未配置CONFIG_SECCOMP。
EINVAL
选项是PR_SET_SECCOMP,arg2是SECCOMP_MODE_FILTER,并且内核未配置CONFIG_SECCOMP_FILTER。
EINVAL
option

is
PR_SET_MM,

and one of the following is true

*
arg4或arg5不为零;
*
arg3大于TASK_SIZE(此体系结构的用户地址空间大小的限制);
*
arg2是PR_SET_MM_START_CODEPR_SET_MM_END_CODEPR_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
选项是PR_SET_PTRACER并且arg2不为0,PR_SET_PTRACER_ANY或现有进程的PID。
EINVAL
选项是PR_SET_PDEATHSIG,而arg2不是有效的信号编号。
EINVAL
选项是PR_SET_DUMPABLE,而arg2既不是SUID_DUMP_DISABLE也不是SUID_DUMP_USER。
EINVAL
选项是PR_SET_TIMING,而arg2不是PR_TIMING_STATISTICAL。
EINVAL
选项是PR_SET_NO_NEW_PRIVS,并且arg2不等于1或arg3,arg4或arg5不为零。
EINVAL
选项为PR_GET_NO_NEW_PRIVS,而arg2arg3,arg4或arg5为非零。
EINVAL
选项是PR_SET_THP_DISABLE,并且arg3,arg4或arg5不为零。
EINVAL
选项是PR_GET_THP_DISABLE,并且arg2arg3,arg4或arg5不为零。
EINVAL
选项为PR_CAP_AMBIENT,未使用的参数(arg4arg5,或者,对于PR_CAP_AMBIENT_CLEAR_ALL,为arg3)为非零;或arg2的值无效;或arg2为PR_CAP_AMBIENT_LOWER,PR_CAP_AMBIENT_RAISE或PR_CAP_AMBIENT_IS_SET,而arg3未指定有效功能。
EINVAL
选项是PR_GET_SPECULATION_CTRL或PR_SET_SPECULATION_CTRL,并且prctl()的未使用参数不为0。EINVAL选项为PR_PAC_RESET_KEYS,并且参数无效或不受支持。有关详细信息,请参见上面的PR_PAC_RESET_KEYS的描述。
EINVAL
选项是PR_SVE_SET_VL,并且参数无效或不受支持,或者此平台上不提供SVE。有关详细信息,请参见上面的PR_SVE_SET_VL的描述。
EINVAL
选项是PR_SVE_GET_VL,SVE在此平台上不可用。
EINVAL
选项是PR_SET_TAGGED_ADDR_CTRL,参数无效或不受支持。有关详细信息,请参见上面的PR_SET_TAGGED_ADDR_CTRL的描述。
EINVAL
选项是PR_GET_TAGGED_ADDR_CTRL,参数无效或不受支持。有关详细信息,请参见上面的PR_GET_TAGGED_ADDR_CTRL的描述。
ENODEV
选项是PR_SET_SPECULATION_CTRL,则内核或CPU不支持请求的推测错误功能。
ENXIO
选项是PR_MPX_ENABLE_MANAGEMENT或PR_MPX_DISABLE_MANAGEMENT,并且内核或CPU不支持MPX管理。检查内核和处理器是否支持MPX。
ENXIO
选项PR_SET_SPECULATION_CTRL表示无法控制所选的推测功能。有关位字段,请参见PR_GET_SPECULATION_CTRL,以确定哪个选项可用。
EOPNOTSUPP
选项是PR_SET_FP_MODE,而arg2的值无效或不受支持。
EPERM
选项是PR_SET_SECUREBITS,并且调用者不具有CAP_SETPCAP功能,或者试图取消设置"锁定"标志,或者试图设置已设置了相应锁定标志的标志(请参阅功能(7))。
EPERM
选项是PR_SET_SPECULATION_CTRL,其中使用PR_SPEC_FORCE_DISABLE禁用了推测,并且调用方尝试再次启用它。
EPERM
选项是PR_SET_KEEPCAPS,并且设置了呼叫者的SECBIT_KEEP_CAPS_LOCKED标志(请参阅功能(7))。
EPERM
选项是PR_CAPBSET_DROP,并且调用者没有CAP_SETPCAP功能。
EPERM
选项是PR_SET_MM,并且调用者没有CAP_SYS_RESOURCE功能。
EPERM
选项是PR_CAP_AMBIENT,而arg2是PR_CAP_AMBIENT_RAISE,但是arg3中指定的功能在进程的允许和可继承功能集中不存在,或者已设置PR_CAP_AMBIENT_LOWER安全位。
ERANGE
选项是PR_SET_SPECULATION_CTRL,而arg3不是PR_SPEC_ENABLEPR_SPEC_DISABLE,PR_SPEC_FORCE_DISABLE或PR_SPEC_DISABLE_NOEXEC。

版本

在Linux 2.1.57中引入了prctl()系统调用。

遵循规范

该调用是特定于Linux的。 IRIX有一个prctl()系统调用(也在Linux 2.1.44中作为MIPS架构上的irix_prctl引入),带有原型

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

以及用于获取每个用户的最大进程数,获取调用进程可以使用的最大处理器数,找出当前是否阻止了指定进程,获取或设置最大堆栈大小的选项,等等。

另外参见

信号(2),核心(5)

出版信息

这个页面是Linux手册页项目5.08版的一部分。有关项目的说明、有关报告错误的信息以及此页面的最新版本,请访问https://www.kernel.org/doc/man-pages/