如何通过 ptrace 设置 child`s errno?

How to set child`s errno by ptrace?

我正在尝试通过 ptrace 拦截和阻止系统调用。问题发生在系统调用结果的 return 期间。 errno 保持为 0,即使在系统调用 return.

中使用 -EPERM

我试过 运行 这个 EXAMPLE。结果是一样的。

$ ./xpledge ./example
fread("/dev/urandom")[1] = 0xb2ac39c4
XPledging...
fopen("/dev/urandom")[2]: Success
fread("/dev/urandom")[1] = 0x2e1bd1c4

部分代码如下:

if (is_syscall_blocked(regs.orig_rax)) {
  regs.orig_rax = -1; // set to invalid system call
  if (ptrace(PTRACE_SETREGS, pid, 0, &regs) == -1)
    FATAL("%s", strerror(errno));
}

/* Run system call and stop on exit */
if (ptrace(PTRACE_SYSCALL, pid, 0, 0) == -1)
  FATAL("%s", strerror(errno));
if (waitpid(pid, 0, 0) == -1)
  FATAL("%s", strerror(errno));

switch (regs.orig_rax) {
case -1:
  if (ptrace(PTRACE_POKEUSER, pid, RAX * 8, -EPERM) == -1)
    FATAL("%s", strerror(errno));
  break;
}

那么问题来了。拒绝系统调用时如何正确设置errno?

实际上示例中的代码看起来并不正确。在本教程中有一些不相同的代码片段。如果你尝试一下,它似乎提供了正确的输出

switch (regs.orig_rax) {
    case -1:
        regs.rax = -E2BIG;
        if (ptrace(PTRACE_SETREGS, pid, 0, &regs) == -1)
            FATAL("%s", strerror(errno));
        break;