[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 svn path=/dists/sid/linux/; revision=21634
This commit is contained in:
parent
805abd3343
commit
a718693e7b
|
@ -4,6 +4,12 @@ linux (3.14.13-3) UNRELEASED; urgency=medium
|
|||
* 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@debian.org> Fri, 25 Jul 2014 23:02:24 +0200
|
||||
|
||||
linux (3.14.13-2) unstable; urgency=medium
|
||||
|
|
|
@ -15,7 +15,8 @@ CONFIG_X86_64_ACPI_NUMA=y
|
|||
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
|
||||
|
|
31
debian/patches/bugfix/x86/x86-reject-x32-executables-if-x32-abi-not-supported.patch
vendored
Normal file
31
debian/patches/bugfix/x86/x86-reject-x32-executables-if-x32-abi-not-supported.patch
vendored
Normal file
|
@ -0,0 +1,31 @@
|
|||
From: Ben Hutchings <ben@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@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"
|
|
@ -0,0 +1,203 @@
|
|||
From: Ben Hutchings <ben@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@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
|
|
@ -110,3 +110,5 @@ features/mips/MIPS-Malta-Let-PIIX4-respond-to-PCI-special-cycles.patch
|
|||
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
|
||||
|
|
Loading…
Reference in New Issue