Skip to content

Commit 076ca27

Browse files
amlutoIngo Molnar
authored andcommitted
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 <[email protected]> Acked-by: Kees Cook <[email protected]> Acked-by: Linus Torvalds <[email protected]> Cc: Borislav Petkov <[email protected]> Cc: Dominik Brodowski <[email protected]> Cc: Kernel Hardening <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Thomas Gleixner <[email protected]> Link: http://lkml.kernel.org/r/519fee5268faea09ae550776ce969fa6e88668b0.1520449896.git.luto@kernel.org Signed-off-by: Ingo Molnar <[email protected]>
1 parent 91c5f0d commit 076ca27

File tree

4 files changed

+10
-30
lines changed

4 files changed

+10
-30
lines changed

arch/x86/Kconfig

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2266,23 +2266,14 @@ choice
22662266
it can be used to assist security vulnerability exploitation.
22672267

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

22712271
On a system with recent enough glibc (2.14 or newer) and no
22722272
static binaries, you can say None without a performance penalty
22732273
to improve security.
22742274

22752275
If unsure, select "Emulate".
22762276

2277-
config LEGACY_VSYSCALL_NATIVE
2278-
bool "Native"
2279-
help
2280-
Actual executable code is located in the fixed vsyscall
2281-
address mapping, implementing time() efficiently. Since
2282-
this makes the mapping executable, it can be used during
2283-
security vulnerability exploitation (traditionally as
2284-
ROP gadgets). This configuration is not recommended.
2285-
22862277
config LEGACY_VSYSCALL_EMULATE
22872278
bool "Emulate"
22882279
help

arch/x86/entry/vsyscall/vsyscall_64.c

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,8 @@
4242
#define CREATE_TRACE_POINTS
4343
#include "vsyscall_trace.h"
4444

45-
static enum { EMULATE, NATIVE, NONE } vsyscall_mode =
46-
#if defined(CONFIG_LEGACY_VSYSCALL_NATIVE)
47-
NATIVE;
48-
#elif defined(CONFIG_LEGACY_VSYSCALL_NONE)
45+
static enum { EMULATE, NONE } vsyscall_mode =
46+
#ifdef CONFIG_LEGACY_VSYSCALL_NONE
4947
NONE;
5048
#else
5149
EMULATE;
@@ -56,8 +54,6 @@ static int __init vsyscall_setup(char *str)
5654
if (str) {
5755
if (!strcmp("emulate", str))
5856
vsyscall_mode = EMULATE;
59-
else if (!strcmp("native", str))
60-
vsyscall_mode = NATIVE;
6157
else if (!strcmp("none", str))
6258
vsyscall_mode = NONE;
6359
else
@@ -139,10 +135,6 @@ bool emulate_vsyscall(struct pt_regs *regs, unsigned long address)
139135

140136
WARN_ON_ONCE(address != regs->ip);
141137

142-
/* This should be unreachable in NATIVE mode. */
143-
if (WARN_ON(vsyscall_mode == NATIVE))
144-
return false;
145-
146138
if (vsyscall_mode == NONE) {
147139
warn_bad_vsyscall(KERN_INFO, regs,
148140
"vsyscall attempted with vsyscall=none");
@@ -370,9 +362,7 @@ void __init map_vsyscall(void)
370362

371363
if (vsyscall_mode != NONE) {
372364
__set_fixmap(VSYSCALL_PAGE, physaddr_vsyscall,
373-
vsyscall_mode == NATIVE
374-
? PAGE_KERNEL_VSYSCALL
375-
: PAGE_KERNEL_VVAR);
365+
PAGE_KERNEL_VVAR);
376366
set_vsyscall_pgtable_user_bits(swapper_pg_dir);
377367
}
378368

arch/x86/include/asm/pgtable_types.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,6 @@ enum page_cache_mode {
174174
#define __PAGE_KERNEL_RO (__PAGE_KERNEL & ~_PAGE_RW)
175175
#define __PAGE_KERNEL_RX (__PAGE_KERNEL_EXEC & ~_PAGE_RW)
176176
#define __PAGE_KERNEL_NOCACHE (__PAGE_KERNEL | _PAGE_NOCACHE)
177-
#define __PAGE_KERNEL_VSYSCALL (__PAGE_KERNEL_RX | _PAGE_USER)
178177
#define __PAGE_KERNEL_VVAR (__PAGE_KERNEL_RO | _PAGE_USER)
179178
#define __PAGE_KERNEL_LARGE (__PAGE_KERNEL | _PAGE_PSE)
180179
#define __PAGE_KERNEL_LARGE_EXEC (__PAGE_KERNEL_EXEC | _PAGE_PSE)
@@ -206,7 +205,6 @@ enum page_cache_mode {
206205
#define PAGE_KERNEL_NOCACHE __pgprot(__PAGE_KERNEL_NOCACHE | _PAGE_ENC)
207206
#define PAGE_KERNEL_LARGE __pgprot(__PAGE_KERNEL_LARGE | _PAGE_ENC)
208207
#define PAGE_KERNEL_LARGE_EXEC __pgprot(__PAGE_KERNEL_LARGE_EXEC | _PAGE_ENC)
209-
#define PAGE_KERNEL_VSYSCALL __pgprot(__PAGE_KERNEL_VSYSCALL | _PAGE_ENC)
210208
#define PAGE_KERNEL_VVAR __pgprot(__PAGE_KERNEL_VVAR | _PAGE_ENC)
211209

212210
#define PAGE_KERNEL_IO __pgprot(__PAGE_KERNEL_IO)

tools/testing/selftests/x86/test_vsyscall.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -450,15 +450,15 @@ static void sigtrap(int sig, siginfo_t *info, void *ctx_void)
450450
num_vsyscall_traps++;
451451
}
452452

453-
static int test_native_vsyscall(void)
453+
static int test_emulation(void)
454454
{
455455
time_t tmp;
456456
bool is_native;
457457

458458
if (!vtime)
459459
return 0;
460460

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

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

481-
return 0;
482+
return is_native;
482483
}
483484
#endif
484485

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

500501
#ifdef __x86_64__
501-
nerrs += test_native_vsyscall();
502+
nerrs += test_emulation();
502503
#endif
503504

504505
return nerrs ? 1 : 0;

0 commit comments

Comments
 (0)