| From: Jann Horn <jannh@google.com> |
| Date: Fri, 5 Oct 2018 15:51:58 -0700 |
| Subject: proc: restrict kernel stack dumps to root |
| |
| commit f8a00cef17206ecd1b30d3d9f99e10d9fa707aa7 upstream. |
| |
| Currently, you can use /proc/self/task/*/stack to cause a stack walk on |
| a task you control while it is running on another CPU. That means that |
| the stack can change under the stack walker. The stack walker does |
| have guards against going completely off the rails and into random |
| kernel memory, but it can interpret random data from your kernel stack |
| as instruction pointers and stack pointers. This can cause exposure of |
| kernel stack contents to userspace. |
| |
| Restrict the ability to inspect kernel stacks of arbitrary tasks to root |
| in order to prevent a local attacker from exploiting racy stack unwinding |
| to leak kernel task stack contents. See the added comment for a longer |
| rationale. |
| |
| There don't seem to be any users of this userspace API that can't |
| gracefully bail out if reading from the file fails. Therefore, I believe |
| that this change is unlikely to break things. In the case that this patch |
| does end up needing a revert, the next-best solution might be to fake a |
| single-entry stack based on wchan. |
| |
| Link: http://lkml.kernel.org/r/20180927153316.200286-1-jannh@google.com |
| Fixes: 2ec220e27f50 ("proc: add /proc/*/stack") |
| Signed-off-by: Jann Horn <jannh@google.com> |
| Acked-by: Kees Cook <keescook@chromium.org> |
| Cc: Alexey Dobriyan <adobriyan@gmail.com> |
| Cc: Ken Chen <kenchen@google.com> |
| Cc: Will Deacon <will.deacon@arm.com> |
| Cc: Laura Abbott <labbott@redhat.com> |
| Cc: Andy Lutomirski <luto@amacapital.net> |
| Cc: Catalin Marinas <catalin.marinas@arm.com> |
| Cc: Josh Poimboeuf <jpoimboe@redhat.com> |
| Cc: Thomas Gleixner <tglx@linutronix.de> |
| Cc: Ingo Molnar <mingo@redhat.com> |
| Cc: "H . Peter Anvin" <hpa@zytor.com> |
| Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| [bwh: Backported to 3.16: adjust context] |
| Signed-off-by: Ben Hutchings <ben@decadent.org.uk> |
| --- |
| fs/proc/base.c | 14 ++++++++++++++ |
| 1 file changed, 14 insertions(+) |
| |
| --- a/fs/proc/base.c |
| +++ b/fs/proc/base.c |
| @@ -273,6 +273,20 @@ static int proc_pid_stack(struct seq_fil |
| int err; |
| int i; |
| |
| + /* |
| + * The ability to racily run the kernel stack unwinder on a running task |
| + * and then observe the unwinder output is scary; while it is useful for |
| + * debugging kernel issues, it can also allow an attacker to leak kernel |
| + * stack contents. |
| + * Doing this in a manner that is at least safe from races would require |
| + * some work to ensure that the remote task can not be scheduled; and |
| + * even then, this would still expose the unwinder as local attack |
| + * surface. |
| + * Therefore, this interface is restricted to root. |
| + */ |
| + if (!file_ns_capable(m->file, &init_user_ns, CAP_SYS_ADMIN)) |
| + return -EACCES; |
| + |
| entries = kmalloc(MAX_STACK_TRACE_DEPTH * sizeof(*entries), GFP_KERNEL); |
| if (!entries) |
| return -ENOMEM; |