diff options
-rw-r--r-- | kernel/signal.c | 17 |
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 | } |
1205 | out_unlock: | 1208 | out_unlock: |
1206 | read_unlock(&tasklist_lock); | 1209 | rcu_read_unlock(); |
1207 | return ret; | 1210 | return ret; |
1208 | } | 1211 | } |
1209 | EXPORT_SYMBOL_GPL(kill_pid_info_as_uid); | 1212 | EXPORT_SYMBOL_GPL(kill_pid_info_as_uid); |