diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/signal.c | 25 | ||||
| -rw-r--r-- | kernel/sys.c | 2 | 
2 files changed, 16 insertions, 11 deletions
| diff --git a/kernel/signal.c b/kernel/signal.c index 1814e68e4de3..d09692b40376 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) <= @@ -1179,11 +1179,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 +1200,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); diff --git a/kernel/sys.c b/kernel/sys.c index 20ccfb5da6af..26a6b73a6b85 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -162,6 +162,7 @@ SYSCALL_DEFINE3(setpriority, int, which, int, who, int, niceval)  	if (niceval > 19)  		niceval = 19; +	rcu_read_lock();  	read_lock(&tasklist_lock);  	switch (which) {  		case PRIO_PROCESS: @@ -199,6 +200,7 @@ SYSCALL_DEFINE3(setpriority, int, which, int, who, int, niceval)  	}  out_unlock:  	read_unlock(&tasklist_lock); +	rcu_read_unlock();  out:  	return error;  } | 
