Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 076ca272 authored by Andy Lutomirski's avatar Andy Lutomirski Committed by Ingo Molnar
Browse files

x86/vsyscall/64: Drop "native" vsyscalls



Since Linux v3.2, vsyscalls have been deprecated and slow.  From v3.2
on, Linux had three vsyscall modes: "native", "emulate", and "none".

"emulate" is the default.  All known user programs work correctly in
emulate mode, but vsyscalls turn into page faults and are emulated.
This is very slow.  In "native" mode, the vsyscall page is easily
usable as an exploit gadget, but vsyscalls are a bit faster -- they
turn into normal syscalls.  (This is in contrast to vDSO functions,
which can be much faster than syscalls.)  In "none" mode, there are
no vsyscalls.

For all practical purposes, "native" was really just a chicken bit
in case something went wrong with the emulation.  It's been over six
years, and nothing has gone wrong.  Delete it.

Signed-off-by: default avatarAndy Lutomirski <luto@kernel.org>
Acked-by: default avatarKees Cook <keescook@chromium.org>
Acked-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Dominik Brodowski <linux@dominikbrodowski.net>
Cc: Kernel Hardening <kernel-hardening@lists.openwall.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/519fee5268faea09ae550776ce969fa6e88668b0.1520449896.git.luto@kernel.org


Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
parent 91c5f0de
Loading
Loading
Loading
Loading
+1 −10
Original line number Diff line number Diff line
@@ -2266,7 +2266,7 @@ choice
	  it can be used to assist security vulnerability exploitation.

	  This setting can be changed at boot time via the kernel command
	  line parameter vsyscall=[native|emulate|none].
	  line parameter vsyscall=[emulate|none].

	  On a system with recent enough glibc (2.14 or newer) and no
	  static binaries, you can say None without a performance penalty
@@ -2274,15 +2274,6 @@ choice

	  If unsure, select "Emulate".

	config LEGACY_VSYSCALL_NATIVE
		bool "Native"
		help
		  Actual executable code is located in the fixed vsyscall
		  address mapping, implementing time() efficiently. Since
		  this makes the mapping executable, it can be used during
		  security vulnerability exploitation (traditionally as
		  ROP gadgets). This configuration is not recommended.

	config LEGACY_VSYSCALL_EMULATE
		bool "Emulate"
		help
+3 −13
Original line number Diff line number Diff line
@@ -42,10 +42,8 @@
#define CREATE_TRACE_POINTS
#include "vsyscall_trace.h"

static enum { EMULATE, NATIVE, NONE } vsyscall_mode =
#if defined(CONFIG_LEGACY_VSYSCALL_NATIVE)
	NATIVE;
#elif defined(CONFIG_LEGACY_VSYSCALL_NONE)
static enum { EMULATE, NONE } vsyscall_mode =
#ifdef CONFIG_LEGACY_VSYSCALL_NONE
	NONE;
#else
	EMULATE;
@@ -56,8 +54,6 @@ static int __init vsyscall_setup(char *str)
	if (str) {
		if (!strcmp("emulate", str))
			vsyscall_mode = EMULATE;
		else if (!strcmp("native", str))
			vsyscall_mode = NATIVE;
		else if (!strcmp("none", str))
			vsyscall_mode = NONE;
		else
@@ -139,10 +135,6 @@ bool emulate_vsyscall(struct pt_regs *regs, unsigned long address)

	WARN_ON_ONCE(address != regs->ip);

	/* This should be unreachable in NATIVE mode. */
	if (WARN_ON(vsyscall_mode == NATIVE))
		return false;

	if (vsyscall_mode == NONE) {
		warn_bad_vsyscall(KERN_INFO, regs,
				  "vsyscall attempted with vsyscall=none");
@@ -370,9 +362,7 @@ void __init map_vsyscall(void)

	if (vsyscall_mode != NONE) {
		__set_fixmap(VSYSCALL_PAGE, physaddr_vsyscall,
			     vsyscall_mode == NATIVE
			     ? PAGE_KERNEL_VSYSCALL
			     : PAGE_KERNEL_VVAR);
			     PAGE_KERNEL_VVAR);
		set_vsyscall_pgtable_user_bits(swapper_pg_dir);
	}

+0 −2
Original line number Diff line number Diff line
@@ -174,7 +174,6 @@ enum page_cache_mode {
#define __PAGE_KERNEL_RO		(__PAGE_KERNEL & ~_PAGE_RW)
#define __PAGE_KERNEL_RX		(__PAGE_KERNEL_EXEC & ~_PAGE_RW)
#define __PAGE_KERNEL_NOCACHE		(__PAGE_KERNEL | _PAGE_NOCACHE)
#define __PAGE_KERNEL_VSYSCALL		(__PAGE_KERNEL_RX | _PAGE_USER)
#define __PAGE_KERNEL_VVAR		(__PAGE_KERNEL_RO | _PAGE_USER)
#define __PAGE_KERNEL_LARGE		(__PAGE_KERNEL | _PAGE_PSE)
#define __PAGE_KERNEL_LARGE_EXEC	(__PAGE_KERNEL_EXEC | _PAGE_PSE)
@@ -206,7 +205,6 @@ enum page_cache_mode {
#define PAGE_KERNEL_NOCACHE	__pgprot(__PAGE_KERNEL_NOCACHE | _PAGE_ENC)
#define PAGE_KERNEL_LARGE	__pgprot(__PAGE_KERNEL_LARGE | _PAGE_ENC)
#define PAGE_KERNEL_LARGE_EXEC	__pgprot(__PAGE_KERNEL_LARGE_EXEC | _PAGE_ENC)
#define PAGE_KERNEL_VSYSCALL	__pgprot(__PAGE_KERNEL_VSYSCALL | _PAGE_ENC)
#define PAGE_KERNEL_VVAR	__pgprot(__PAGE_KERNEL_VVAR | _PAGE_ENC)

#define PAGE_KERNEL_IO		__pgprot(__PAGE_KERNEL_IO)
+6 −5
Original line number Diff line number Diff line
@@ -450,7 +450,7 @@ static void sigtrap(int sig, siginfo_t *info, void *ctx_void)
		num_vsyscall_traps++;
}

static int test_native_vsyscall(void)
static int test_emulation(void)
{
	time_t tmp;
	bool is_native;
@@ -458,7 +458,7 @@ static int test_native_vsyscall(void)
	if (!vtime)
		return 0;

	printf("[RUN]\tchecking for native vsyscall\n");
	printf("[RUN]\tchecking that vsyscalls are emulated\n");
	sethandler(SIGTRAP, sigtrap, 0);
	set_eflags(get_eflags() | X86_EFLAGS_TF);
	vtime(&tmp);
@@ -474,11 +474,12 @@ static int test_native_vsyscall(void)
	 */
	is_native = (num_vsyscall_traps > 1);

	printf("\tvsyscalls are %s (%d instructions in vsyscall page)\n",
	printf("[%s]\tvsyscalls are %s (%d instructions in vsyscall page)\n",
	       (is_native ? "FAIL" : "OK"),
	       (is_native ? "native" : "emulated"),
	       (int)num_vsyscall_traps);

	return 0;
	return is_native;
}
#endif

@@ -498,7 +499,7 @@ int main(int argc, char **argv)
	nerrs += test_vsys_r();

#ifdef __x86_64__
	nerrs += test_native_vsyscall();
	nerrs += test_emulation();
#endif

	return nerrs ? 1 : 0;