I am trying to intercept and block system calls via ptrace. The problem occurs during the return of the syscall result. errno stays 0, even with -EPERM in the syscall return.
I have tried running this EXAMPLE. The result is the same.
$ ./xpledge ./example
fread("/dev/urandom")[1] = 0xb2ac39c4
XPledging...
fopen("/dev/urandom")[2]: Success
fread("/dev/urandom")[1] = 0x2e1bd1c4
Here's part of the code:
if (is_syscall_blocked(regs.orig_rax)) {
regs.orig_rax = -1; // set to invalid system call
if (ptrace(PTRACE_SETREGS, pid, 0, ®s) == -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;
}
So the question is. How to set errno correctly when rejecting a system call?
CodePudding user response:
Actually the codes in the example do not look correct. In the tutorial there are code pieces which are not same. if you try it, seems it provides the correct output
switch (regs.orig_rax) {
case -1:
regs.rax = -E2BIG;
if (ptrace(PTRACE_SETREGS, pid, 0, ®s) == -1)
FATAL("%s", strerror(errno));
break;