Commit 445a91d2fe3667fb8fc251433645f686933cf56a
Committed by
Linus Torvalds
1 parent
35de254dc6
Exists in
master
and in
7 other branches
tracehook: tracehook_consider_fatal_signal
This defines tracehook_consider_fatal_signal() has a fine-grained hook for deciding to skip the special cases for a fatal signal, as ptrace does. There is no change, only cleanup. Signed-off-by: Roland McGrath <roland@redhat.com> Cc: Oleg Nesterov <oleg@tv-sign.ru> Reviewed-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Showing 2 changed files with 26 additions and 4 deletions Side-by-side Diff
include/linux/tracehook.h
... | ... | @@ -331,5 +331,26 @@ |
331 | 331 | return (task_ptrace(task) & PT_PTRACED) != 0; |
332 | 332 | } |
333 | 333 | |
334 | +/** | |
335 | + * tracehook_consider_fatal_signal - suppress special handling of fatal signal | |
336 | + * @task: task receiving the signal | |
337 | + * @sig: signal number being sent | |
338 | + * @handler: %SIG_DFL or %SIG_IGN | |
339 | + * | |
340 | + * Return nonzero to prevent special handling of this termination signal. | |
341 | + * Normally @handler is %SIG_DFL. It can be %SIG_IGN if @sig is ignored, | |
342 | + * in which case force_sig() is about to reset it to %SIG_DFL. | |
343 | + * When this returns zero, this signal might cause a quick termination | |
344 | + * that does not give the debugger a chance to intercept the signal. | |
345 | + * | |
346 | + * Called with or without @task->sighand->siglock held. | |
347 | + */ | |
348 | +static inline int tracehook_consider_fatal_signal(struct task_struct *task, | |
349 | + int sig, | |
350 | + void __user *handler) | |
351 | +{ | |
352 | + return (task_ptrace(task) & PT_PTRACED) != 0; | |
353 | +} | |
354 | + | |
334 | 355 | #endif /* <linux/tracehook.h> */ |
kernel/signal.c
... | ... | @@ -300,12 +300,12 @@ |
300 | 300 | |
301 | 301 | int unhandled_signal(struct task_struct *tsk, int sig) |
302 | 302 | { |
303 | + void __user *handler = tsk->sighand->action[sig-1].sa.sa_handler; | |
303 | 304 | if (is_global_init(tsk)) |
304 | 305 | return 1; |
305 | - if (tsk->ptrace & PT_PTRACED) | |
306 | + if (handler != SIG_IGN && handler != SIG_DFL) | |
306 | 307 | return 0; |
307 | - return (tsk->sighand->action[sig-1].sa.sa_handler == SIG_IGN) || | |
308 | - (tsk->sighand->action[sig-1].sa.sa_handler == SIG_DFL); | |
308 | + return !tracehook_consider_fatal_signal(tsk, sig, handler); | |
309 | 309 | } |
310 | 310 | |
311 | 311 | |
... | ... | @@ -761,7 +761,8 @@ |
761 | 761 | if (sig_fatal(p, sig) && |
762 | 762 | !(signal->flags & (SIGNAL_UNKILLABLE | SIGNAL_GROUP_EXIT)) && |
763 | 763 | !sigismember(&t->real_blocked, sig) && |
764 | - (sig == SIGKILL || !(t->ptrace & PT_PTRACED))) { | |
764 | + (sig == SIGKILL || | |
765 | + !tracehook_consider_fatal_signal(t, sig, SIG_DFL))) { | |
765 | 766 | /* |
766 | 767 | * This signal will be fatal to the whole group. |
767 | 768 | */ |