All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] x86/vsyscall/64: Drop "native" vsyscalls
@ 2018-03-07 19:12 Andy Lutomirski
  2018-03-07 19:21 ` Kees Cook
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Andy Lutomirski @ 2018-03-07 19:12 UTC (permalink / raw)
  To: x86, LKML
  Cc: Linus Torvalds, Kernel Hardening, Borislav Petkov, Kees Cook,
	Dominik Brodowski, Andy Lutomirski

Since Linux 3.2, vsyscalls have been deprecated and slow.  From 3.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: Andy Lutomirski <luto@kernel.org>
---
 arch/x86/Kconfig                            | 11 +----------
 arch/x86/entry/vsyscall/vsyscall_64.c       | 16 +++-------------
 arch/x86/include/asm/pgtable_types.h        |  2 --
 tools/testing/selftests/x86/test_vsyscall.c | 11 ++++++-----
 4 files changed, 10 insertions(+), 30 deletions(-)

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index eb7f43f23521..0fa71a78ec99 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -2307,7 +2307,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
@@ -2315,15 +2315,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
diff --git a/arch/x86/entry/vsyscall/vsyscall_64.c b/arch/x86/entry/vsyscall/vsyscall_64.c
index 577fa8adb785..8560ef68a9d6 100644
--- a/arch/x86/entry/vsyscall/vsyscall_64.c
+++ b/arch/x86/entry/vsyscall/vsyscall_64.c
@@ -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);
 	}
 
diff --git a/arch/x86/include/asm/pgtable_types.h b/arch/x86/include/asm/pgtable_types.h
index 246f15b4e64c..acfe755562a6 100644
--- a/arch/x86/include/asm/pgtable_types.h
+++ b/arch/x86/include/asm/pgtable_types.h
@@ -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)
diff --git a/tools/testing/selftests/x86/test_vsyscall.c b/tools/testing/selftests/x86/test_vsyscall.c
index be81621446f0..0b4f1cc2291c 100644
--- a/tools/testing/selftests/x86/test_vsyscall.c
+++ b/tools/testing/selftests/x86/test_vsyscall.c
@@ -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;
-- 
2.14.3

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH] x86/vsyscall/64: Drop "native" vsyscalls
  2018-03-07 19:12 [PATCH] x86/vsyscall/64: Drop "native" vsyscalls Andy Lutomirski
@ 2018-03-07 19:21 ` Kees Cook
  2018-03-07 19:31   ` Dominik Brodowski
  2018-03-07 19:23 ` Linus Torvalds
  2018-03-08  7:49 ` [tip:x86/pti] " tip-bot for Andy Lutomirski
  2 siblings, 1 reply; 6+ messages in thread
From: Kees Cook @ 2018-03-07 19:21 UTC (permalink / raw)
  To: Andy Lutomirski
  Cc: X86 ML, LKML, Linus Torvalds, Kernel Hardening, Borislav Petkov,
	Dominik Brodowski

On Wed, Mar 7, 2018 at 11:12 AM, Andy Lutomirski <luto@kernel.org> wrote:
> Since Linux 3.2, vsyscalls have been deprecated and slow.  From 3.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: Andy Lutomirski <luto@kernel.org>

Acked-by: Kees Cook <keescook@chromium.org>

I related news, I wonder how long before we can switch from EMULATE to
NONE as the default? glibc 2.15 (which stopped using vsyscall) is (not
coincidentally) 6 years old too...

-Kees

> ---
>  arch/x86/Kconfig                            | 11 +----------
>  arch/x86/entry/vsyscall/vsyscall_64.c       | 16 +++-------------
>  arch/x86/include/asm/pgtable_types.h        |  2 --
>  tools/testing/selftests/x86/test_vsyscall.c | 11 ++++++-----
>  4 files changed, 10 insertions(+), 30 deletions(-)
>
> diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
> index eb7f43f23521..0fa71a78ec99 100644
> --- a/arch/x86/Kconfig
> +++ b/arch/x86/Kconfig
> @@ -2307,7 +2307,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
> @@ -2315,15 +2315,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
> diff --git a/arch/x86/entry/vsyscall/vsyscall_64.c b/arch/x86/entry/vsyscall/vsyscall_64.c
> index 577fa8adb785..8560ef68a9d6 100644
> --- a/arch/x86/entry/vsyscall/vsyscall_64.c
> +++ b/arch/x86/entry/vsyscall/vsyscall_64.c
> @@ -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);
>         }
>
> diff --git a/arch/x86/include/asm/pgtable_types.h b/arch/x86/include/asm/pgtable_types.h
> index 246f15b4e64c..acfe755562a6 100644
> --- a/arch/x86/include/asm/pgtable_types.h
> +++ b/arch/x86/include/asm/pgtable_types.h
> @@ -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)
> diff --git a/tools/testing/selftests/x86/test_vsyscall.c b/tools/testing/selftests/x86/test_vsyscall.c
> index be81621446f0..0b4f1cc2291c 100644
> --- a/tools/testing/selftests/x86/test_vsyscall.c
> +++ b/tools/testing/selftests/x86/test_vsyscall.c
> @@ -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;
> --
> 2.14.3
>



-- 
Kees Cook
Pixel Security

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] x86/vsyscall/64: Drop "native" vsyscalls
  2018-03-07 19:12 [PATCH] x86/vsyscall/64: Drop "native" vsyscalls Andy Lutomirski
  2018-03-07 19:21 ` Kees Cook
@ 2018-03-07 19:23 ` Linus Torvalds
  2018-03-08  7:49 ` [tip:x86/pti] " tip-bot for Andy Lutomirski
  2 siblings, 0 replies; 6+ messages in thread
From: Linus Torvalds @ 2018-03-07 19:23 UTC (permalink / raw)
  To: Andy Lutomirski
  Cc: the arch/x86 maintainers, LKML, Kernel Hardening,
	Borislav Petkov, Kees Cook, Dominik Brodowski

On Wed, Mar 7, 2018 at 11:12 AM, Andy Lutomirski <luto@kernel.org> wrote:
>
> 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.

Ack.

I guess we';ll hear if anybody might still use it and cares, but..

               Linus

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] x86/vsyscall/64: Drop "native" vsyscalls
  2018-03-07 19:21 ` Kees Cook
@ 2018-03-07 19:31   ` Dominik Brodowski
  2018-03-07 19:32     ` Andy Lutomirski
  0 siblings, 1 reply; 6+ messages in thread
From: Dominik Brodowski @ 2018-03-07 19:31 UTC (permalink / raw)
  To: Kees Cook
  Cc: Andy Lutomirski, X86 ML, LKML, Linus Torvalds, Kernel Hardening,
	Borislav Petkov

On Wed, Mar 07, 2018 at 11:21:46AM -0800, Kees Cook wrote:
> On Wed, Mar 7, 2018 at 11:12 AM, Andy Lutomirski <luto@kernel.org> wrote:
> > Since Linux 3.2, vsyscalls have been deprecated and slow.  From 3.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: Andy Lutomirski <luto@kernel.org>
> 
> Acked-by: Kees Cook <keescook@chromium.org>
> 
> I related news, I wonder how long before we can switch from EMULATE to
> NONE as the default? glibc 2.15 (which stopped using vsyscall) is (not
> coincidentally) 6 years old too...

Or, in the meantime, add a warning

        if (vsyscall_mode == EMULATE) {
                warn_bad_vsyscall(KERN_INFO, regs,
                                  "vsyscalls are deprecated -- use vDSO instead");
        }

Otherwise, the patch looks good.

Thanks,
	Dominik

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] x86/vsyscall/64: Drop "native" vsyscalls
  2018-03-07 19:31   ` Dominik Brodowski
@ 2018-03-07 19:32     ` Andy Lutomirski
  0 siblings, 0 replies; 6+ messages in thread
From: Andy Lutomirski @ 2018-03-07 19:32 UTC (permalink / raw)
  To: Dominik Brodowski
  Cc: Kees Cook, Andy Lutomirski, X86 ML, LKML, Linus Torvalds,
	Kernel Hardening, Borislav Petkov

On Wed, Mar 7, 2018 at 7:31 PM, Dominik Brodowski
<linux@dominikbrodowski.net> wrote:
> On Wed, Mar 07, 2018 at 11:21:46AM -0800, Kees Cook wrote:
>> On Wed, Mar 7, 2018 at 11:12 AM, Andy Lutomirski <luto@kernel.org> wrote:
>> > Since Linux 3.2, vsyscalls have been deprecated and slow.  From 3.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: Andy Lutomirski <luto@kernel.org>
>>
>> Acked-by: Kees Cook <keescook@chromium.org>
>>
>> I related news, I wonder how long before we can switch from EMULATE to
>> NONE as the default? glibc 2.15 (which stopped using vsyscall) is (not
>> coincidentally) 6 years old too...
>
> Or, in the meantime, add a warning
>
>         if (vsyscall_mode == EMULATE) {
>                 warn_bad_vsyscall(KERN_INFO, regs,
>                                   "vsyscalls are deprecated -- use vDSO instead");
>         }
>
> Otherwise, the patch looks good.
>

I'm not sure the warning buys us anything.  AFAICT there are no modern
toolchains in any language that will use vsyscalls.  The problem is
old binaries.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [tip:x86/pti] x86/vsyscall/64: Drop "native" vsyscalls
  2018-03-07 19:12 [PATCH] x86/vsyscall/64: Drop "native" vsyscalls Andy Lutomirski
  2018-03-07 19:21 ` Kees Cook
  2018-03-07 19:23 ` Linus Torvalds
@ 2018-03-08  7:49 ` tip-bot for Andy Lutomirski
  2 siblings, 0 replies; 6+ messages in thread
From: tip-bot for Andy Lutomirski @ 2018-03-08  7:49 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: keescook, linux-kernel, kernel-hardening, mingo, hpa, luto,
	torvalds, linux, peterz, tglx, bp

Commit-ID:  076ca272a14cea558b1092ec85cea08510283f2a
Gitweb:     https://git.kernel.org/tip/076ca272a14cea558b1092ec85cea08510283f2a
Author:     Andy Lutomirski <luto@kernel.org>
AuthorDate: Wed, 7 Mar 2018 11:12:27 -0800
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Thu, 8 Mar 2018 06:48:15 +0100

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: Andy Lutomirski <luto@kernel.org>
Acked-by: Kees Cook <keescook@chromium.org>
Acked-by: Linus 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: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/Kconfig                            | 11 +----------
 arch/x86/entry/vsyscall/vsyscall_64.c       | 16 +++-------------
 arch/x86/include/asm/pgtable_types.h        |  2 --
 tools/testing/selftests/x86/test_vsyscall.c | 11 ++++++-----
 4 files changed, 10 insertions(+), 30 deletions(-)

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index c1aed6c0e413..09c599e0900d 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -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
diff --git a/arch/x86/entry/vsyscall/vsyscall_64.c b/arch/x86/entry/vsyscall/vsyscall_64.c
index 577fa8adb785..8560ef68a9d6 100644
--- a/arch/x86/entry/vsyscall/vsyscall_64.c
+++ b/arch/x86/entry/vsyscall/vsyscall_64.c
@@ -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);
 	}
 
diff --git a/arch/x86/include/asm/pgtable_types.h b/arch/x86/include/asm/pgtable_types.h
index 246f15b4e64c..acfe755562a6 100644
--- a/arch/x86/include/asm/pgtable_types.h
+++ b/arch/x86/include/asm/pgtable_types.h
@@ -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)
diff --git a/tools/testing/selftests/x86/test_vsyscall.c b/tools/testing/selftests/x86/test_vsyscall.c
index be81621446f0..0b4f1cc2291c 100644
--- a/tools/testing/selftests/x86/test_vsyscall.c
+++ b/tools/testing/selftests/x86/test_vsyscall.c
@@ -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;

^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2018-03-08  7:50 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-03-07 19:12 [PATCH] x86/vsyscall/64: Drop "native" vsyscalls Andy Lutomirski
2018-03-07 19:21 ` Kees Cook
2018-03-07 19:31   ` Dominik Brodowski
2018-03-07 19:32     ` Andy Lutomirski
2018-03-07 19:23 ` Linus Torvalds
2018-03-08  7:49 ` [tip:x86/pti] " tip-bot for Andy Lutomirski

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.