X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=kernel%2Fsched.c;h=3798b954e6e8cc2235dd1dbfcd9a7625569b4316;hb=b0f4b285d7ed174804658539129a834270f4829a;hp=dcb39bc88f6ccc75bd7c1e8aee2847b95fed6b9a;hpb=5250d329e38cdf7580faeb9c53c17d3588d7d19c;p=~andy%2Flinux diff --git a/kernel/sched.c b/kernel/sched.c index dcb39bc88f6..3798b954e6e 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -351,7 +351,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); @@ -5141,6 +5143,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) { @@ -5200,8 +5218,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; } @@ -5433,8 +5450,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);