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) | |||
| 345 | struct task_group *tg; | 345 | struct task_group *tg; |
| 346 | 346 | ||
| 347 | #ifdef CONFIG_USER_SCHED | 347 | #ifdef CONFIG_USER_SCHED |
| 348 | tg = p->user->tg; | 348 | rcu_read_lock(); |
| 349 | tg = __task_cred(p)->user->tg; | ||
| 350 | rcu_read_unlock(); | ||
| 349 | #elif defined(CONFIG_CGROUP_SCHED) | 351 | #elif defined(CONFIG_CGROUP_SCHED) |
| 350 | tg = container_of(task_subsys_state(p, cpu_cgroup_subsys_id), | 352 | tg = container_of(task_subsys_state(p, cpu_cgroup_subsys_id), |
| 351 | struct task_group, css); | 353 | struct task_group, css); |
| @@ -5134,6 +5136,22 @@ __setscheduler(struct rq *rq, struct task_struct *p, int policy, int prio) | |||
| 5134 | set_load_weight(p); | 5136 | set_load_weight(p); |
| 5135 | } | 5137 | } |
| 5136 | 5138 | ||
| 5139 | /* | ||
| 5140 | * check the target process has a UID that matches the current process's | ||
| 5141 | */ | ||
| 5142 | static bool check_same_owner(struct task_struct *p) | ||
| 5143 | { | ||
| 5144 | const struct cred *cred = current_cred(), *pcred; | ||
| 5145 | bool match; | ||
| 5146 | |||
| 5147 | rcu_read_lock(); | ||
| 5148 | pcred = __task_cred(p); | ||
| 5149 | match = (cred->euid == pcred->euid || | ||
| 5150 | cred->euid == pcred->uid); | ||
| 5151 | rcu_read_unlock(); | ||
| 5152 | return match; | ||
| 5153 | } | ||
| 5154 | |||
| 5137 | static int __sched_setscheduler(struct task_struct *p, int policy, | 5155 | static int __sched_setscheduler(struct task_struct *p, int policy, |
| 5138 | struct sched_param *param, bool user) | 5156 | struct sched_param *param, bool user) |
| 5139 | { | 5157 | { |
| @@ -5193,8 +5211,7 @@ recheck: | |||
| 5193 | return -EPERM; | 5211 | return -EPERM; |
| 5194 | 5212 | ||
| 5195 | /* can't change other user's priorities */ | 5213 | /* can't change other user's priorities */ |
| 5196 | if ((current->euid != p->euid) && | 5214 | if (!check_same_owner(p)) |
| 5197 | (current->euid != p->uid)) | ||
| 5198 | return -EPERM; | 5215 | return -EPERM; |
| 5199 | } | 5216 | } |
| 5200 | 5217 | ||
| @@ -5426,8 +5443,7 @@ long sched_setaffinity(pid_t pid, const cpumask_t *in_mask) | |||
| 5426 | read_unlock(&tasklist_lock); | 5443 | read_unlock(&tasklist_lock); |
| 5427 | 5444 | ||
| 5428 | retval = -EPERM; | 5445 | retval = -EPERM; |
| 5429 | if ((current->euid != p->euid) && (current->euid != p->uid) && | 5446 | if (!check_same_owner(p) && !capable(CAP_SYS_NICE)) |
| 5430 | !capable(CAP_SYS_NICE)) | ||
| 5431 | goto out_unlock; | 5447 | goto out_unlock; |
| 5432 | 5448 | ||
| 5433 | retval = security_task_setscheduler(p, 0, NULL); | 5449 | retval = security_task_setscheduler(p, 0, NULL); |
