Messages in this thread Patch in this message | | | From | Kyle Huey <> | Subject | [PATCH] seccomp: suppress fatal signals that will never be delivered before seccomp forces an exit because of said signals | Date | Wed, 10 Aug 2016 12:50:57 -0700 |
| |
This fixes rr. It doesn't quite fix the provided testcase, because the testcase fails to wait on the tracee after awakening from the nanosleep. Instead the testcase immediately does a PTHREAD_CONT, discarding the PTHREAD_EVENT_EXIT. The slightly modified testcase at https://gist.github.com/khuey/3c43ac247c72cef8c956c does pass.
I don't see any obvious way to dequeue only the fatal signal, so instead I dequeue them all. Since none of these signals will ever be delivered it shouldn't affect the executing task.
Suggested-by: Robert O'Callahan <robert@ocallahan.org> Signed-off-by: Kyle Huey <khuey@kylehuey.com> --- kernel/seccomp.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/kernel/seccomp.c b/kernel/seccomp.c index ef6c6c3..728074d 100644 --- a/kernel/seccomp.c +++ b/kernel/seccomp.c @@ -609,8 +609,20 @@ static int __seccomp_filter(int this_syscall, const struct seccomp_data *sd, * Terminating the task now avoids executing a system * call that may not be intended. */ - if (fatal_signal_pending(current)) + if (fatal_signal_pending(current)) { + /* + * Swallow the signals we will never deliver. + * If we do not do this, the PTRACE_EVENT_EXIT will + * be suppressed by those signals. + */ + siginfo_t info; + + spin_lock_irq(¤t->sighand->siglock); + while (dequeue_signal(current, ¤t->blocked, &info)); + spin_unlock_irq(¤t->sighand->siglock); + do_exit(SIGSYS); + } /* Check if the tracer forced the syscall to be skipped. */ this_syscall = syscall_get_nr(current, task_pt_regs(current)); if (this_syscall < 0) -- 2.7.4
| |