Merge git://oss.sgi.com:8090/xfs/xfs-2.6
[linux-drm-fsl-dcu.git] / kernel / signal.c
index ec81defde33946380518215cab07e309876360ed..228fdb5c01d12a0b1b409b1819a95a4c8d223840 100644 (file)
@@ -24,6 +24,9 @@
 #include <linux/signal.h>
 #include <linux/capability.h>
 #include <linux/freezer.h>
+#include <linux/pid_namespace.h>
+#include <linux/nsproxy.h>
+
 #include <asm/param.h>
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
@@ -583,7 +586,7 @@ static int check_kill_permission(int sig, struct siginfo *info,
        error = -EPERM;
        if ((info == SEND_SIG_NOINFO || (!is_si_special(info) && SI_FROMUSER(info)))
            && ((sig != SIGCONT) ||
-               (current->signal->session != t->signal->session))
+               (process_session(current) != process_session(t)))
            && (current->euid ^ t->suid) && (current->euid ^ t->uid)
            && (current->uid ^ t->suid) && (current->uid ^ t->uid)
            && !capable(CAP_KILL))
@@ -1116,19 +1119,18 @@ kill_pg_info(int sig, struct siginfo *info, pid_t pgrp)
 int kill_pid_info(int sig, struct siginfo *info, struct pid *pid)
 {
        int error;
-       int acquired_tasklist_lock = 0;
        struct task_struct *p;
 
        rcu_read_lock();
-       if (unlikely(sig_needs_tasklist(sig))) {
+       if (unlikely(sig_needs_tasklist(sig)))
                read_lock(&tasklist_lock);
-               acquired_tasklist_lock = 1;
-       }
+
        p = pid_task(pid, PIDTYPE_PID);
        error = -ESRCH;
        if (p)
                error = group_send_sig_info(sig, info, p);
-       if (unlikely(acquired_tasklist_lock))
+
+       if (unlikely(sig_needs_tasklist(sig)))
                read_unlock(&tasklist_lock);
        rcu_read_unlock();
        return error;
@@ -1702,7 +1704,9 @@ finish_stop(int stop_count)
                read_unlock(&tasklist_lock);
        }
 
-       schedule();
+       do {
+               schedule();
+       } while (try_to_freeze());
        /*
         * Now we don't run again until continued.
         */
@@ -1877,8 +1881,12 @@ relock:
                if (sig_kernel_ignore(signr)) /* Default is nothing. */
                        continue;
 
-               /* Init gets no signals it doesn't want.  */
-               if (current == child_reaper)
+               /*
+                * Init of a pid space gets no signals it doesn't want from
+                * within that pid space. It can of course get signals from
+                * its parent pid space.
+                */
+               if (current == child_reaper(current))
                        continue;
 
                if (sig_kernel_stop(signr)) {
@@ -2274,7 +2282,7 @@ static int do_tkill(int tgid, int pid, int sig)
  *  @pid: the PID of the thread
  *  @sig: signal to be sent
  *
- *  This syscall also checks the tgid and returns -ESRCH even if the PID
+ *  This syscall also checks the @tgid and returns -ESRCH even if the PID
  *  exists but it's not belonging to the target process anymore. This
  *  method solves the problem of threads exiting and PIDs getting reused.
  */