An autrace that follows forks

John D. Ramsdell ramsdell at mitre.org
Sun Oct 15 15:38:16 UTC 2006


ramsdell at mitre.org (John D. Ramsdell) writes:

> The tricky part seems to be that the SIGTRAP generated by the
> parent's immediate child has to be converted to a SIGSTOP before
> continuing the child.

If you trace a shell, you find out you must always convert a SIGTRAP
to a SIGSTOP.

John

> static int			/* Watch all children */
> watch(pid_t pid)		/* This process' child is pid  */
> {				/* Function returns an exit code */
>   if (add_rule(pid))
>     return 1;
>   for (;;) {
>     int status;
>     pid = wait_for_it(&status);
>     if (pid < 0) {
>       if (errno == ECHILD)	/* No children to wait for */
> 	return 0;		/* Declare success */
>       perror("wait");
>       return 1;
>     }
>     if (WIFSTOPPED(status)) {
>       int signal = WSTOPSIG(status);
>       if (signal == SIGTRAP) {	/* Tracing causes this signal */
        signal = SIGSTOP;
> 	unsigned long msg;
> 	if (geteventmsg(pid, &msg) < 0) {
> 	  perror("ptrace(PTRACE_GETEVENTMSG, ...)");
> 	  return 1;
> 	}
> 	pid_t child = (pid_t)msg;
> 	if (child) {
> 	  /* The child of each traced fork is noted here */
> 	  if (add_rule(child))
> 	    return 1;
> 	}
> 	/* Only this process' child gets to this location, and just
> 	   one time */
> 	else if (setoptions(pid, PTRACE_O_TRACEFORK) < 0) {
> 	  perror("ptrace(PTRACE_SETOPTIONS, ...)");
> 	  return 1;
> 	}
 	/* Wrong
>       else
> 	  signal = SIGSTOP;
        */
>       }
>       if (restart(pid, signal) < 0) {
> 	perror("ptrace(PTRACE_CONT, ...)");
> 	return 1;
>       }
>     }
>   }
> }




More information about the Linux-audit mailing list