[kernel] r21634 - in dists/sid/linux/debian: . config/kernelarch-x86 patches patches/bugfix/x86 patches/features/x86

Ben Hutchings benh at moszumanska.debian.org
Sun Jul 27 04:08:26 UTC 2014


Author: benh
Date: Sun Jul 27 04:08:25 2014
New Revision: 21634

Log:
[amd64] Enable X86_X32 (Closes: #708070)

- Reject x32 executables if x32 ABI not supported
- Make x32 syscall support conditional on a kernel parameter
- Enable X86_X32_DISABLED so that x32 support must be explicitly enabled

Added:
   dists/sid/linux/debian/patches/bugfix/x86/x86-reject-x32-executables-if-x32-abi-not-supported.patch
   dists/sid/linux/debian/patches/features/x86/x86-make-x32-syscall-support-conditional.patch
Modified:
   dists/sid/linux/debian/changelog
   dists/sid/linux/debian/config/kernelarch-x86/config-arch-64
   dists/sid/linux/debian/patches/series

Modified: dists/sid/linux/debian/changelog
==============================================================================
--- dists/sid/linux/debian/changelog	Fri Jul 25 21:25:34 2014	(r21633)
+++ dists/sid/linux/debian/changelog	Sun Jul 27 04:08:25 2014	(r21634)
@@ -4,6 +4,12 @@
   * Update German debconf template translations (Holger Wansing) (Closes:
     #756049).
 
+  [ Ben Hutchings ]
+  * [amd64] Reject x32 executables if x32 ABI not supported
+  * [amd64] Make x32 syscall support conditional on a kernel parameter
+  * [amd64] Enable X86_X32 (Closes: #708070) and X86_X32_DISABLED.
+    Use the kernel parameter "syscall.x32=y" to enable support for x32.
+
  -- Aurelien Jarno <aurel32 at debian.org>  Fri, 25 Jul 2014 23:02:24 +0200
 
 linux (3.14.13-2) unstable; urgency=medium

Modified: dists/sid/linux/debian/config/kernelarch-x86/config-arch-64
==============================================================================
--- dists/sid/linux/debian/config/kernelarch-x86/config-arch-64	Fri Jul 25 21:25:34 2014	(r21633)
+++ dists/sid/linux/debian/config/kernelarch-x86/config-arch-64	Sun Jul 27 04:08:25 2014	(r21634)
@@ -15,7 +15,8 @@
 CONFIG_NUMA_EMU=y
 CONFIG_PCI_MMCONFIG=y
 CONFIG_ISA_DMA_API=y
-# CONFIG_X86_X32 is not set
+CONFIG_X86_X32=y
+CONFIG_X86_X32_DISABLED=y
 
 ##
 ## file: arch/x86/Kconfig.cpu

Added: dists/sid/linux/debian/patches/bugfix/x86/x86-reject-x32-executables-if-x32-abi-not-supported.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux/debian/patches/bugfix/x86/x86-reject-x32-executables-if-x32-abi-not-supported.patch	Sun Jul 27 04:08:25 2014	(r21634)
@@ -0,0 +1,31 @@
+From: Ben Hutchings <ben at decadent.org.uk>
+Date: Sat, 26 Jul 2014 15:03:11 +0100
+Subject: x86: Reject x32 executables if x32 ABI not supported
+Forwarded: http://mid.gmane.org/1406431195.29010.154.camel@deadeye.wl.decadent.org.uk
+
+It is currently possible to execve() an x32 executable on an x86_64
+kernel that has only ia32 compat enabled.  However all its syscalls
+will fail, even _exit().  This usually causes it to segfault.
+
+Change the ELF compat architecture check so that x32 executables are
+rejected if we don't support the x32 ABI.
+
+Signed-off-by: Ben Hutchings <ben at decadent.org.uk>
+---
+ arch/x86/include/asm/elf.h | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/arch/x86/include/asm/elf.h
++++ b/arch/x86/include/asm/elf.h
+@@ -155,8 +155,9 @@ do {						\
+ #define elf_check_arch(x)			\
+ 	((x)->e_machine == EM_X86_64)
+ 
+-#define compat_elf_check_arch(x)		\
+-	(elf_check_arch_ia32(x) || (x)->e_machine == EM_X86_64)
++#define compat_elf_check_arch(x)					\
++	(elf_check_arch_ia32(x) ||					\
++	 (IS_ENABLED(CONFIG_X86_X32_ABI) && (x)->e_machine == EM_X86_64))
+ 
+ #if __USER32_DS != __USER_DS
+ # error "The following code assumes __USER32_DS == __USER_DS"

Added: dists/sid/linux/debian/patches/features/x86/x86-make-x32-syscall-support-conditional.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux/debian/patches/features/x86/x86-make-x32-syscall-support-conditional.patch	Sun Jul 27 04:08:25 2014	(r21634)
@@ -0,0 +1,203 @@
+From: Ben Hutchings <ben at decadent.org.uk>
+Date: Fri, 25 Jul 2014 01:16:15 +0100
+Subject: x86: Make x32 syscall support conditional on a kernel parameter
+Bug-Debian: https://bugs.debian.org/708070
+
+Enabling x32 in the standard amd64 kernel would increase its attack
+surface while provide no benefit to the vast majority of its users.
+No-one seems interested in regularly checking for vulnerabilities
+specific to x32 (at least no-one with a white hat).
+
+Still, adding another flavour just to turn on x32 seems wasteful.  And
+the only difference on syscall entry is whether we mask the x32 flag
+out of the syscall number before range-checking it.
+
+So replace the mask (andl) instruction with a nop and add a kernel
+parameter "syscall.x32" which allows it to be enabled/disabled at
+boot time.  Add a Kconfig parameter to set the default.
+
+Change the comparison instruction to cmpq, because now the upper 32
+bits may or may not be cleared by the previous instruction.
+
+Signed-off-by: Ben Hutchings <ben at decadent.org.uk>
+---
+ Documentation/kernel-parameters.txt |  4 ++++
+ arch/x86/Kconfig                    |  8 +++++++
+ arch/x86/include/asm/elf.h          |  8 ++++++-
+ arch/x86/kernel/entry_64.S          | 36 ++++++++++++++++++++++---------
+ arch/x86/kernel/syscall_64.c        | 43 +++++++++++++++++++++++++++++++++++++
+ 5 files changed, 88 insertions(+), 11 deletions(-)
+
+--- a/Documentation/kernel-parameters.txt
++++ b/Documentation/kernel-parameters.txt
+@@ -3132,6 +3132,10 @@ bytes respectively. Such letter suffixes
+ 
+ 	switches=	[HW,M68k]
+ 
++	syscall.x32=	[KNL,x86_64] Enable/disable use of x32 syscalls on
++			an x86_64 kernel where CONFIG_X86_X32 is enabled.
++			Default depends on CONFIG_X86_X32_DISABLED.
++
+ 	sysfs.deprecated=0|1 [KNL]
+ 			Enable/disable old style sysfs layout for old udev
+ 			on older distributions. When this option is enabled
+--- a/arch/x86/Kconfig
++++ b/arch/x86/Kconfig
+@@ -2383,6 +2383,14 @@ config X86_X32
+ 	  elf32_x86_64 support enabled to compile a kernel with this
+ 	  option set.
+ 
++config X86_X32_DISABLED
++	bool "x32 ABI disabled by default"
++	depends on X86_X32
++	default n
++	help
++	  Disable the x32 ABI unless explicitly enabled using the
++	  kernel paramter "syscall.x32=y".
++
+ config COMPAT
+ 	def_bool y
+ 	depends on IA32_EMULATION || X86_X32
+--- a/arch/x86/include/asm/elf.h
++++ b/arch/x86/include/asm/elf.h
+@@ -149,6 +149,12 @@ do {						\
+ 
+ #else /* CONFIG_X86_32 */
+ 
++#ifdef CONFIG_X86_X32_ABI
++extern bool x32_enabled;
++#else
++#define x32_enabled 0
++#endif
++
+ /*
+  * This is used to ensure we don't load something for the wrong architecture.
+  */
+@@ -157,7 +163,7 @@ do {						\
+ 
+ #define compat_elf_check_arch(x)					\
+ 	(elf_check_arch_ia32(x) ||					\
+-	 (IS_ENABLED(CONFIG_X86_X32_ABI) && (x)->e_machine == EM_X86_64))
++	 (x32_enabled && (x)->e_machine == EM_X86_64))
+ 
+ #if __USER32_DS != __USER_DS
+ # error "The following code assumes __USER32_DS == __USER_DS"
+--- a/arch/x86/kernel/entry_64.S
++++ b/arch/x86/kernel/entry_64.S
+@@ -618,12 +618,14 @@ GLOBAL(system_call_after_swapgs)
+ 	testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags+THREAD_INFO(%rsp,RIP-ARGOFFSET)
+ 	jnz tracesys
+ system_call_fastpath:
+-#if __SYSCALL_MASK == ~0
+-	cmpq $__NR_syscall_max,%rax
+-#else
+-	andl $__SYSCALL_MASK,%eax
+-	cmpl $__NR_syscall_max,%eax
++#if __SYSCALL_MASK != ~0
++	.globl system_call_fast_maybe_mask
++	.globl system_call_fast_masked
++system_call_fast_maybe_mask:
++	.byte P6_NOP5_ATOMIC
++system_call_fast_masked:
+ #endif
++	cmpq $__NR_syscall_max,%rax
+ 	ja badsys
+ 	movq %r10,%rcx
+ 	call *sys_call_table(,%rax,8)  # XXX:	 rip relative
+@@ -737,12 +739,14 @@ tracesys:
+ 	 */
+ 	LOAD_ARGS ARGOFFSET, 1
+ 	RESTORE_REST
+-#if __SYSCALL_MASK == ~0
+-	cmpq $__NR_syscall_max,%rax
+-#else
+-	andl $__SYSCALL_MASK,%eax
+-	cmpl $__NR_syscall_max,%eax
++#if __SYSCALL_MASK != ~0
++	.globl system_call_trace_maybe_mask
++	.globl system_call_trace_masked
++system_call_trace_maybe_mask:
++	.byte P6_NOP5_ATOMIC
++system_call_trace_masked:
+ #endif
++	cmpq $__NR_syscall_max,%rax
+ 	ja   int_ret_from_sys_call	/* RAX(%rsp) set to -ENOSYS above */
+ 	movq %r10,%rcx	/* fixup for C */
+ 	call *sys_call_table(,%rax,8)
+@@ -813,6 +817,18 @@ int_restore_rest:
+ 	CFI_ENDPROC
+ END(system_call)
+ 
++#if __SYSCALL_MASK != ~0
++	/*
++	 * This replaces the nops before the syscall range check
++	 * if syscall.x32 is set
++	 */
++	.globl system_call_mask
++	.globl system_call_mask_end
++system_call_mask:
++	andl $__SYSCALL_MASK,%eax
++system_call_mask_end:
++#endif
++
+ 	.macro FORK_LIKE func
+ ENTRY(stub_\func)
+ 	CFI_STARTPROC
+--- a/arch/x86/kernel/syscall_64.c
++++ b/arch/x86/kernel/syscall_64.c
+@@ -3,8 +3,14 @@
+ #include <linux/linkage.h>
+ #include <linux/sys.h>
+ #include <linux/cache.h>
++#include <linux/moduleparam.h>
++#undef MODULE_PARAM_PREFIX
++#define MODULE_PARAM_PREFIX "syscall."
++#include <linux/bug.h>
++#include <linux/init.h>
+ #include <asm/asm-offsets.h>
+ #include <asm/syscall.h>
++#include <asm/alternative.h>
+ 
+ #define __SYSCALL_COMMON(nr, sym, compat) __SYSCALL_64(nr, sym, compat)
+ 
+@@ -30,3 +36,40 @@ asmlinkage const sys_call_ptr_t sys_call
+ 	[0 ... __NR_syscall_max] = &sys_ni_syscall,
+ #include <asm/syscalls_64.h>
+ };
++
++#ifdef CONFIG_X86_X32_ABI
++
++/* Maybe enable x32 syscalls */
++
++bool x32_enabled = !IS_ENABLED(CONFIG_X86_X32_DISABLED);
++module_param_named(x32, x32_enabled, bool, 0444);
++
++extern char system_call_fast_masked[], system_call_fast_maybe_mask[],
++	system_call_trace_masked[], system_call_trace_maybe_mask[],
++	system_call_mask_end[], system_call_mask[];
++
++static int __init x32_enable(void)
++{
++	BUG_ON(system_call_fast_masked - system_call_fast_maybe_mask != 5);
++	BUG_ON(system_call_trace_masked - system_call_trace_maybe_mask != 5);
++	BUG_ON(system_call_mask_end - system_call_mask != 5);
++
++	if (x32_enabled) {
++		text_poke_early(system_call_fast_maybe_mask,
++				system_call_mask, 5);
++		text_poke_early(system_call_trace_maybe_mask,
++				system_call_mask, 5);
++#ifdef CONFIG_X86_X32_DISABLED
++		pr_info("Enabled x32 syscalls\n");
++#endif
++	}
++#ifndef CONFIG_X86_X32_DISABLED
++	else
++		pr_info("Disabled x32 syscalls\n");
++#endif
++
++	return 0;
++}
++late_initcall(x32_enable);
++
++#endif

Modified: dists/sid/linux/debian/patches/series
==============================================================================
--- dists/sid/linux/debian/patches/series	Fri Jul 25 21:25:34 2014	(r21633)
+++ dists/sid/linux/debian/patches/series	Sun Jul 27 04:08:25 2014	(r21634)
@@ -110,3 +110,5 @@
 features/mips/MIPS-Malta-hang-on-halt.patch
 features/mips/MIPS-Malta-support-powering-down.patch
 features/mips/MIPS-Loongson-3-Add-Loongson-LS3A-RS780E-1-way-machi.patch
+bugfix/x86/x86-reject-x32-executables-if-x32-abi-not-supported.patch
+features/x86/x86-make-x32-syscall-support-conditional.patch



More information about the Kernel-svn-changes mailing list