]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - kernel/futex.c
CRED: Use RCU to access another task's creds and to release a task's own creds
[mirror_ubuntu-bionic-kernel.git] / kernel / futex.c
index 7d1136e97c142d198b897dab1846acd99f1f655f..4fe790e89d0f34af1cc24359d32bca3b58e970ca 100644 (file)
@@ -439,13 +439,20 @@ static void free_pi_state(struct futex_pi_state *pi_state)
 static struct task_struct * futex_find_get_task(pid_t pid)
 {
        struct task_struct *p;
+       const struct cred *cred = current_cred(), *pcred;
 
        rcu_read_lock();
        p = find_task_by_vpid(pid);
-       if (!p || ((current->euid != p->euid) && (current->euid != p->uid)))
+       if (!p) {
                p = ERR_PTR(-ESRCH);
-       else
-               get_task_struct(p);
+       } else {
+               pcred = __task_cred(p);
+               if (cred->euid != pcred->euid &&
+                   cred->euid != pcred->uid)
+                       p = ERR_PTR(-ESRCH);
+               else
+                       get_task_struct(p);
+       }
 
        rcu_read_unlock();
 
@@ -1296,13 +1303,16 @@ static int futex_wait(u32 __user *uaddr, struct rw_semaphore *fshared,
                if (!abs_time)
                        schedule();
                else {
+                       unsigned long slack;
+                       slack = current->timer_slack_ns;
+                       if (rt_task(current))
+                               slack = 0;
                        hrtimer_init_on_stack(&t.timer, CLOCK_MONOTONIC,
                                                HRTIMER_MODE_ABS);
                        hrtimer_init_sleeper(&t, current);
-                       t.timer.expires = *abs_time;
+                       hrtimer_set_expires_range_ns(&t.timer, *abs_time, slack);
 
-                       hrtimer_start(&t.timer, t.timer.expires,
-                                               HRTIMER_MODE_ABS);
+                       hrtimer_start_expires(&t.timer, HRTIMER_MODE_ABS);
                        if (!hrtimer_active(&t.timer))
                                t.task = NULL;
 
@@ -1404,7 +1414,7 @@ static int futex_lock_pi(u32 __user *uaddr, struct rw_semaphore *fshared,
                hrtimer_init_on_stack(&to->timer, CLOCK_REALTIME,
                                      HRTIMER_MODE_ABS);
                hrtimer_init_sleeper(to, current);
-               to->timer.expires = *time;
+               hrtimer_set_expires(&to->timer, *time);
        }
 
        q.pi_state = NULL;
@@ -1826,6 +1836,7 @@ sys_get_robust_list(int pid, struct robust_list_head __user * __user *head_ptr,
 {
        struct robust_list_head __user *head;
        unsigned long ret;
+       const struct cred *cred = current_cred(), *pcred;
 
        if (!futex_cmpxchg_enabled)
                return -ENOSYS;
@@ -1841,8 +1852,10 @@ sys_get_robust_list(int pid, struct robust_list_head __user * __user *head_ptr,
                if (!p)
                        goto err_unlock;
                ret = -EPERM;
-               if ((current->euid != p->euid) && (current->euid != p->uid) &&
-                               !capable(CAP_SYS_PTRACE))
+               pcred = __task_cred(p);
+               if (cred->euid != pcred->euid &&
+                   cred->euid != pcred->uid &&
+                   !capable(CAP_SYS_PTRACE))
                        goto err_unlock;
                head = p->robust_list;
                rcu_read_unlock();