From: Kees Cook <keescook@chromium.org>
To: Andy Lutomirski <luto@kernel.org>
Cc: x86@kernel.org, LKML <linux-kernel@vger.kernel.org>,
Florian Weimer <fweimer@redhat.com>, Jann Horn <jannh@google.com>,
Borislav Petkov <bp@alien8.de>,
Kernel Hardening <kernel-hardening@lists.openwall.com>,
Peter Zijlstra <peterz@infradead.org>,
Thomas Gleixner <tglx@linutronix.de>
Subject: Re: [PATCH v2 2/8] x86/vsyscall: Add a new vsyscall=xonly mode
Date: Thu, 27 Jun 2019 10:26:55 -0700 [thread overview]
Message-ID: <201906271026.383D4F5@keescook> (raw)
In-Reply-To: <d17655777c21bc09a7af1bbcf74e6f2b69a51152.1561610354.git.luto@kernel.org>
On Wed, Jun 26, 2019 at 09:45:03PM -0700, Andy Lutomirski wrote:
> With vsyscall emulation on, we still expose a readable vsyscall page
> that contains syscall instructions that validly implement the
> vsyscalls. We need this because certain dynamic binary
> instrumentation tools attempt to read the call targets of call
> instructions in the instrumented code. If the instrumented code
> uses vsyscalls, then the vsyscal page needs to contain readable
> code.
>
> Unfortunately, leaving readable memory at a deterministic address
> can be used to help various ASLR bypasses, so we gain some hardening
> value if we disallow vsyscall reads.
>
> Given how rarely the vsyscall page needs to be readable, add a
> mechanism to make the vsyscall page be execute only.
>
> Cc: Kees Cook <keescook@chromium.org>
> Cc: Borislav Petkov <bp@alien8.de>
> Cc: Kernel Hardening <kernel-hardening@lists.openwall.com>
> Cc: Peter Zijlstra <peterz@infradead.org>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Signed-off-by: Andy Lutomirski <luto@kernel.org>
Reviewed-by: Kees Cook <keescook@chromium.org>
-Kees
> ---
> .../admin-guide/kernel-parameters.txt | 7 +++-
> arch/x86/Kconfig | 33 ++++++++++++++-----
> arch/x86/entry/vsyscall/vsyscall_64.c | 16 +++++++--
> 3 files changed, 44 insertions(+), 12 deletions(-)
>
> diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
> index 0082d1e56999..be8c3a680afa 100644
> --- a/Documentation/admin-guide/kernel-parameters.txt
> +++ b/Documentation/admin-guide/kernel-parameters.txt
> @@ -5100,7 +5100,12 @@
> targets for exploits that can control RIP.
>
> emulate [default] Vsyscalls turn into traps and are
> - emulated reasonably safely.
> + emulated reasonably safely. The vsyscall
> + page is readable.
> +
> + xonly Vsyscalls turn into traps and are
> + emulated reasonably safely. The vsyscall
> + page is not readable.
>
> none Vsyscalls don't work at all. This makes
> them quite hard to use for exploits but
> diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
> index 2bbbd4d1ba31..0182d2c67590 100644
> --- a/arch/x86/Kconfig
> +++ b/arch/x86/Kconfig
> @@ -2293,23 +2293,38 @@ 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=[emulate|none].
> + line parameter vsyscall=[emulate|xonly|none].
>
> On a system with recent enough glibc (2.14 or newer) and no
> static binaries, you can say None without a performance penalty
> to improve security.
>
> - If unsure, select "Emulate".
> + If unsure, select "Emulate execution only".
>
> config LEGACY_VSYSCALL_EMULATE
> - bool "Emulate"
> + bool "Full emulation"
> help
> - The kernel traps and emulates calls into the fixed
> - vsyscall address mapping. This makes the mapping
> - non-executable, but it still contains known contents,
> - which could be used in certain rare security vulnerability
> - exploits. This configuration is recommended when userspace
> - still uses the vsyscall area.
> + The kernel traps and emulates calls into the fixed vsyscall
> + address mapping. This makes the mapping non-executable, but
> + it still contains readable known contents, which could be
> + used in certain rare security vulnerability exploits. This
> + configuration is recommended when using legacy userspace
> + that still uses vsyscalls along with legacy binary
> + instrumentation tools that require code to be readable.
> +
> + An example of this type of legacy userspace is running
> + Pin on an old binary that still uses vsyscalls.
> +
> + config LEGACY_VSYSCALL_XONLY
> + bool "Emulate execution only"
> + help
> + The kernel traps and emulates calls into the fixed vsyscall
> + address mapping and does not allow reads. This
> + configuration is recommended when userspace might use the
> + legacy vsyscall area but support for legacy binary
> + instrumentation of legacy code is not needed. It mitigates
> + certain uses of the vsyscall area as an ASLR-bypassing
> + buffer.
>
> config LEGACY_VSYSCALL_NONE
> bool "None"
> diff --git a/arch/x86/entry/vsyscall/vsyscall_64.c b/arch/x86/entry/vsyscall/vsyscall_64.c
> index d9d81ad7a400..fedd7628f3a6 100644
> --- a/arch/x86/entry/vsyscall/vsyscall_64.c
> +++ b/arch/x86/entry/vsyscall/vsyscall_64.c
> @@ -42,9 +42,11 @@
> #define CREATE_TRACE_POINTS
> #include "vsyscall_trace.h"
>
> -static enum { EMULATE, NONE } vsyscall_mode =
> +static enum { EMULATE, XONLY, NONE } vsyscall_mode =
> #ifdef CONFIG_LEGACY_VSYSCALL_NONE
> NONE;
> +#elif defined(CONFIG_LEGACY_VSYSCALL_XONLY)
> + XONLY;
> #else
> EMULATE;
> #endif
> @@ -54,6 +56,8 @@ static int __init vsyscall_setup(char *str)
> if (str) {
> if (!strcmp("emulate", str))
> vsyscall_mode = EMULATE;
> + else if (!strcmp("xonly", str))
> + vsyscall_mode = XONLY;
> else if (!strcmp("none", str))
> vsyscall_mode = NONE;
> else
> @@ -357,12 +361,20 @@ void __init map_vsyscall(void)
> extern char __vsyscall_page;
> unsigned long physaddr_vsyscall = __pa_symbol(&__vsyscall_page);
>
> - if (vsyscall_mode != NONE) {
> + /*
> + * For full emulation, the page needs to exist for real. In
> + * execute-only mode, there is no PTE at all backing the vsyscall
> + * page.
> + */
> + if (vsyscall_mode == EMULATE) {
> __set_fixmap(VSYSCALL_PAGE, physaddr_vsyscall,
> PAGE_KERNEL_VVAR);
> set_vsyscall_pgtable_user_bits(swapper_pg_dir);
> }
>
> + if (vsyscall_mode == XONLY)
> + gate_vma.vm_flags = VM_EXEC;
> +
> BUILD_BUG_ON((unsigned long)__fix_to_virt(VSYSCALL_PAGE) !=
> (unsigned long)VSYSCALL_ADDR);
> }
> --
> 2.21.0
>
--
Kees Cook
next prev parent reply other threads:[~2019-06-27 17:26 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-06-27 4:45 [PATCH v2 0/8] vsyscall xonly mode Andy Lutomirski
2019-06-27 4:45 ` [PATCH v2 1/8] x86/vsyscall: Remove the vsyscall=native documentation Andy Lutomirski
2019-06-27 17:26 ` Kees Cook
2019-06-27 22:13 ` [tip:x86/entry] Documentation/admin: " tip-bot for Andy Lutomirski
2019-06-27 4:45 ` [PATCH v2 2/8] x86/vsyscall: Add a new vsyscall=xonly mode Andy Lutomirski
2019-06-27 17:26 ` Kees Cook [this message]
2019-06-27 22:13 ` [tip:x86/entry] " tip-bot for Andy Lutomirski
2019-06-27 4:45 ` [PATCH v2 3/8] x86/vsyscall: Show something useful on a read fault Andy Lutomirski
2019-06-27 17:28 ` Kees Cook
2019-06-27 22:14 ` [tip:x86/entry] " tip-bot for Andy Lutomirski
2019-06-27 4:45 ` [PATCH v2 4/8] x86/vsyscall: Document odd SIGSEGV error code for vsyscalls Andy Lutomirski
2019-06-27 17:28 ` Kees Cook
2019-06-27 22:15 ` [tip:x86/entry] " tip-bot for Andy Lutomirski
2019-06-27 4:45 ` [PATCH v2 5/8] selftests/x86/vsyscall: Verify that vsyscall=none blocks execution Andy Lutomirski
2019-06-27 17:29 ` Kees Cook
2019-06-27 22:16 ` [tip:x86/entry] " tip-bot for Andy Lutomirski
2019-06-27 4:45 ` [PATCH v2 6/8] x86/vsyscall: Change the default vsyscall mode to xonly Andy Lutomirski
2019-06-27 17:30 ` Kees Cook
2019-06-27 22:16 ` [tip:x86/entry] " tip-bot for Andy Lutomirski
2019-06-27 4:45 ` [PATCH v2 7/8] x86/vsyscall: Add __ro_after_init to global variables Andy Lutomirski
2019-06-27 17:30 ` Kees Cook
2019-06-27 22:17 ` [tip:x86/entry] " tip-bot for Andy Lutomirski
2019-06-27 4:45 ` [PATCH v2 8/8] selftests/x86: Add a test for process_vm_readv() on the vsyscall page Andy Lutomirski
2019-06-27 17:30 ` Kees Cook
2019-06-27 22:18 ` [tip:x86/entry] " tip-bot for Andy Lutomirski
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=201906271026.383D4F5@keescook \
--to=keescook@chromium.org \
--cc=bp@alien8.de \
--cc=fweimer@redhat.com \
--cc=jannh@google.com \
--cc=kernel-hardening@lists.openwall.com \
--cc=linux-kernel@vger.kernel.org \
--cc=luto@kernel.org \
--cc=peterz@infradead.org \
--cc=tglx@linutronix.de \
--cc=x86@kernel.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