Control: tag -1 patch On Thu, 2014-07-24 at 21:47 +0100, Robert de Bath wrote: > On Thu, 24 Jul 2014, Ian Campbell wrote: > > > On Thu, 2014-07-24 at 20:22 +0100, Robert de Bath wrote: > >> On Thu, 24 Jul 2014, Ian Campbell wrote: > >> > > But that's rather different to now enabling x32 in the arch=amd64 kernel > > which is what #708070 is about. Likewise creating a new > > flavour=x86,arch=amd64 kernel. > > > > What the people responsible for the x32 arch on debian-ports do wrt an > > arch=x32 flavour is up to them, but that's the situation analogous to > > what you are referring to. > > > > Ian. > > I was referring to the package that's now called > linux-image-3.14-1-amd64:i386 not linux-image-3.14-1-amd64:amd64 > > The equivalents would be approximatly linux-image-3.14-1-x32:amd64 and > linux-image-3.14-1-x32:i386 not any packages in the new port. [...] No, there should be no extra kernel flavours for i386 or amd64. I had an idea how to unblock this, and finally got round to trying it, and it seems to work. That is, we build in x32 support but require a run-time parameter to enable. So, please try the attached patch (against the sid branch), adding "syscall.x32=y" to the kernel command line. The general instructions for building a patched package are: <http://kernel-handbook.alioth.debian.org/ch-common-tasks.html#s-common-official>. You'll need to follow subsection 4.2.3 and apply the patch like so: patch -p1 < ../x86-syscall-make-x32-syscall-support-conditional.patch quilt push You won't need to change the ABI name. Ben. -- Ben Hutchings Absolutum obsoletum. (If it works, it's out of date.) - Stafford Beer
Index: linux/debian/changelog =================================================================== --- linux/debian/changelog (revision 21631) +++ linux/debian/changelog (working copy) @@ -1,3 +1,11 @@ +linux (3.14.13-2+x32) UNRELEASED; urgency=medium + + [ Ben Hutchings ] + * [amd64] Enable X86_X32 (Closes: #708070) + * [amd64] syscall: Make x32 syscall support conditional on a kernel parameter + + -- Ben Hutchings <ben@decadent.org.uk> Fri, 25 Jul 2014 01:48:06 +0100 + linux (3.14.13-2) unstable; urgency=medium [ Aurelien Jarno ] Index: linux/debian/config/kernelarch-x86/config-arch-64 =================================================================== --- linux/debian/config/kernelarch-x86/config-arch-64 (revision 21631) +++ linux/debian/config/kernelarch-x86/config-arch-64 (working copy) @@ -15,7 +15,7 @@ CONFIG_NUMA_EMU=y CONFIG_PCI_MMCONFIG=y CONFIG_ISA_DMA_API=y -# CONFIG_X86_X32 is not set +CONFIG_X86_X32=y ## ## file: arch/x86/Kconfig.cpu Index: linux/debian/patches/features/x86/x86-syscall-make-x32-syscall-support-conditional.patch =================================================================== --- linux/debian/patches/features/x86/x86-syscall-make-x32-syscall-support-conditional.patch (revision 0) +++ linux/debian/patches/features/x86/x86-syscall-make-x32-syscall-support-conditional.patch (working copy) @@ -0,0 +1,140 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Fri, 25 Jul 2014 01:16:15 +0100 +Subject: x86/syscall: 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 turned back on again. + +Change the comparison instruction to cmpq because the upper 32 bits +may or may not be cleared by the previous instruction. + +--- 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,13 @@ + #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 <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 +35,42 @@ 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 */ ++ ++static bool x32_enabled = false; ++ ++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 ++set_x32_enabled(const char *val, const struct kernel_param *kp) ++{ ++ int ret = param_set_bool(val, kp); ++ ++ 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); ++ pr_info("Enabled x32 syscalls\n"); ++ } ++ ++ return ret; ++} ++ ++static const struct kernel_param_ops x32_enabled_ops = { ++ .get = param_get_bool, ++ .set = set_x32_enabled ++}; ++ ++late_param_cb(x32, &x32_enabled_ops, &x32_enabled, 0444); ++ ++#endif Index: linux/debian/patches/series =================================================================== --- linux/debian/patches/series (revision 21631) +++ linux/debian/patches/series (working copy) @@ -110,3 +110,4 @@ 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 +features/x86/x86-syscall-make-x32-syscall-support-conditional.patch
Attachment:
signature.asc
Description: This is a digitally signed message part