diff options
author | Ben Hutchings <ben@decadent.org.uk> | 2018-03-09 00:11:14 +0000 |
---|---|---|
committer | Ben Hutchings <ben@decadent.org.uk> | 2018-03-19 18:59:13 +0000 |
commit | 8c34712ac217fff16d0d225bd48d68af40c33038 (patch) | |
tree | 5aeb585662e4678ba359ce367507b763862cabf7 /include/linux | |
parent | 49731da00f0f2160cdcaeaf2daa711f6b7061663 (diff) | |
download | linux-stable-8c34712ac217fff16d0d225bd48d68af40c33038.tar.gz linux-stable-8c34712ac217fff16d0d225bd48d68af40c33038.tar.bz2 linux-stable-8c34712ac217fff16d0d225bd48d68af40c33038.zip |
x86/syscall: Sanitize syscall table de-references under speculation
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.
The ia32 compat syscall table lookup on x86_64 is also written in
assembly, so I've added the same masking in ia32entry.S, using r8 as
the temporary since it is always clobbered by the following
instructions.
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>
Diffstat (limited to 'include/linux')
0 files changed, 0 insertions, 0 deletions