Patch "binfmt_elf: use ELF_ET_DYN_BASE only for PIE" has been added to the 4.9-stable tree
Subsystems (4)
This is a note to let you know that I've just added the patch titled
binfmt_elf: use ELF_ET_DYN_BASE only for PIE
to the 4.9-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
binfmt_elf-use-elf_et_dyn_base-only-for-pie.patch
and it can be found in the queue-4.9 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
eab09532d40090698b05a07c1c87f39fdbc5fab5Mon Sep 17 00:00:00 2001
From: Kees Cook <[email protected]>
Date: Mon, 10 Jul 2017 15:52:37 -0700
Subject: binfmt_elf: use ELF_ET_DYN_BASE only for PIE
From: Kees Cook <[email protected]>
commit eab09532d40090698b05a07c1c87f39fdbc5fab5 upstream.
The ELF_ET_DYN_BASE position was originally intended to keep loaders away from ET_EXEC binaries. (For example, running "/lib/ld-linux.so.2 /bin/cat" might cause the subsequent load of /bin/cat into where the loader had been loaded.)
With the advent of PIE (ET_DYN binaries with an INTERP Program Header), ELF_ET_DYN_BASE continued to be used since the kernel was only looking at ET_DYN. However, since ELF_ET_DYN_BASE is traditionally set at the top 1/3rd of the TASK_SIZE, a substantial portion of the address space is unused.
For 32-bit tasks when RLIMIT_STACK is set to RLIM_INFINITY, programs are loaded above the mmap region. This means they can be made to collide (CVE-2017-1000370) or nearly collide (CVE-2017-1000371) with pathological stack regions.
Lowering ELF_ET_DYN_BASE solves both by moving programs below the mmap region in all cases, and will now additionally avoid programs falling back to the mmap region by enforcing MAP_FIXED for program loads (i.e. if it would have collided with the stack, now it will fail to load instead of falling back to the mmap region).
To allow for a lower ELF_ET_DYN_BASE, loaders (ET_DYN without INTERP) are loaded into the mmap region, leaving space available for either an ET_EXEC binary with a fixed location or PIE being loaded into mmap by the loader. Only PIE programs are loaded offset from ELF_ET_DYN_BASE, which means architectures can now safely lower their values without risk of loaders colliding with their subsequently loaded programs.
For 64-bit, ELF_ET_DYN_BASE is best set to 4GB to allow runtimes to use the entire 32-bit address space for 32-bit pointers.
Thanks to PaX Team, Daniel Micay, and Rik van Riel for inspiration and suggestions on how to implement this solution.
--- arch/x86/include/asm/elf.h | 13 +++++---- fs/binfmt_elf.c | 59 ++++++++++++++++++++++++++++++++++++++------- 2 files changed, 58 insertions(+), 14 deletions(-)
arch/x86/include/asm/elf.h +7 -6
@@ -245,12 +245,13 @@ extern int force_personality32;#define CORE_DUMP_USE_REGSET #define ELF_EXEC_PAGESIZE 4096 -/* This is the location that an ET_DYN program is loaded if exec'ed. Typical -use of this is to invoke "./ld.so someprog" to test out a new version of -the loader. We need to make sure that it is out of the way of the program -that it will "exec", and that there is sufficient room for the brk. */ - -#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2) +/* +* This is the base location for PIE (ET_DYN with INTERP) loads. On +* 64-bit, this is raised to 4GB to leave the entire 32-bit address +* space open for things that want to use the area for 32-bit pointers. +*/ +#define ELF_ET_DYN_BASE (mmap_is_ia32() ? 0x000400000UL : \ + 0x100000000UL)/* This yields a mask that user programs can use to figure out what instruction set this CPU supports. This could be done in user space,
fs/binfmt_elf.c +51 -8
68 lines not on this page · raw message
Patches currently in stable-queue which might be from [email protected] are
queue-4.9/binfmt_elf-use-elf_et_dyn_base-only-for-pie.patch queue-4.9/exec-limit-arg-stack-to-at-most-75-of-_stk_lim.patch queue-4.9/s390-reduce-elf_et_dyn_base.patch queue-4.9/arm-move-elf_et_dyn_base-to-4mb.patch queue-4.9/arm64-move-elf_et_dyn_base-to-4gb-4mb.patch queue-4.9/selftests-capabilities-fix-the-test_execve-test.patch queue-4.9/powerpc-move-elf_et_dyn_base-to-4gb-4mb.patch