From: Ben Hutchings <ben@decadent.org.uk>
To: linux-kernel@vger.kernel.org, stable@vger.kernel.org
Cc: akpm@linux-foundation.org,
Jinpu Wang <jinpu.wang@profitbricks.com>,
kernel-hardening@lists.openwall.com, Jiri Slaby <jslaby@suse.cz>,
Andy Lutomirski <luto@kernel.org>,
Linus Torvalds <torvalds@linux-foundation.org>,
Jan Beulich <JBeulich@suse.com>,
alan@linux.intel.com, Thomas Gleixner <tglx@linutronix.de>,
Dan Williams <dan.j.williams@intel.com>,
gregkh@linuxfoundation.org, linux-arch@vger.kernel.org
Subject: [PATCH 3.16 56/76] x86/syscall: Sanitize syscall table de-references under speculation
Date: Mon, 12 Mar 2018 03:06:12 +0000 [thread overview]
Message-ID: <lsq.1520823972.93871245@decadent.org.uk> (raw)
In-Reply-To: <lsq.1520823971.5976735@decadent.org.uk>
3.16.56-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Ben Hutchings <ben@decadent.org.uk>
commit 2fbd7af5af8665d18bcefae3e9700be07e22b681 upstream.
The upstream version of this, touching C code, was written by Dan Williams,
with the following description:
> The syscall table base is a user controlled function pointer in kernel
> space. Use array_index_nospec() to prevent any out of bounds speculation.
>
> While retpoline prevents speculating into a userspace directed target it
> does not stop the pointer de-reference, the concern is leaking memory
> relative to the syscall table base, by observing instruction cache
> behavior.
The x86_64 assembly version for 4.4 was written by Jiri Slaby, with
the following description:
> In 4.4.118, we have commit c8961332d6da (x86/syscall: Sanitize syscall
> table de-references under speculation), which is a backport of upstream
> commit 2fbd7af5af86. But it fixed only the C part of the upstream patch
> -- the IA32 sysentry. So it ommitted completely the assembly part -- the
> 64bit sysentry.
>
> Fix that in this patch by explicit array_index_mask_nospec written in
> assembly. The same was used in lib/getuser.S.
>
> However, to have "sbb" working properly, we have to switch from "cmp"
> against (NR_syscalls-1) to (NR_syscalls), otherwise the last syscall
> number would be "and"ed by 0. It is because the original "ja" relies on
> "CF" or "ZF", but we rely only on "CF" in "sbb". That means: switch to
> "jae" conditional jump too.
>
> Final note: use rcx for mask as this is exactly what is overwritten by
> the 4th syscall argument (r10) right after.
In 3.16 the x86_32 syscall table lookup is also written in assembly.
So I've taken Jiri's version and added similar masking in entry_32.S,
using edx as the temporary. edx is clobbered by SAVE_REGS and seems
to be free at this point.
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: Jiri Slaby <jslaby@suse.cz>
Cc: Jan Beulich <JBeulich@suse.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-arch@vger.kernel.org
Cc: kernel-hardening@lists.openwall.com
Cc: gregkh@linuxfoundation.org
Cc: Andy Lutomirski <luto@kernel.org>
Cc: alan@linux.intel.com
Cc: Jinpu Wang <jinpu.wang@profitbricks.com>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
--- a/arch/x86/kernel/entry_32.S
+++ b/arch/x86/kernel/entry_32.S
@@ -426,6 +426,8 @@ sysenter_past_esp:
sysenter_do_call:
cmpl $(NR_syscalls), %eax
jae sysenter_badsys
+ sbb %edx, %edx /* array_index_mask_nospec() */
+ and %edx, %eax
call *sys_call_table(,%eax,4)
sysenter_after_call:
movl %eax,PT_EAX(%esp)
@@ -503,6 +505,8 @@ ENTRY(system_call)
cmpl $(NR_syscalls), %eax
jae syscall_badsys
syscall_call:
+ sbb %edx, %edx /* array_index_mask_nospec() */
+ and %edx, %eax
call *sys_call_table(,%eax,4)
syscall_after_call:
movl %eax,PT_EAX(%esp) # store the return value
--- a/arch/x86/kernel/entry_64.S
+++ b/arch/x86/kernel/entry_64.S
@@ -445,12 +445,14 @@ GLOBAL(system_call_after_swapgs)
jnz tracesys
system_call_fastpath:
#if __SYSCALL_MASK == ~0
- cmpq $__NR_syscall_max,%rax
+ cmpq $NR_syscalls, %rax
#else
andl $__SYSCALL_MASK,%eax
- cmpl $__NR_syscall_max,%eax
+ cmpl $NR_syscalls, %eax
#endif
- ja badsys
+ jae badsys
+ sbb %rcx, %rcx /* array_index_mask_nospec() */
+ and %rcx, %rax
movq %r10,%rcx
#ifdef CONFIG_RETPOLINE
movq sys_call_table(, %rax, 8), %rax
@@ -577,12 +579,14 @@ tracesys:
LOAD_ARGS ARGOFFSET, 1
RESTORE_REST
#if __SYSCALL_MASK == ~0
- cmpq $__NR_syscall_max,%rax
+ cmpq $NR_syscalls, %rax
#else
andl $__SYSCALL_MASK,%eax
- cmpl $__NR_syscall_max,%eax
+ cmpl $NR_syscalls, %eax
#endif
- ja int_ret_from_sys_call /* RAX(%rsp) set to -ENOSYS above */
+ jae int_ret_from_sys_call /* RAX(%rsp) set to -ENOSYS above */
+ sbb %rcx, %rcx /* array_index_mask_nospec() */
+ and %rcx, %rax
movq %r10,%rcx /* fixup for C */
#ifdef CONFIG_RETPOLINE
movq sys_call_table(, %rax, 8), %rax
next prev parent reply other threads:[~2018-03-12 3:06 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <lsq.1520823971.5976735@decadent.org.uk>
2018-03-12 3:06 ` [PATCH 3.16 57/76] vfs, fdtable: Prevent bounds-check bypass via speculative execution Ben Hutchings
2018-03-12 3:06 ` Ben Hutchings
2018-03-12 3:06 ` [PATCH 3.16 69/76] nospec: Kill array_index_nospec_mask_check() Ben Hutchings
2018-03-12 3:06 ` Ben Hutchings
2018-03-12 3:06 ` Ben Hutchings [this message]
2018-03-12 3:06 ` [PATCH 3.16 56/76] x86/syscall: Sanitize syscall table de-references under speculation Ben Hutchings
2018-03-12 7:32 ` Jiri Slaby
2018-03-12 7:32 ` Jiri Slaby
2018-03-19 0:59 ` Ben Hutchings
2018-03-19 0:59 ` Ben Hutchings
2018-03-12 3:06 ` [PATCH 3.16 51/76] Documentation: Document array_index_nospec Ben Hutchings
2018-03-12 3:06 ` Ben Hutchings
2018-03-12 3:06 ` [PATCH 3.16 73/76] x86: Introduce __uaccess_begin_nospec() and uaccess_try_nospec Ben Hutchings
2018-03-12 3:06 ` Ben Hutchings
2018-03-12 3:06 ` [PATCH 3.16 52/76] array_index_nospec: Sanitize speculative array de-references Ben Hutchings
2018-03-12 3:06 ` Ben Hutchings
2018-03-12 3:06 ` [PATCH 3.16 55/76] x86/get_user: Use pointer masking to limit speculation Ben Hutchings
2018-03-12 3:06 ` Ben Hutchings
2018-03-12 3:06 ` [PATCH 3.16 53/76] x86: Implement array_index_mask_nospec Ben Hutchings
2018-03-12 3:06 ` Ben Hutchings
2018-03-12 3:06 ` [PATCH 3.16 58/76] nl80211: Sanitize array index in parse_txq_params Ben Hutchings
2018-03-12 3:06 ` Ben Hutchings
2018-03-12 3:06 ` [PATCH 3.16 59/76] x86/spectre: Report get_user mitigation for spectre_v1 Ben Hutchings
2018-03-12 3:06 ` Ben Hutchings
2018-03-12 3:06 ` [PATCH 3.16 54/76] x86: Introduce barrier_nospec Ben Hutchings
2018-03-12 3:06 ` Ben Hutchings
2018-03-12 3:06 ` [PATCH 3.16 75/76] x86/uaccess: Use __uaccess_begin_nospec() and uaccess_try_nospec Ben Hutchings
2018-03-12 3:06 ` Ben Hutchings
2018-03-12 3:06 ` [PATCH 3.16 70/76] nospec: Include <asm/barrier.h> dependency Ben Hutchings
2018-03-12 3:06 ` Ben Hutchings
2018-03-12 3:06 ` [PATCH 3.16 74/76] x86/usercopy: Replace open coded stac/clac with __uaccess_{begin, end} Ben Hutchings
2018-03-12 3:06 ` Ben Hutchings
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=lsq.1520823972.93871245@decadent.org.uk \
--to=ben@decadent.org.uk \
--cc=JBeulich@suse.com \
--cc=akpm@linux-foundation.org \
--cc=alan@linux.intel.com \
--cc=dan.j.williams@intel.com \
--cc=gregkh@linuxfoundation.org \
--cc=jinpu.wang@profitbricks.com \
--cc=jslaby@suse.cz \
--cc=kernel-hardening@lists.openwall.com \
--cc=linux-arch@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=luto@kernel.org \
--cc=stable@vger.kernel.org \
--cc=tglx@linutronix.de \
--cc=torvalds@linux-foundation.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox