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

Commit b0b49f26 authored by Andy Lutomirski's avatar Andy Lutomirski Committed by H. Peter Anvin
Browse files

x86, vdso: Remove compat vdso support



The compat vDSO is a complicated hack that's needed to maintain
compatibility with a small range of glibc versions.

This removes it and replaces it with a much simpler hack: a config
option to disable the 32-bit vDSO by default.

This also changes the default value of CONFIG_COMPAT_VDSO to n --
users configuring kernels from scratch almost certainly want that
choice.

Signed-off-by: default avatarAndy Lutomirski <luto@amacapital.net>
Link: http://lkml.kernel.org/r/4bb4690899106eb11430b1186d5cc66ca9d1660c.1394751608.git.luto@amacapital.net


Signed-off-by: default avatarH. Peter Anvin <hpa@linux.intel.com>
parent fa389e22
Loading
Loading
Loading
Loading
+16 −6
Original line number Original line Diff line number Diff line
@@ -3409,14 +3409,24 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
					of CONFIG_HIGHPTE.
					of CONFIG_HIGHPTE.


	vdso=		[X86,SH]
	vdso=		[X86,SH]
			vdso=2: enable compat VDSO (default with COMPAT_VDSO)
			On X86_32, this is an alias for vdso32=.  Otherwise:
			vdso=1: enable VDSO (default)

			vdso=1: enable VDSO (the default)
			vdso=0: disable VDSO mapping
			vdso=0: disable VDSO mapping


	vdso32=		[X86]
	vdso32=		[X86] Control the 32-bit vDSO
			vdso32=2: enable compat VDSO (default with COMPAT_VDSO)
			vdso32=1: enable 32-bit VDSO
			vdso32=1: enable 32-bit VDSO (default)
			vdso32=0 or vdso32=2: disable 32-bit VDSO
			vdso32=0: disable 32-bit VDSO mapping

			See the help text for CONFIG_COMPAT_VDSO for more
			details.  If CONFIG_COMPAT_VDSO is set, the default is
			vdso32=0; otherwise, the default is vdso32=1.

			For compatibility with older kernels, vdso32=2 is an
			alias for vdso32=0.

			Try vdso32=0 if you encounter an error that says:
			dl_main: Assertion `(void *) ph->p_vaddr == _rtld_local._dl_sysinfo_dso' failed!


	vector=		[IA-64,SMP]
	vector=		[IA-64,SMP]
			vector=percpu: enable percpu vector domain
			vector=percpu: enable percpu vector domain
+19 −7
Original line number Original line Diff line number Diff line
@@ -1836,17 +1836,29 @@ config DEBUG_HOTPLUG_CPU0
	  If unsure, say N.
	  If unsure, say N.


config COMPAT_VDSO
config COMPAT_VDSO
	def_bool y
	def_bool n
	prompt "Compat VDSO support"
	prompt "Disable the 32-bit vDSO (needed for glibc 2.3.3)"
	depends on X86_32 || IA32_EMULATION
	depends on X86_32 || IA32_EMULATION
	---help---
	---help---
	  Map the 32-bit VDSO to the predictable old-style address too.
	  Certain buggy versions of glibc will crash if they are
	  presented with a 32-bit vDSO that is not mapped at the address
	  indicated in its segment table.


	  Say N here if you are running a sufficiently recent glibc
	  The bug was introduced by f866314b89d56845f55e6f365e18b31ec978ec3a
	  version (2.3.3 or later), to remove the high-mapped
	  and fixed by 3b3ddb4f7db98ec9e912ccdf54d35df4aa30e04a and
	  VDSO mapping and to exclusively use the randomized VDSO.
	  49ad572a70b8aeb91e57483a11dd1b77e31c4468.  Glibc 2.3.3 is
	  the only released version with the bug, but OpenSUSE 9
	  contains a buggy "glibc 2.3.2".


	  If unsure, say Y.
	  The symptom of the bug is that everything crashes on startup, saying:
	  dl_main: Assertion `(void *) ph->p_vaddr == _rtld_local._dl_sysinfo_dso' failed!

	  Saying Y here changes the default value of the vdso32 boot
	  option from 1 to 0, which turns off the 32-bit vDSO entirely.
	  This works around the glibc bug but hurts performance.

	  If unsure, say N: if you are compiling your own kernel, you
	  are unlikely to be using a buggy version of glibc.


config CMDLINE_BOOL
config CMDLINE_BOOL
	bool "Built-in kernel command line"
	bool "Built-in kernel command line"
+0 −4
Original line number Original line Diff line number Diff line
@@ -281,16 +281,12 @@ do { \


#define STACK_RND_MASK (0x7ff)
#define STACK_RND_MASK (0x7ff)


#define VDSO_HIGH_BASE		(__fix_to_virt(FIX_VDSO))

#define ARCH_DLINFO		ARCH_DLINFO_IA32(vdso_enabled)
#define ARCH_DLINFO		ARCH_DLINFO_IA32(vdso_enabled)


/* update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes */
/* update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes */


#else /* CONFIG_X86_32 */
#else /* CONFIG_X86_32 */


#define VDSO_HIGH_BASE		0xffffe000U /* CONFIG_COMPAT_VDSO address */

/* 1GB for 64bit, 8MB for 32bit */
/* 1GB for 64bit, 8MB for 32bit */
#define STACK_RND_MASK (test_thread_flag(TIF_ADDR32) ? 0x7ff : 0x3fffff)
#define STACK_RND_MASK (test_thread_flag(TIF_ADDR32) ? 0x7ff : 0x3fffff)


+0 −8
Original line number Original line Diff line number Diff line
@@ -40,15 +40,8 @@
 */
 */
extern unsigned long __FIXADDR_TOP;
extern unsigned long __FIXADDR_TOP;
#define FIXADDR_TOP	((unsigned long)__FIXADDR_TOP)
#define FIXADDR_TOP	((unsigned long)__FIXADDR_TOP)

#define FIXADDR_USER_START     __fix_to_virt(FIX_VDSO)
#define FIXADDR_USER_END       __fix_to_virt(FIX_VDSO - 1)
#else
#else
#define FIXADDR_TOP	(VSYSCALL_END-PAGE_SIZE)
#define FIXADDR_TOP	(VSYSCALL_END-PAGE_SIZE)

/* Only covers 32bit vsyscalls currently. Need another set for 64bit. */
#define FIXADDR_USER_START	((unsigned long)VSYSCALL32_VSYSCALL)
#define FIXADDR_USER_END	(FIXADDR_USER_START + PAGE_SIZE)
#endif
#endif




@@ -74,7 +67,6 @@ extern unsigned long __FIXADDR_TOP;
enum fixed_addresses {
enum fixed_addresses {
#ifdef CONFIG_X86_32
#ifdef CONFIG_X86_32
	FIX_HOLE,
	FIX_HOLE,
	FIX_VDSO,
#else
#else
	VSYSCALL_LAST_PAGE,
	VSYSCALL_LAST_PAGE,
	VSYSCALL_FIRST_PAGE = VSYSCALL_LAST_PAGE
	VSYSCALL_FIRST_PAGE = VSYSCALL_LAST_PAGE
+1 −4
Original line number Original line Diff line number Diff line
@@ -2,8 +2,6 @@
#define _ASM_X86_VDSO_H
#define _ASM_X86_VDSO_H


#if defined CONFIG_X86_32 || defined CONFIG_COMPAT
#if defined CONFIG_X86_32 || defined CONFIG_COMPAT
extern const char VDSO32_PRELINK[];

/*
/*
 * Given a pointer to the vDSO image, find the pointer to VDSO32_name
 * Given a pointer to the vDSO image, find the pointer to VDSO32_name
 * as that symbol is defined in the vDSO sources or linker script.
 * as that symbol is defined in the vDSO sources or linker script.
@@ -11,8 +9,7 @@ extern const char VDSO32_PRELINK[];
#define VDSO32_SYMBOL(base, name)					\
#define VDSO32_SYMBOL(base, name)					\
({									\
({									\
	extern const char VDSO32_##name[];				\
	extern const char VDSO32_##name[];				\
	(void __user *)(VDSO32_##name - VDSO32_PRELINK +		\
	(void __user *)(VDSO32_##name + (unsigned long)(base));		\
			(unsigned long)(base));				\
})
})
#endif
#endif


Loading