diff options
Diffstat (limited to 'kernel/sched.c')
| -rw-r--r-- | kernel/sched.c | 26 | 
1 files changed, 21 insertions, 5 deletions
| diff --git a/kernel/sched.c b/kernel/sched.c index e4bb1dd7b308..33cf4a1cbcd1 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -345,7 +345,9 @@ static inline struct task_group *task_group(struct task_struct *p)  	struct task_group *tg;  #ifdef CONFIG_USER_SCHED -	tg = p->user->tg; +	rcu_read_lock(); +	tg = __task_cred(p)->user->tg; +	rcu_read_unlock();  #elif defined(CONFIG_CGROUP_SCHED)  	tg = container_of(task_subsys_state(p, cpu_cgroup_subsys_id),  				struct task_group, css); @@ -5134,6 +5136,22 @@ __setscheduler(struct rq *rq, struct task_struct *p, int policy, int prio)  	set_load_weight(p);  } +/* + * check the target process has a UID that matches the current process's + */ +static bool check_same_owner(struct task_struct *p) +{ +	const struct cred *cred = current_cred(), *pcred; +	bool match; + +	rcu_read_lock(); +	pcred = __task_cred(p); +	match = (cred->euid == pcred->euid || +		 cred->euid == pcred->uid); +	rcu_read_unlock(); +	return match; +} +  static int __sched_setscheduler(struct task_struct *p, int policy,  				struct sched_param *param, bool user)  { @@ -5193,8 +5211,7 @@ recheck:  			return -EPERM;  		/* can't change other user's priorities */ -		if ((current->euid != p->euid) && -		    (current->euid != p->uid)) +		if (!check_same_owner(p))  			return -EPERM;  	} @@ -5426,8 +5443,7 @@ long sched_setaffinity(pid_t pid, const cpumask_t *in_mask)  	read_unlock(&tasklist_lock);  	retval = -EPERM; -	if ((current->euid != p->euid) && (current->euid != p->uid) && -			!capable(CAP_SYS_NICE)) +	if (!check_same_owner(p) && !capable(CAP_SYS_NICE))  		goto out_unlock;  	retval = security_task_setscheduler(p, 0, NULL); | 
