aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/signal.c17
1 files changed, 10 insertions, 7 deletions
diff --git a/kernel/signal.c b/kernel/signal.c
index 6b982f2cf524..73316568a69c 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -1175,11 +1175,12 @@ int kill_pid_info_as_uid(int sig, struct siginfo *info, struct pid *pid,
1175 int ret = -EINVAL; 1175 int ret = -EINVAL;
1176 struct task_struct *p; 1176 struct task_struct *p;
1177 const struct cred *pcred; 1177 const struct cred *pcred;
1178 unsigned long flags;
1178 1179
1179 if (!valid_signal(sig)) 1180 if (!valid_signal(sig))
1180 return ret; 1181 return ret;
1181 1182
1182 read_lock(&tasklist_lock); 1183 rcu_read_lock();
1183 p = pid_task(pid, PIDTYPE_PID); 1184 p = pid_task(pid, PIDTYPE_PID);
1184 if (!p) { 1185 if (!p) {
1185 ret = -ESRCH; 1186 ret = -ESRCH;
@@ -1196,14 +1197,16 @@ int kill_pid_info_as_uid(int sig, struct siginfo *info, struct pid *pid,
1196 ret = security_task_kill(p, info, sig, secid); 1197 ret = security_task_kill(p, info, sig, secid);
1197 if (ret) 1198 if (ret)
1198 goto out_unlock; 1199 goto out_unlock;
1199 if (sig && p->sighand) { 1200
1200 unsigned long flags; 1201 if (sig) {
1201 spin_lock_irqsave(&p->sighand->siglock, flags); 1202 if (lock_task_sighand(p, &flags)) {
1202 ret = __send_signal(sig, info, p, 1, 0); 1203 ret = __send_signal(sig, info, p, 1, 0);
1203 spin_unlock_irqrestore(&p->sighand->siglock, flags); 1204 unlock_task_sighand(p, &flags);
1205 } else
1206 ret = -ESRCH;
1204 } 1207 }
1205out_unlock: 1208out_unlock:
1206 read_unlock(&tasklist_lock); 1209 rcu_read_unlock();
1207 return ret; 1210 return ret;
1208} 1211}
1209EXPORT_SYMBOL_GPL(kill_pid_info_as_uid); 1212EXPORT_SYMBOL_GPL(kill_pid_info_as_uid);