1. execve

execve - 执行程序

1.1. 总览

#include <unistd.h>
int execve (const char *filename, char *const argv [], char *const envp[]);
execve("./a.sh", ["./a.sh"], [/* 25 vars */]) = -1 EACCES (Permission denied)

1.2. 描述 (DESCRIPTION)

execve()执行filename指出的程序。filename必须是二进制可执行文件, 或者以#! interpreter [arg]行开始的脚本文件。后者的 interpreter必须是某个可执行文件的有效路径, 这个可执行文件自身不能是脚本程序, 调用形式是 interpreter [arg] filename.

execve()调用成功后不会返回, 其进程的正文(text), 数据(data), bss和堆栈(stack)段被调入程序覆盖. 调入程序继承了调用程序的 PID和所有打开的文件描述符, 他们不会因为exec过程而关闭。父进程的未决信号被清除. 所有被调用进程设置过的信号重置为缺省行为。

如果当前程序正在被ptrace跟踪, 成功的调用execve()后将收到一个 SIGTRAP信号.

如果可执行文件是动态连接的a.out二进制程序, 含有共享库的 stub, 开始执行程序的时候, Linux动态连接器(linker)ld.so(8) 把所需的共享库调入核心, 并且和程序相连.

如果可执行文件是动态连接的ELF二进制程序, 定义在PT_INTERP字段 的解释器(interpreter) 调入所需的共享库. 连接libc5的程序的 典型解释器是/lib/ld-linux.so.1, 而连接GNU libc2 (libc6) 的程序则为 /lib/ld-linux.so.2.

1.3. 返回值 (RETURN VALUE)

调用成功的时候 execve()不会返回, 调用失败时返回 -1, 并设置 errno为相应的值.

1.4. 错误 (ERRORS)

EACCES : 文件或脚本解释器不正确. EACCES : 没有文件或脚本解释器的执行权限. EACCES : 文件系统挂载(mount)为noexec. EPERM : 文件系统挂载为nosuid, 使用者不是超级用户, 以及 文件设置了SUID或SGID位. EPERM : 进程正被跟踪, 使用者不是超级用户, 以及文件设置了SUID或SGID位. E2BIG : 参数列表过长. ENOEXEC : 可执行文件的文件格式无法识别, 误用在不同的 体系结构, 或者其他格式错误导致程序无法执行. EFAULT : filename指针超出可访问的地址空间. ENAMETOOLONG : filename 太长. ENOENT : filename , 脚本解释器, 或ELF解释器不存在. ENOMEM : 内核空间不足. ENOTDIR : 在filename , 脚本解释器或ELF解释器的前缀 路径中, 某些成员不是目录. EACCES : 在 filename或脚本解释器的前缀路径中, 对某些 目录没有访问许可. ELOOP : 解析 filename , 脚本解释器 或 ELF 解释器 时 遇到 过多的 符号连接. ETXTBUSY : 可执行文件 被 一个 或 多个 进程 以 写方式 打开. EIO : 发生 I/O 错误. ENFILE : 达到 系统 定义的 同时打开文件数 限制. EMFILE : 进程 打开了 最大数量 的 文件. EINVAL : 该 ELF 可执行文件 拥有 多个 PT_INTERP 字段 (就是说, 试图 定义 多个 解释器). EISDIRELF : 解释器 是 目录. ELIBBAD : 无法 识别 ELF 解释器 的 格式.

1.5. 兼容

SVr4, SVID, X/OPEN, BSD 4.3. POSIX 没有 对 #! 行为 的 文档, 但有 其他的 兼容 形式. SVr4 记录了 额外的 错误情况 EAGAIN, EINTR, ELIBACC, ENOLINK, EMULTIHOP; POSIX 没有 关于 ETXTBSY, EPERM, EFAULT, ELOOP, EIO, ENFILE, EMFILE, EINVAL, EISDIR 或 ELIBBAD 错误情况 的 文档.

1.6. 注意 (NOTES)

SUID and SGID processes can not be ptrace()d SUID or SGID. 在 #! 格式的 shell 可执行脚本 中, 第一行 的 长度 不得 超过 127 字节.

Linux 忽略 脚本程序 的 SUID 和 SGID 位.

1.7. 另见 (SEE ALSO)

ld.so(8), execl(3), fork(2)

Copyright © 温玉 2021 | 浙ICP备2020032454号 all right reserved,powered by Gitbook该文件修订时间: 2023-06-19 08:59:50

results matching ""

    No results matching ""