FEXECVE - Linux手册页
Linux程序员手册 第3部分
更新日期: 2019-10-10
名称
fexecve-执行通过文件描述符指定的程序
语法
#include <unistd.h> int fexecve(int fd, char *const argv[], char *const envp[]);
glibc的功能测试宏要求(请参阅feature_test_macros(7)):
fexecve():
- Since glibc 2.10:
- _POSIX_C_SOURCE>= 200809L
- Before glibc 2.10:
- _GNU_SOURCE
说明
fexecve()与execve(2)执行相同的任务,不同之处在于,要执行的文件是通过文件描述符fd而不是路径名指定的。文件描述符fd必须以只读(O_RDONLY)或带有O_PATH标志打开,并且调用者必须有权执行它所引用的文件。
返回值
成功调用fexecve()永远不会返回。出错时,函数将返回,结果值为-1,并正确设置了errno。
错误说明
错误与execve(2)相同,但有以下补充:
- EINVAL
- fd不是有效的文件描述符,或者argv是NULL,或者envp是NULL。
- ENOENT
- 在fd上设置close-on-exec标志,fd引用脚本。参见错误。
- ENOSYS
- 内核不提供execveat(2)系统调用,并且/ proc文件系统无法访问。
版本
从glibc 2.3.2开始实施fexecve()。
属性
有关本节中使用的术语的说明,请参见attribute(7)。
Interface | Attribute | Value |
fexecve() | Thread safety | MT-Safe |
遵循规范
POSIX.1-2008。 POSIX.1-2001中未指定此功能,并且在其他系统上未广泛使用。在POSIX.1-2008中指定。
备注
在具有glibc 2.26和更早版本的Linux上,fexecve()是使用proc(5)文件系统实现的,因此/ proc需要在调用时挂载并可用。从glibc 2.27开始,如果底层内核支持execveat(2)系统调用,则使用该系统调用实现fexecve(),无需安装/ proc。
fexecve()的思想是允许调用者在执行可执行文件之前对其进行校验(校验和)。简单地打开文件,对内容进行校验和,然后执行execve(2)是不够的,因为在两个步骤之间,可能已经交换了文件名或路径名的目录前缀(例如,通过修改符号链接的目标)。 fexecve()不能缓解在校验和与对fexecve()的调用之间可以更改文件内容的问题;为此,解决方案是确保文件的权限防止恶意用户对其进行修改。
使用fexecve()时的自然习惯是在fd上设置执行时关闭标志,以便文件描述符不会泄漏到执行的程序中。这种方法很自然,原因有二。首先,它防止不必要地使用文件描述符。 (执行的程序通常不需要引用程序本身的文件描述符。)其次,如果递归使用fexecve(),则使用close-on-exec标志可以防止由于以下事实而导致文件描述符耗尽:递归的每一步都将导致一个文件描述符传递给新程序。 (但请参阅错误。)
BUGS
如果fd引用脚本(即,这是一个可执行文本文件,其脚本脚本解释器的第一行以字符#!开头),并且已为fd设置了close-on-exec标志,则fexecve()失败,并显示错误ENOENT。发生此错误的原因是,在执行脚本解释器时,由于close-on-exec标志,fd已经关闭。因此,如果fd引用了脚本,则无法在fd上设置close-on-exec标志,这会导致NOTES中描述的问题。
出版信息
这个页面是Linux手册页项目5.08版的一部分。有关项目的说明、有关报告错误的信息以及此页面的最新版本,请访问https://www.kernel.org/doc/man-pages/。