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

Commit e6e5494c authored by Ingo Molnar's avatar Ingo Molnar Committed by Linus Torvalds
Browse files

[PATCH] vdso: randomize the i386 vDSO by moving it into a vma



Move the i386 VDSO down into a vma and thus randomize it.

Besides the security implications, this feature also helps debuggers, which
can COW a vma-backed VDSO just like a normal DSO and can thus do
single-stepping and other debugging features.

It's good for hypervisors (Xen, VMWare) too, which typically live in the same
high-mapped address space as the VDSO, hence whenever the VDSO is used, they
get lots of guest pagefaults and have to fix such guest accesses up - which
slows things down instead of speeding things up (the primary purpose of the
VDSO).

There's a new CONFIG_COMPAT_VDSO (default=y) option, which provides support
for older glibcs that still rely on a prelinked high-mapped VDSO.  Newer
distributions (using glibc 2.3.3 or later) can turn this option off.  Turning
it off is also recommended for security reasons: attackers cannot use the
predictable high-mapped VDSO page as syscall trampoline anymore.

There is a new vdso=[0|1] boot option as well, and a runtime
/proc/sys/vm/vdso_enabled sysctl switch, that allows the VDSO to be turned
on/off.

(This version of the VDSO-randomization patch also has working ELF
coredumping, the previous patch crashed in the coredumping code.)

This code is a combined work of the exec-shield VDSO randomization
code and Gerd Hoffmann's hypervisor-centric VDSO patch. Rusty Russell
started this patch and i completed it.

[akpm@osdl.org: cleanups]
[akpm@osdl.org: compile fix]
[akpm@osdl.org: compile fix 2]
[akpm@osdl.org: compile fix 3]
[akpm@osdl.org: revernt MAXMEM change]
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
Signed-off-by: default avatarArjan van de Ven <arjan@infradead.org>
Cc: Gerd Hoffmann <kraxel@suse.de>
Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: Zachary Amsden <zach@vmware.com>
Cc: Andi Kleen <ak@muc.de>
Cc: Jan Beulich <jbeulich@novell.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent d5fb3426
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -1669,6 +1669,10 @@ running once the system is up.
	usbhid.mousepoll=
			[USBHID] The interval which mice are to be polled at.

	vdso=		[IA-32]
			vdso=1: enable VDSO (default)
			vdso=0: disable VDSO mapping

	video=		[FB] Frame buffer configuration
			See Documentation/fb/modedb.txt.

+11 −0
Original line number Diff line number Diff line
@@ -780,6 +780,17 @@ config HOTPLUG_CPU
	  enable suspend on SMP systems. CPUs can be controlled through
	  /sys/devices/system/cpu.

config COMPAT_VDSO
	bool "Compat VDSO support"
	default y
	help
	  Map the VDSO to the predictable old-style address too.
	---help---
	  Say N here if you are running a sufficiently recent glibc
	  version (2.3.3 or later), to remove the high-mapped
	  VDSO mapping and to exclusively use the randomized VDSO.

	  If unsure, say Y.

endmenu

+3 −1
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@
#include <asm/fixmap.h>
#include <asm/processor.h>
#include <asm/thread_info.h>
#include <asm/elf.h>

#define DEFINE(sym, val) \
        asm volatile("\n->" #sym " %0 " #val : : "i" (val))
@@ -54,6 +55,7 @@ void foo(void)
	OFFSET(TI_preempt_count, thread_info, preempt_count);
	OFFSET(TI_addr_limit, thread_info, addr_limit);
	OFFSET(TI_restart_block, thread_info, restart_block);
	OFFSET(TI_sysenter_return, thread_info, sysenter_return);
	BLANK();

	OFFSET(EXEC_DOMAIN_handler, exec_domain, handler);
@@ -69,7 +71,7 @@ void foo(void)
		 sizeof(struct tss_struct));

	DEFINE(PAGE_SIZE_asm, PAGE_SIZE);
	DEFINE(VSYSCALL_BASE, __fix_to_virt(FIX_VSYSCALL));
	DEFINE(VDSO_PRELINK, VDSO_PRELINK);

	OFFSET(crypto_tfm_ctx_offset, crypto_tfm, __crt_ctx);
}
+6 −1
Original line number Diff line number Diff line
@@ -270,7 +270,12 @@ sysenter_past_esp:
	pushl $(__USER_CS)
	CFI_ADJUST_CFA_OFFSET 4
	/*CFI_REL_OFFSET cs, 0*/
	pushl $SYSENTER_RETURN
	/*
	 * Push current_thread_info()->sysenter_return to the stack.
	 * A tiny bit of offset fixup is necessary - 4*4 means the 4 words
	 * pushed above; +8 corresponds to copy_thread's esp0 setting.
	 */
	pushl (TI_sysenter_return-THREAD_SIZE+8+4*4)(%esp)
	CFI_ADJUST_CFA_OFFSET 4
	CFI_REL_OFFSET eip, 0

+2 −2
Original line number Diff line number Diff line
@@ -351,7 +351,7 @@ static int setup_frame(int sig, struct k_sigaction *ka,
			goto give_sigsegv;
	}

	restorer = &__kernel_sigreturn;
	restorer = (void *)VDSO_SYM(&__kernel_sigreturn);
	if (ka->sa.sa_flags & SA_RESTORER)
		restorer = ka->sa.sa_restorer;

@@ -447,7 +447,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
		goto give_sigsegv;

	/* Set up to return from userspace.  */
	restorer = &__kernel_rt_sigreturn;
	restorer = (void *)VDSO_SYM(&__kernel_rt_sigreturn);
	if (ka->sa.sa_flags & SA_RESTORER)
		restorer = ka->sa.sa_restorer;
	err |= __put_user(restorer, &frame->pretcode);
Loading