binfmt_elf: use ELF_ET_DYN_BASE only for PIE

The ELF_ET_DYN_BASE position was originally intended to keep loaders
away from ET_EXEC binaries.  (For example, running "/lib/
/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.

Fixes: d1fd836dcf00 ("mm: split ET_DYN ASLR from mmap ASLR")
Signed-off-by: Kees Cook <>
Acked-by: Rik van Riel <>
Cc: Daniel Micay <>
Cc: Qualys Security Advisory <>
Cc: Thomas Gleixner <>
Cc: Ingo Molnar <>
Cc: "H. Peter Anvin" <>
Cc: Alexander Viro <>
Cc: Dmitry Safonov <>
Cc: Andy Lutomirski <>
Cc: Grzegorz Andrejczuk <>
Cc: Masahiro Yamada <>
Cc: Benjamin Herrenschmidt <>
Cc: Catalin Marinas <>
Cc: Heiko Carstens <>
Cc: James Hogan <>
Cc: Martin Schwidefsky <>
Cc: Michael Ellerman <>
Cc: Paul Mackerras <>
Cc: Pratyush Anand <>
Cc: Russell King <>
Cc: Will Deacon <>
Cc: <>
Signed-off-by: Andrew Morton <>
Signed-off-by: Linus Torvalds <>
2 files changed