diff options
Diffstat (limited to 'kernel/ptrace.c')
-rw-r--r-- | kernel/ptrace.c | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/kernel/ptrace.c b/kernel/ptrace.c index 210bbf045ee9..c890ac9a7962 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c | |||
@@ -161,6 +161,14 @@ int ptrace_check_attach(struct task_struct *child, bool ignore_state) | |||
161 | return ret; | 161 | return ret; |
162 | } | 162 | } |
163 | 163 | ||
164 | static int ptrace_has_cap(struct user_namespace *ns, unsigned int mode) | ||
165 | { | ||
166 | if (mode & PTRACE_MODE_NOAUDIT) | ||
167 | return has_ns_capability_noaudit(current, ns, CAP_SYS_PTRACE); | ||
168 | else | ||
169 | return has_ns_capability(current, ns, CAP_SYS_PTRACE); | ||
170 | } | ||
171 | |||
164 | int __ptrace_may_access(struct task_struct *task, unsigned int mode) | 172 | int __ptrace_may_access(struct task_struct *task, unsigned int mode) |
165 | { | 173 | { |
166 | const struct cred *cred = current_cred(), *tcred; | 174 | const struct cred *cred = current_cred(), *tcred; |
@@ -187,7 +195,7 @@ int __ptrace_may_access(struct task_struct *task, unsigned int mode) | |||
187 | cred->gid == tcred->sgid && | 195 | cred->gid == tcred->sgid && |
188 | cred->gid == tcred->gid)) | 196 | cred->gid == tcred->gid)) |
189 | goto ok; | 197 | goto ok; |
190 | if (ns_capable(tcred->user->user_ns, CAP_SYS_PTRACE)) | 198 | if (ptrace_has_cap(tcred->user->user_ns, mode)) |
191 | goto ok; | 199 | goto ok; |
192 | rcu_read_unlock(); | 200 | rcu_read_unlock(); |
193 | return -EPERM; | 201 | return -EPERM; |
@@ -196,7 +204,7 @@ ok: | |||
196 | smp_rmb(); | 204 | smp_rmb(); |
197 | if (task->mm) | 205 | if (task->mm) |
198 | dumpable = get_dumpable(task->mm); | 206 | dumpable = get_dumpable(task->mm); |
199 | if (!dumpable && !ns_capable(task_user_ns(task), CAP_SYS_PTRACE)) | 207 | if (!dumpable && !ptrace_has_cap(task_user_ns(task), mode)) |
200 | return -EPERM; | 208 | return -EPERM; |
201 | 209 | ||
202 | return security_ptrace_access_check(task, mode); | 210 | return security_ptrace_access_check(task, mode); |