Fix sys32_rt_sigtimedwait
The copy of this logic in arch/mips/ has gotten out of sync with the copy in kernel/ - fatally so. Because it doesn't set real_blocked, sigwaiting for a blocked but otherwise fatal signal may cause the thread group to exit.
Signed-off-by Daniel Jacobowitz <[email protected]>
arch/mips/kernel/signal32.c +18 -14
@@ -948,25 +948,29 @@spin_lock_irq (¤t->sighand->siglock); sig =dequeue_signal (current, &these, &info);if (!sig) { -/* None ready -- temporarily unblock those we're interested -in so that we'll be awakened when they arrive. */ -sigset_t oldblocked = current->blocked; -sigandsets (¤t->blocked, ¤t->blocked, &these); -recalc_sigpending (); -spin_unlock_irq (¤t->sighand->siglock); - timeout =MAX_SCHEDULE_TIMEOUT ;if (uts) timeout = (timespec_to_jiffies (&ts) + (ts.tv_sec || ts.tv_nsec)); - current->state =TASK_INTERRUPTIBLE ; - timeout =schedule_timeout (timeout); - -spin_lock_irq (¤t->sighand->siglock); - sig =dequeue_signal (current, &these, &info); - current->blocked = oldblocked; -recalc_sigpending (); +if (timeout) { +/* None ready -- temporarily unblock those we're +* interested while we are sleeping in so that we'll +* be awakened when they arrive. */ + current->real_blocked = current->blocked; +sigandsets (¤t->blocked, ¤t->blocked, &these); +recalc_sigpending (); +spin_unlock_irq (¤t->sighand->siglock); + + current->state =TASK_INTERRUPTIBLE ; + timeout =schedule_timeout (timeout); + +spin_lock_irq (¤t->sighand->siglock); + sig =dequeue_signal (current, &these, &info); + current->blocked = current->real_blocked; +siginitset (¤t->real_blocked,0 ); +recalc_sigpending (); + } }spin_unlock_irq (¤t->sighand->siglock);
Signature · 1 line
Daniel Jacobowitz