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 dcb39bc88f6c..3798b954e6e8 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -351,7 +351,9 @@ static inline struct task_group *task_group(struct task_struct *p) | |||
351 | struct task_group *tg; | 351 | struct task_group *tg; |
352 | 352 | ||
353 | #ifdef CONFIG_USER_SCHED | 353 | #ifdef CONFIG_USER_SCHED |
354 | tg = p->user->tg; | 354 | rcu_read_lock(); |
355 | tg = __task_cred(p)->user->tg; | ||
356 | rcu_read_unlock(); | ||
355 | #elif defined(CONFIG_CGROUP_SCHED) | 357 | #elif defined(CONFIG_CGROUP_SCHED) |
356 | tg = container_of(task_subsys_state(p, cpu_cgroup_subsys_id), | 358 | tg = container_of(task_subsys_state(p, cpu_cgroup_subsys_id), |
357 | struct task_group, css); | 359 | struct task_group, css); |
@@ -5141,6 +5143,22 @@ __setscheduler(struct rq *rq, struct task_struct *p, int policy, int prio) | |||
5141 | set_load_weight(p); | 5143 | set_load_weight(p); |
5142 | } | 5144 | } |
5143 | 5145 | ||
5146 | /* | ||
5147 | * check the target process has a UID that matches the current process's | ||
5148 | */ | ||
5149 | static bool check_same_owner(struct task_struct *p) | ||
5150 | { | ||
5151 | const struct cred *cred = current_cred(), *pcred; | ||
5152 | bool match; | ||
5153 | |||
5154 | rcu_read_lock(); | ||
5155 | pcred = __task_cred(p); | ||
5156 | match = (cred->euid == pcred->euid || | ||
5157 | cred->euid == pcred->uid); | ||
5158 | rcu_read_unlock(); | ||
5159 | return match; | ||
5160 | } | ||
5161 | |||
5144 | static int __sched_setscheduler(struct task_struct *p, int policy, | 5162 | static int __sched_setscheduler(struct task_struct *p, int policy, |
5145 | struct sched_param *param, bool user) | 5163 | struct sched_param *param, bool user) |
5146 | { | 5164 | { |
@@ -5200,8 +5218,7 @@ recheck: | |||
5200 | return -EPERM; | 5218 | return -EPERM; |
5201 | 5219 | ||
5202 | /* can't change other user's priorities */ | 5220 | /* can't change other user's priorities */ |
5203 | if ((current->euid != p->euid) && | 5221 | if (!check_same_owner(p)) |
5204 | (current->euid != p->uid)) | ||
5205 | return -EPERM; | 5222 | return -EPERM; |
5206 | } | 5223 | } |
5207 | 5224 | ||
@@ -5433,8 +5450,7 @@ long sched_setaffinity(pid_t pid, const cpumask_t *in_mask) | |||
5433 | read_unlock(&tasklist_lock); | 5450 | read_unlock(&tasklist_lock); |
5434 | 5451 | ||
5435 | retval = -EPERM; | 5452 | retval = -EPERM; |
5436 | if ((current->euid != p->euid) && (current->euid != p->uid) && | 5453 | if (!check_same_owner(p) && !capable(CAP_SYS_NICE)) |
5437 | !capable(CAP_SYS_NICE)) | ||
5438 | goto out_unlock; | 5454 | goto out_unlock; |
5439 | 5455 | ||
5440 | retval = security_task_setscheduler(p, 0, NULL); | 5456 | retval = security_task_setscheduler(p, 0, NULL); |