Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=10ab825bdef8df510f99c703a5a2d9b13a4e31a5
Commit:     10ab825bdef8df510f99c703a5a2d9b13a4e31a5
Parent:     5de18d169739293e27e0cf9acfc75a2d2f4aa572
Author:     Oleg Nesterov <[EMAIL PROTECTED]>
AuthorDate: Wed May 9 02:34:37 2007 -0700
Committer:  Linus Torvalds <[EMAIL PROTECTED]>
CommitDate: Wed May 9 12:30:53 2007 -0700

    change kernel threads to ignore signals instead of blocking them
    
    Currently kernel threads use sigprocmask(SIG_BLOCK) to protect against
    signals.  This doesn't prevent the signal delivery, this only blocks
    signal_wake_up().  Every "killall -33 kthreadd" means a "struct siginfo"
    leak.
    
    Change kthreadd_setup() to set all handlers to SIG_IGN instead of blocking
    them (make a new helper ignore_signals() for that).  If the kernel thread
    needs some signal, it should use allow_signal() anyway, and in that case it
    should not use CLONE_SIGHAND.
    
    Note that we can't change daemonize() (should die!) in the same way,
    because it can be used along with CLONE_SIGHAND.  This means that
    allow_signal() still should unblock the signal to work correctly with
    daemonize()ed threads.
    
    However, disallow_signal() doesn't block the signal any longer but ignores
    it.
    
    NOTE: with or without this patch the kernel threads are not protected from
    handle_stop_signal(), this seems harmless, but not good.
    
    Signed-off-by: Oleg Nesterov <[EMAIL PROTECTED]>
    Acked-by: "Eric W. Biederman" <[EMAIL PROTECTED]>
    Signed-off-by: Andrew Morton <[EMAIL PROTECTED]>
    Signed-off-by: Linus Torvalds <[EMAIL PROTECTED]>
---
 include/linux/sched.h |    1 +
 kernel/exit.c         |    2 +-
 kernel/kthread.c      |   17 +++--------------
 kernel/signal.c       |   10 ++++++++++
 4 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/include/linux/sched.h b/include/linux/sched.h
index 3d95c48..28000b1 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1317,6 +1317,7 @@ extern int in_egroup_p(gid_t);
 
 extern void proc_caches_init(void);
 extern void flush_signals(struct task_struct *);
+extern void ignore_signals(struct task_struct *);
 extern void flush_signal_handlers(struct task_struct *, int force_default);
 extern int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t 
*info);
 
diff --git a/kernel/exit.c b/kernel/exit.c
index bc982cd..b0c6f0c 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -347,7 +347,7 @@ int disallow_signal(int sig)
                return -EINVAL;
 
        spin_lock_irq(&current->sighand->siglock);
-       sigaddset(&current->blocked, sig);
+       current->sighand->action[(sig)-1].sa.sa_handler = SIG_IGN;
        recalc_sigpending();
        spin_unlock_irq(&current->sighand->siglock);
        return 0;
diff --git a/kernel/kthread.c b/kernel/kthread.c
index 0eb0070..df8a8e8 100644
--- a/kernel/kthread.c
+++ b/kernel/kthread.c
@@ -215,24 +215,13 @@ EXPORT_SYMBOL(kthread_stop);
 static __init void kthreadd_setup(void)
 {
        struct task_struct *tsk = current;
-       struct k_sigaction sa;
-       sigset_t blocked;
 
        set_task_comm(tsk, "kthreadd");
 
-       /* Block and flush all signals */
-       sigfillset(&blocked);
-       sigprocmask(SIG_BLOCK, &blocked, NULL);
-       flush_signals(tsk);
+       ignore_signals(tsk);
 
-       /* SIG_IGN makes children autoreap: see do_notify_parent(). */
-       sa.sa.sa_handler = SIG_IGN;
-       sa.sa.sa_flags = 0;
-       siginitset(&sa.sa.sa_mask, sigmask(SIGCHLD));
-       do_sigaction(SIGCHLD, &sa, (struct k_sigaction *)0);
-
-       set_user_nice(current, -5);
-       set_cpus_allowed(current, CPU_MASK_ALL);
+       set_user_nice(tsk, -5);
+       set_cpus_allowed(tsk, CPU_MASK_ALL);
 }
 
 int kthreadd(void *unused)
diff --git a/kernel/signal.c b/kernel/signal.c
index 23ae6d6..2ac3a66 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -209,6 +209,16 @@ void flush_signals(struct task_struct *t)
        spin_unlock_irqrestore(&t->sighand->siglock, flags);
 }
 
+void ignore_signals(struct task_struct *t)
+{
+       int i;
+
+       for (i = 0; i < _NSIG; ++i)
+               t->sighand->action[i].sa.sa_handler = SIG_IGN;
+
+       flush_signals(t);
+}
+
 /*
  * Flush all handlers for a task.
  */
-
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