Trouble with ptrace and process::Command::spawn


#1

Hi all,

I’m pushing the boundaries of process on linux, in trying to port my bigbro libray to rust. I thought everything would work beautifully with the before_exec method, which would allow me to leverage the whole (and nice) process::Command code, rather than writing my own fork+chdir+setenv+redirect stderr/stdout+exec code as I did in the C version of bigbro.

Sadly, I’m finding that spawn does not return, when before_exec has the following © function:

void bigbro_before_exec(void) {
  if (ptrace(PTRACE_TRACEME)) {
    fprintf(stderr,
            "Unable to trace child process, perhaps seccomp too strict?!\n");
  } else {
    kill(getpid(), SIGSTOP);
  }
}

I believe the problem arises because process::Command::spawn is very clever and uses a CLOEXEC pipe to communicate that the execvp has succeeded by its very closing. The trouble being that in order to ptrace my process and not miss anything, I need to stop it prior to setting up the tracing from the tracer’s end, which means that the pipe is never closed, and I never get to call ptrace(PTRACE_SETOPTIONS,...) and then more importantly ptrace(PTRACE_SYSCALL,...) which is needed to get the process running again.

Perhaps this just means I can’t use process after all. I had hoped to avoid duplicating the API and the nice handling of configuration (arguments, environment, stderr/out, etc). Any suggestions as to how I might get around this? I don’t know of any way to reliably ptrace without SIGSTOPping the process prior to exec, and I can’t see how to do that while reusing the process:::Command code. :frowning:

If it’s helpful, my code is on github.