Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=834d216e1f804560bd1421c511ad168d7c24b01d
Commit:     834d216e1f804560bd1421c511ad168d7c24b01d
Parent:     d02479bdeb1c9b037892061cdcf4e730183391fa
Author:     Oleg Nesterov <[EMAIL PROTECTED]>
AuthorDate: Wed Aug 22 14:01:42 2007 -0700
Committer:  Linus Torvalds <[EMAIL PROTECTED]>
CommitDate: Wed Aug 22 19:52:46 2007 -0700

    signalfd: fix interaction with posix-timers
    
    dequeue_signal:
    
        if (__SI_TIMER) {
                spin_unlock(&tsk->sighand->siglock);
                do_schedule_next_timer(info);
                spin_lock(&tsk->sighand->siglock);
        }
    
    Unless tsk == curent, this is absolutely unsafe: nothing prevents tsk from
    exiting. If signalfd was passed to another process, do_schedule_next_timer()
    is just wrong.
    
    Add yet another "tsk == current" check into dequeue_signal().
    
    This patch fixes an oopsable bug, but breaks the scheduling of posix timers
    if the shared __SI_TIMER signal was fetched via signalfd attached to another
    sub-thread. Mostly fixed by the next patch.
    
    Signed-off-by: Oleg Nesterov <[EMAIL PROTECTED]>
    Cc: Benjamin Herrenschmidt <[EMAIL PROTECTED]>
    Cc: Davide Libenzi <[EMAIL PROTECTED]>
    Cc: Ingo Molnar <[EMAIL PROTECTED]>
    Cc: Michael Kerrisk <[EMAIL PROTECTED]>
    Cc: Roland McGrath <[EMAIL PROTECTED]>
    Cc: Thomas Gleixner <[EMAIL PROTECTED]>
    Cc: <[EMAIL PROTECTED]>
    Signed-off-by: Andrew Morton <[EMAIL PROTECTED]>
    Signed-off-by: Linus Torvalds <[EMAIL PROTECTED]>
---
 kernel/signal.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/kernel/signal.c b/kernel/signal.c
index b27c01a..ad63109 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -378,7 +378,7 @@ int dequeue_signal(struct task_struct *tsk, sigset_t *mask, 
siginfo_t *info)
        /* We only dequeue private signals from ourselves, we don't let
         * signalfd steal them
         */
-       if (tsk == current)
+       if (likely(tsk == current))
                signr = __dequeue_signal(&tsk->pending, mask, info);
        if (!signr) {
                signr = __dequeue_signal(&tsk->signal->shared_pending,
@@ -425,7 +425,7 @@ int dequeue_signal(struct task_struct *tsk, sigset_t *mask, 
siginfo_t *info)
                if (!(tsk->signal->flags & SIGNAL_GROUP_EXIT))
                        tsk->signal->flags |= SIGNAL_STOP_DEQUEUED;
        }
-       if ( signr &&
+       if (signr && likely(tsk == current) &&
             ((info->si_code & __SI_MASK) == __SI_TIMER) &&
             info->si_sys_private){
                /*
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to