]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - glsdk/meta-ti-glsdk.git/blob - recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.16/0064-futex-Do-not-leak-robust-list-to-unprivileged-proces.patch
linux-ti33x-psp 3.2: bump SRCREV for 2 CPPI1.4 fixes
[glsdk/meta-ti-glsdk.git] / recipes-kernel / linux / linux-ti33x-psp-3.2 / 3.2.16 / 0064-futex-Do-not-leak-robust-list-to-unprivileged-proces.patch
1 From 7480d9953ded1b970bb05c7585e2a08001ae8565 Mon Sep 17 00:00:00 2001
2 From: Kees Cook <keescook@chromium.org>
3 Date: Mon, 19 Mar 2012 16:12:53 -0700
4 Subject: [PATCH 64/68] futex: Do not leak robust list to unprivileged process
6 commit bdbb776f882f5ad431aa1e694c69c1c3d6a4a5b8 upstream.
8 It was possible to extract the robust list head address from a setuid
9 process if it had used set_robust_list(), allowing an ASLR info leak. This
10 changes the permission checks to be the same as those used for similar
11 info that comes out of /proc.
13 Running a setuid program that uses robust futexes would have had:
14   cred->euid != pcred->euid
15   cred->euid == pcred->uid
16 so the old permissions check would allow it. I'm not aware of any setuid
17 programs that use robust futexes, so this is just a preventative measure.
19 (This patch is based on changes from grsecurity.)
21 Signed-off-by: Kees Cook <keescook@chromium.org>
22 Cc: Darren Hart <dvhart@linux.intel.com>
23 Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
24 Cc: Jiri Kosina <jkosina@suse.cz>
25 Cc: Eric W. Biederman <ebiederm@xmission.com>
26 Cc: David Howells <dhowells@redhat.com>
27 Cc: Serge E. Hallyn <serge.hallyn@canonical.com>
28 Cc: kernel-hardening@lists.openwall.com
29 Cc: spender@grsecurity.net
30 Link: http://lkml.kernel.org/r/20120319231253.GA20893@www.outflux.net
31 Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
32 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
33 ---
34  kernel/futex.c        |   36 +++++++++++++-----------------------
35  kernel/futex_compat.c |   36 +++++++++++++-----------------------
36  2 files changed, 26 insertions(+), 46 deletions(-)
38 diff --git a/kernel/futex.c b/kernel/futex.c
39 index 0677023..866c9d5 100644
40 --- a/kernel/futex.c
41 +++ b/kernel/futex.c
42 @@ -59,6 +59,7 @@
43  #include <linux/magic.h>
44  #include <linux/pid.h>
45  #include <linux/nsproxy.h>
46 +#include <linux/ptrace.h>
47  
48  #include <asm/futex.h>
49  
50 @@ -2443,40 +2444,29 @@ SYSCALL_DEFINE3(get_robust_list, int, pid,
51  {
52         struct robust_list_head __user *head;
53         unsigned long ret;
54 -       const struct cred *cred = current_cred(), *pcred;
55 +       struct task_struct *p;
56  
57         if (!futex_cmpxchg_enabled)
58                 return -ENOSYS;
59  
60 +       rcu_read_lock();
61 +
62 +       ret = -ESRCH;
63         if (!pid)
64 -               head = current->robust_list;
65 +               p = current;
66         else {
67 -               struct task_struct *p;
68 -
69 -               ret = -ESRCH;
70 -               rcu_read_lock();
71                 p = find_task_by_vpid(pid);
72                 if (!p)
73                         goto err_unlock;
74 -               ret = -EPERM;
75 -               pcred = __task_cred(p);
76 -               /* If victim is in different user_ns, then uids are not
77 -                  comparable, so we must have CAP_SYS_PTRACE */
78 -               if (cred->user->user_ns != pcred->user->user_ns) {
79 -                       if (!ns_capable(pcred->user->user_ns, CAP_SYS_PTRACE))
80 -                               goto err_unlock;
81 -                       goto ok;
82 -               }
83 -               /* If victim is in same user_ns, then uids are comparable */
84 -               if (cred->euid != pcred->euid &&
85 -                   cred->euid != pcred->uid &&
86 -                   !ns_capable(pcred->user->user_ns, CAP_SYS_PTRACE))
87 -                       goto err_unlock;
88 -ok:
89 -               head = p->robust_list;
90 -               rcu_read_unlock();
91         }
92  
93 +       ret = -EPERM;
94 +       if (!ptrace_may_access(p, PTRACE_MODE_READ))
95 +               goto err_unlock;
96 +
97 +       head = p->robust_list;
98 +       rcu_read_unlock();
99 +
100         if (put_user(sizeof(*head), len_ptr))
101                 return -EFAULT;
102         return put_user(head, head_ptr);
103 diff --git a/kernel/futex_compat.c b/kernel/futex_compat.c
104 index 5f9e689..a9642d5 100644
105 --- a/kernel/futex_compat.c
106 +++ b/kernel/futex_compat.c
107 @@ -10,6 +10,7 @@
108  #include <linux/compat.h>
109  #include <linux/nsproxy.h>
110  #include <linux/futex.h>
111 +#include <linux/ptrace.h>
112  
113  #include <asm/uaccess.h>
114  
115 @@ -136,40 +137,29 @@ compat_sys_get_robust_list(int pid, compat_uptr_t __user *head_ptr,
116  {
117         struct compat_robust_list_head __user *head;
118         unsigned long ret;
119 -       const struct cred *cred = current_cred(), *pcred;
120 +       struct task_struct *p;
121  
122         if (!futex_cmpxchg_enabled)
123                 return -ENOSYS;
124  
125 +       rcu_read_lock();
127 +       ret = -ESRCH;
128         if (!pid)
129 -               head = current->compat_robust_list;
130 +               p = current;
131         else {
132 -               struct task_struct *p;
134 -               ret = -ESRCH;
135 -               rcu_read_lock();
136                 p = find_task_by_vpid(pid);
137                 if (!p)
138                         goto err_unlock;
139 -               ret = -EPERM;
140 -               pcred = __task_cred(p);
141 -               /* If victim is in different user_ns, then uids are not
142 -                  comparable, so we must have CAP_SYS_PTRACE */
143 -               if (cred->user->user_ns != pcred->user->user_ns) {
144 -                       if (!ns_capable(pcred->user->user_ns, CAP_SYS_PTRACE))
145 -                               goto err_unlock;
146 -                       goto ok;
147 -               }
148 -               /* If victim is in same user_ns, then uids are comparable */
149 -               if (cred->euid != pcred->euid &&
150 -                   cred->euid != pcred->uid &&
151 -                   !ns_capable(pcred->user->user_ns, CAP_SYS_PTRACE))
152 -                       goto err_unlock;
153 -ok:
154 -               head = p->compat_robust_list;
155 -               rcu_read_unlock();
156         }
157  
158 +       ret = -EPERM;
159 +       if (!ptrace_may_access(p, PTRACE_MODE_READ))
160 +               goto err_unlock;
162 +       head = p->compat_robust_list;
163 +       rcu_read_unlock();
165         if (put_user(sizeof(*head), len_ptr))
166                 return -EFAULT;
167         return put_user(ptr_to_compat(head), head_ptr);
168 -- 
169 1.7.10