aboutsummaryrefslogtreecommitdiffstats
path: root/security/commoncap.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/commoncap.c')
-rw-r--r--security/commoncap.c40
1 files changed, 32 insertions, 8 deletions
diff --git a/security/commoncap.c b/security/commoncap.c
index 43a205bc7d7c..f20e984ccfb4 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -127,18 +127,30 @@ int cap_settime(const struct timespec *ts, const struct timezone *tz)
127 * @child: The process to be accessed 127 * @child: The process to be accessed
128 * @mode: The mode of attachment. 128 * @mode: The mode of attachment.
129 * 129 *
130 * If we are in the same or an ancestor user_ns and have all the target
131 * task's capabilities, then ptrace access is allowed.
132 * If we have the ptrace capability to the target user_ns, then ptrace
133 * access is allowed.
134 * Else denied.
135 *
130 * Determine whether a process may access another, returning 0 if permission 136 * Determine whether a process may access another, returning 0 if permission
131 * granted, -ve if denied. 137 * granted, -ve if denied.
132 */ 138 */
133int cap_ptrace_access_check(struct task_struct *child, unsigned int mode) 139int cap_ptrace_access_check(struct task_struct *child, unsigned int mode)
134{ 140{
135 int ret = 0; 141 int ret = 0;
142 const struct cred *cred, *child_cred;
136 143
137 rcu_read_lock(); 144 rcu_read_lock();
138 if (!cap_issubset(__task_cred(child)->cap_permitted, 145 cred = current_cred();
139 current_cred()->cap_permitted) && 146 child_cred = __task_cred(child);
140 !capable(CAP_SYS_PTRACE)) 147 if (cred->user->user_ns == child_cred->user->user_ns &&
141 ret = -EPERM; 148 cap_issubset(child_cred->cap_permitted, cred->cap_permitted))
149 goto out;
150 if (ns_capable(child_cred->user->user_ns, CAP_SYS_PTRACE))
151 goto out;
152 ret = -EPERM;
153out:
142 rcu_read_unlock(); 154 rcu_read_unlock();
143 return ret; 155 return ret;
144} 156}
@@ -147,18 +159,30 @@ int cap_ptrace_access_check(struct task_struct *child, unsigned int mode)
147 * cap_ptrace_traceme - Determine whether another process may trace the current 159 * cap_ptrace_traceme - Determine whether another process may trace the current
148 * @parent: The task proposed to be the tracer 160 * @parent: The task proposed to be the tracer
149 * 161 *
162 * If parent is in the same or an ancestor user_ns and has all current's
163 * capabilities, then ptrace access is allowed.
164 * If parent has the ptrace capability to current's user_ns, then ptrace
165 * access is allowed.
166 * Else denied.
167 *
150 * Determine whether the nominated task is permitted to trace the current 168 * Determine whether the nominated task is permitted to trace the current
151 * process, returning 0 if permission is granted, -ve if denied. 169 * process, returning 0 if permission is granted, -ve if denied.
152 */ 170 */
153int cap_ptrace_traceme(struct task_struct *parent) 171int cap_ptrace_traceme(struct task_struct *parent)
154{ 172{
155 int ret = 0; 173 int ret = 0;
174 const struct cred *cred, *child_cred;
156 175
157 rcu_read_lock(); 176 rcu_read_lock();
158 if (!cap_issubset(current_cred()->cap_permitted, 177 cred = __task_cred(parent);
159 __task_cred(parent)->cap_permitted) && 178 child_cred = current_cred();
160 !has_capability(parent, CAP_SYS_PTRACE)) 179 if (cred->user->user_ns == child_cred->user->user_ns &&
161 ret = -EPERM; 180 cap_issubset(child_cred->cap_permitted, cred->cap_permitted))
181 goto out;
182 if (has_ns_capability(parent, child_cred->user->user_ns, CAP_SYS_PTRACE))
183 goto out;
184 ret = -EPERM;
185out:
162 rcu_read_unlock(); 186 rcu_read_unlock();
163 return ret; 187 return ret;
164} 188}