powerpc: don't duplicate name between vio_driver and device_driver
[linux-3.10.git] / kernel / signal.c
index c135f5a..f2b96b0 100644 (file)
@@ -262,7 +262,7 @@ next_signal(struct sigpending *pending, sigset_t *mask)
        return sig;
 }
 
-static struct sigqueue *__sigqueue_alloc(struct task_struct *t, unsigned int __nocast flags,
+static struct sigqueue *__sigqueue_alloc(struct task_struct *t, gfp_t flags,
                                         int override_rlimit)
 {
        struct sigqueue *q = NULL;
@@ -397,20 +397,8 @@ void __exit_signal(struct task_struct *tsk)
        flush_sigqueue(&tsk->pending);
        if (sig) {
                /*
-                * We are cleaning up the signal_struct here.  We delayed
-                * calling exit_itimers until after flush_sigqueue, just in
-                * case our thread-local pending queue contained a queued
-                * timer signal that would have been cleared in
-                * exit_itimers.  When that called sigqueue_free, it would
-                * attempt to re-take the tasklist_lock and deadlock.  This
-                * can never happen if we ensure that all queues the
-                * timer's signal might be queued on have been flushed
-                * first.  The shared_pending queue, and our own pending
-                * queue are the only queues the timer could be on, since
-                * there are no other threads left in the group and timer
-                * signals are constrained to threads inside the group.
+                * We are cleaning up the signal_struct here.
                 */
-               exit_itimers(sig);
                exit_thread_group_keys(sig);
                kmem_cache_free(signal_cachep, sig);
        }
@@ -1193,6 +1181,40 @@ kill_proc_info(int sig, struct siginfo *info, pid_t pid)
        return error;
 }
 
+/* like kill_proc_info(), but doesn't use uid/euid of "current" */
+int kill_proc_info_as_uid(int sig, struct siginfo *info, pid_t pid,
+                     uid_t uid, uid_t euid)
+{
+       int ret = -EINVAL;
+       struct task_struct *p;
+
+       if (!valid_signal(sig))
+               return ret;
+
+       read_lock(&tasklist_lock);
+       p = find_task_by_pid(pid);
+       if (!p) {
+               ret = -ESRCH;
+               goto out_unlock;
+       }
+       if ((!info || ((unsigned long)info != 1 &&
+                       (unsigned long)info != 2 && SI_FROMUSER(info)))
+           && (euid != p->suid) && (euid != p->uid)
+           && (uid != p->suid) && (uid != p->uid)) {
+               ret = -EPERM;
+               goto out_unlock;
+       }
+       if (sig && p->sighand) {
+               unsigned long flags;
+               spin_lock_irqsave(&p->sighand->siglock, flags);
+               ret = __group_send_sig_info(sig, info, p);
+               spin_unlock_irqrestore(&p->sighand->siglock, flags);
+       }
+out_unlock:
+       read_unlock(&tasklist_lock);
+       return ret;
+}
+EXPORT_SYMBOL_GPL(kill_proc_info_as_uid);
 
 /*
  * kill_something_info() interprets pid in interesting ways just like kill(2).