| From cf23705244c947151179f929774fabf71e239eee Mon Sep 17 00:00:00 2001 |
| From: =?UTF-8?q?Micka=C3=ABl=20Sala=C3=BCn?= <mic@linux.microsoft.com> |
| Date: Fri, 30 Oct 2020 13:38:48 +0100 |
| Subject: ptrace: Set PF_SUPERPRIV when checking capability |
| MIME-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| From: Mickaël Salaün <mic@linux.microsoft.com> |
| |
| commit cf23705244c947151179f929774fabf71e239eee upstream. |
| |
| Commit 69f594a38967 ("ptrace: do not audit capability check when outputing |
| /proc/pid/stat") replaced the use of ns_capable() with |
| has_ns_capability{,_noaudit}() which doesn't set PF_SUPERPRIV. |
| |
| Commit 6b3ad6649a4c ("ptrace: reintroduce usage of subjective credentials in |
| ptrace_has_cap()") replaced has_ns_capability{,_noaudit}() with |
| security_capable(), which doesn't set PF_SUPERPRIV neither. |
| |
| Since commit 98f368e9e263 ("kernel: Add noaudit variant of ns_capable()"), a |
| new ns_capable_noaudit() helper is available. Let's use it! |
| |
| As a result, the signature of ptrace_has_cap() is restored to its original one. |
| |
| Cc: Christian Brauner <christian.brauner@ubuntu.com> |
| Cc: Eric Paris <eparis@redhat.com> |
| Cc: Jann Horn <jannh@google.com> |
| Cc: Kees Cook <keescook@chromium.org> |
| Cc: Oleg Nesterov <oleg@redhat.com> |
| Cc: Serge E. Hallyn <serge@hallyn.com> |
| Cc: Tyler Hicks <tyhicks@linux.microsoft.com> |
| Cc: stable@vger.kernel.org |
| Fixes: 6b3ad6649a4c ("ptrace: reintroduce usage of subjective credentials in ptrace_has_cap()") |
| Fixes: 69f594a38967 ("ptrace: do not audit capability check when outputing /proc/pid/stat") |
| Signed-off-by: Mickaël Salaün <mic@linux.microsoft.com> |
| Reviewed-by: Jann Horn <jannh@google.com> |
| Signed-off-by: Kees Cook <keescook@chromium.org> |
| Link: https://lore.kernel.org/r/20201030123849.770769-2-mic@digikod.net |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| kernel/ptrace.c | 16 +++++----------- |
| 1 file changed, 5 insertions(+), 11 deletions(-) |
| |
| --- a/kernel/ptrace.c |
| +++ b/kernel/ptrace.c |
| @@ -258,17 +258,11 @@ static int ptrace_check_attach(struct ta |
| return ret; |
| } |
| |
| -static bool ptrace_has_cap(const struct cred *cred, struct user_namespace *ns, |
| - unsigned int mode) |
| +static bool ptrace_has_cap(struct user_namespace *ns, unsigned int mode) |
| { |
| - int ret; |
| - |
| if (mode & PTRACE_MODE_NOAUDIT) |
| - ret = security_capable(cred, ns, CAP_SYS_PTRACE, CAP_OPT_NOAUDIT); |
| - else |
| - ret = security_capable(cred, ns, CAP_SYS_PTRACE, CAP_OPT_NONE); |
| - |
| - return ret == 0; |
| + return ns_capable_noaudit(ns, CAP_SYS_PTRACE); |
| + return ns_capable(ns, CAP_SYS_PTRACE); |
| } |
| |
| /* Returns 0 on success, -errno on denial. */ |
| @@ -320,7 +314,7 @@ static int __ptrace_may_access(struct ta |
| gid_eq(caller_gid, tcred->sgid) && |
| gid_eq(caller_gid, tcred->gid)) |
| goto ok; |
| - if (ptrace_has_cap(cred, tcred->user_ns, mode)) |
| + if (ptrace_has_cap(tcred->user_ns, mode)) |
| goto ok; |
| rcu_read_unlock(); |
| return -EPERM; |
| @@ -339,7 +333,7 @@ ok: |
| mm = task->mm; |
| if (mm && |
| ((get_dumpable(mm) != SUID_DUMP_USER) && |
| - !ptrace_has_cap(cred, mm->user_ns, mode))) |
| + !ptrace_has_cap(mm->user_ns, mode))) |
| return -EPERM; |
| |
| return security_ptrace_access_check(task, mode); |