[2.6.26 PATCH] BZ#469684 utrace: make sure utrace_report_syscall_entry() can't lose TIF_SIGPENDING
Oleg Nesterov
oleg at redhat.com
Mon Dec 1 00:56:11 UTC 2008
(apologies to all, re-send to fedora-kernel-list at redhat.com)
(the patch targets 2.6.26 fedora kernels, don't know what should be
in SUBJECT).
See https://bugzilla.redhat.com/show_bug.cgi?id=469684
utrace_report_syscall_entry() must recalc_sigpending() unconditionally.
While we slept in TASK_TRACED the new signals can be queued, but in that
case TIF_SIGPENDING is not set. See the (correct) task_is_stopped_or_traced()
check in wants_signal().
Signed-off-by: Oleg Nesterov <oleg at redhat.com>
--- linux-2.6.26.x86_64/kernel/utrace.c~UTRACE_SIGLOST 2008-10-09 17:47:14.000000000 +0200
+++ linux-2.6.26.x86_64/kernel/utrace.c 2008-11-30 23:15:33.000000000 +0100
@@ -1383,20 +1383,21 @@ bool utrace_report_syscall_entry(struct
if (unlikely(report.result == UTRACE_SYSCALL_ABORT))
return true;
- if (signal_pending(task)) {
- /*
- * Clear TIF_SIGPENDING if it no longer needs to be set.
- * It may have been set as part of quiescence, and won't
- * ever have been cleared by another thread. For other
- * reports, we can just leave it set and will go through
- * utrace_get_signal() to reset things. But here we are
- * about to enter a syscall, which might bail out with an
- * -ERESTART* error if it's set now.
- */
- spin_lock_irq(&task->sighand->siglock);
- recalc_sigpending();
- spin_unlock_irq(&task->sighand->siglock);
- }
+ /*
+ * Clear TIF_SIGPENDING if it no longer needs to be set.
+ * It may have been set as part of quiescence, and won't
+ * ever have been cleared by another thread. For other
+ * reports, we can just leave it set and will go through
+ * utrace_get_signal() to reset things. But here we are
+ * about to enter a syscall, which might bail out with an
+ * -ERESTART* error if it's set now.
+ *
+ * Or, set TIF_SIGPENDING if the signal was queued while
+ * we were stopped in TASK_TRACED.
+ */
+ spin_lock_irq(&task->sighand->siglock);
+ recalc_sigpending();
+ spin_unlock_irq(&task->sighand->siglock);
return false;
}
More information about the Fedora-kernel-list
mailing list