]> Pileus Git - ~andy/linux/blobdiff - kernel/sched.c
Merge branch 'tracing-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[~andy/linux] / kernel / sched.c
index dcb39bc88f6ccc75bd7c1e8aee2847b95fed6b9a..3798b954e6e8cc2235dd1dbfcd9a7625569b4316 100644 (file)
@@ -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);