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); |