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