|
@@ -1175,11 +1175,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;
|
|
@@ -1196,14 +1197,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);
|