diff options
author | Ingo Molnar <mingo@elte.hu> | 2010-01-13 09:58:37 +0100 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2010-01-13 10:08:50 +0100 |
commit | 61405fea92c42d072d9b8bd189689f1502a838af (patch) | |
tree | 013ea3e7ed71f4114004d5852d40b6e89e128f76 /kernel/signal.c | |
parent | 9c443dfdd31eddea6cbe6ee0ca469fbcc4e1dc3b (diff) | |
parent | 1703f2c321a8a531c393e137a82602e16c6061cb (diff) |
Merge branch 'perf/urgent' into perf/core
Merge reason: queue up dependent patch, update to -rc4
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel/signal.c')
-rw-r--r-- | kernel/signal.c | 28 |
1 files changed, 16 insertions, 12 deletions
diff --git a/kernel/signal.c b/kernel/signal.c index 1814e68e4de3..934ae5e687b9 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -218,13 +218,13 @@ __sigqueue_alloc(int sig, struct task_struct *t, gfp_t flags, int override_rlimi struct user_struct *user; /* - * We won't get problems with the target's UID changing under us - * because changing it requires RCU be used, and if t != current, the - * caller must be holding the RCU readlock (by way of a spinlock) and - * we use RCU protection here + * Protect access to @t credentials. This can go away when all + * callers hold rcu read lock. */ + rcu_read_lock(); user = get_uid(__task_cred(t)->user); atomic_inc(&user->sigpending); + rcu_read_unlock(); if (override_rlimit || atomic_read(&user->sigpending) <= @@ -979,7 +979,8 @@ static void print_fatal_signal(struct pt_regs *regs, int signr) for (i = 0; i < 16; i++) { unsigned char insn; - __get_user(insn, (unsigned char *)(regs->ip + i)); + if (get_user(insn, (unsigned char *)(regs->ip + i))) + break; printk("%02x ", insn); } } @@ -1179,11 +1180,12 @@ int kill_pid_info_as_uid(int sig, struct siginfo *info, struct pid *pid, int ret = -EINVAL; struct task_struct *p; const struct cred *pcred; + unsigned long flags; if (!valid_signal(sig)) return ret; - read_lock(&tasklist_lock); + rcu_read_lock(); p = pid_task(pid, PIDTYPE_PID); if (!p) { ret = -ESRCH; @@ -1199,14 +1201,16 @@ int kill_pid_info_as_uid(int sig, struct siginfo *info, struct pid *pid, ret = security_task_kill(p, info, sig, secid); if (ret) goto out_unlock; - if (sig && p->sighand) { - unsigned long flags; - spin_lock_irqsave(&p->sighand->siglock, flags); - ret = __send_signal(sig, info, p, 1, 0); - spin_unlock_irqrestore(&p->sighand->siglock, flags); + + if (sig) { + if (lock_task_sighand(p, &flags)) { + ret = __send_signal(sig, info, p, 1, 0); + unlock_task_sighand(p, &flags); + } else + ret = -ESRCH; } out_unlock: - read_unlock(&tasklist_lock); + rcu_read_unlock(); return ret; } EXPORT_SYMBOL_GPL(kill_pid_info_as_uid); |