Thanks, Oleg. Seems like this would be a nice change to have. As we can see, people do use ptrace() as a security technology. With this in place, you can also (where possible) set up the tracee with PR_SET_PDEATHSIG==SIGKILL. And then, you have defences again either of the tracer or tracee dying from a stray SIGKILL. On Wed, Jan 18, 2012 at 9:12 AM, Oleg Nesterov <oleg@xxxxxxxxxx> wrote: > On 01/18, Oleg Nesterov wrote: >> >> On 01/17, Chris Evans wrote: >> > >> > 1) Tracee is compromised; executes fork() which is syscall that isn't allowed >> > 2) Tracee traps >> > 2b) Tracee could take a SIGKILL here >> > 3) Tracer looks at registers; bad syscall >> > 3b) Or tracee could take a SIGKILL here >> > 4) The only way to stop the bad syscall from executing is to rewrite >> > orig_eax (PTRACE_CONT + SIGKILL only kills the process after the >> > syscall has finished) >> > 5) Disaster: the tracee took a SIGKILL so any attempt to address it by >> > pid (such as PTRACE_SETREGS) fails. >> > 6) Syscall fork() executes; possible unsupervised process now running >> > since the tracer wasn't expecting the fork() to be allowed. >> >> As for fork() in particular, it can't succeed after SIGKILL. >> >> But I agree, probably it makes sense to change ptrace_stop() to check >> fatal_signal_pending() and do do_group_exit(SIGKILL) after it sleeps >> in TASK_TRACED. Or we can change tracehook_report_syscall_entry() >> >> - return 0; >> + return !fatal_signal_pending(); >> >> (no, I do not literally mean the change above) >> >> Not only for security. The current behaviour sometime confuses the >> users. Debugger sends SIGKILL to the tracee and assumes it should >> die asap, but the tracee exits only after syscall. > > Something like the patch below. > > Oleg. > > --- x/include/linux/tracehook.h > +++ x/include/linux/tracehook.h > @@ -54,12 +54,12 @@ struct linux_binprm; > /* > * ptrace report for syscall entry and exit looks identical. > */ > -static inline void ptrace_report_syscall(struct pt_regs *regs) > +static inline int ptrace_report_syscall(struct pt_regs *regs) > { > int ptrace = current->ptrace; > > if (!(ptrace & PT_PTRACED)) > - return; > + return 0; > > ptrace_notify(SIGTRAP | ((ptrace & PT_TRACESYSGOOD) ? 0x80 : 0)); > > @@ -72,6 +72,8 @@ static inline void ptrace_report_syscall > send_sig(current->exit_code, current, 1); > current->exit_code = 0; > } > + > + return fatal_signal_pending(current); > } > > /** > @@ -96,8 +98,7 @@ static inline void ptrace_report_syscall > static inline __must_check int tracehook_report_syscall_entry( > struct pt_regs *regs) > { > - ptrace_report_syscall(regs); > - return 0; > + return ptrace_report_syscall(regs); > } > > /** > -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html