Thanks for helping out to dissect this! Much appreciated!
Thomas Gleixner tglx@linutronix.de writes:
Let me look at your failure analysis from your first reply:
strace "tracing": Requires that regs->a0 is not tampered with prior ptrace notification
E.g.: | # ./strace / | execve("/", ["/"], 0x7ffffaac3890 /* 21 vars */) = -1 EACCES (Permission denied) | ./strace: exec: Permission denied | +++ exited with 1 +++ | # ./disable_ptrace_get_syscall_info ./strace / | execve(0xffffffffffffffda, ["/"], 0x7fffd893ce10 /* 21 vars */) = -1 EACCES (Permission denied) | ./strace: exec: Permission denied | +++ exited with 1 +++
In the second case, arg0 is prematurely set to -ENOSYS (0xffffffffffffffda).
That's expected if ptrace_get_syscall_info() is not used. Plain dumping registers will give you the current value on all architectures. ptrace_get_syscall_info() exist exactly for that reason.
Noted! So this shouldn't be considered as a regression. IOW, the existing upstream code is OK for this scenario.
strace "syscall tampering": Requires that ENOSYS is returned for syscall(-1), and not skipped w/o a proper return value.
E.g.: | ./strace -a0 -ewrite -einject=write:error=enospc echo helloject=write:error=enospc echo hello
Here, strace expects that injecting -1, would result in a ENOSYS.
No. It expects ENOSPC with the above command line. man strace:
If :error=errno option is specified, a fault is injected into a syscall invocation: the syscall number is replaced by -1 which corresponds to an invalid syscall (unless a syscall is specified with :syscall= option), and the error code is specified using a symbolic errno value like ENOSYS or a numeric value within 1..4095 range.
Similar for -einject:retval=$N
So you cannot overwrite a0 with ENOSYS if the syscall needs to be skipped.
ACK!