Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 14d8c9f3 authored by Thomas Gleixner's avatar Thomas Gleixner
Browse files

signal: Fix racy access to __task_cred in kill_pid_info_as_uid()



kill_pid_info_as_uid() accesses __task_cred() without being in a RCU
read side critical section. tasklist_lock is not protecting that when
CONFIG_TREE_PREEMPT_RCU=y.

Convert the whole tasklist_lock section to rcu and use
lock_task_sighand to prevent the exit race.

Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
LKML-Reference: <20091210004703.232302055@linutronix.de>
Acked-by: default avatarOleg Nesterov <oleg@redhat.com>
parent ea5b41f9
Loading
Loading
Loading
Loading
+10 −7
Original line number Diff line number Diff line
@@ -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);

	if (sig) {
		if (lock_task_sighand(p, &flags)) {
			ret = __send_signal(sig, info, p, 1, 0);
		spin_unlock_irqrestore(&p->sighand->siglock, flags);
			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);