• Kees Cook's avatar
    binfmt_elf: use ELF_ET_DYN_BASE only for PIE · 9b1bbf6e
    Kees Cook authored
    commit eab09532 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.
    
    Fixes: d1fd836d ("mm: split ET_DYN ASLR from mmap ASLR")
    Link: http://lkml.kernel.org/r/20170621173201.GA114489@beastSigned-off-by: default avatarKees Cook <keescook@chromium.org>
    Acked-by: default avatarRik van Riel <riel@redhat.com>
    Cc: Daniel Micay <danielmicay@gmail.com>
    Cc: Qualys Security Advisory <qsa@qualys.com>
    Cc: Thomas Gleixner <tglx@linutronix.de>
    Cc: Ingo Molnar <mingo@redhat.com>
    Cc: "H. Peter Anvin" <hpa@zytor.com>
    Cc: Alexander Viro <viro@zeniv.linux.org.uk>
    Cc: Dmitry Safonov <dsafonov@virtuozzo.com>
    Cc: Andy Lutomirski <luto@amacapital.net>
    Cc: Grzegorz Andrejczuk <grzegorz.andrejczuk@intel.com>
    Cc: Masahiro Yamada <yamada.masahiro@socionext.com>
    Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
    Cc: Catalin Marinas <catalin.marinas@arm.com>
    Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
    Cc: James Hogan <james.hogan@imgtec.com>
    Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
    Cc: Michael Ellerman <mpe@ellerman.id.au>
    Cc: Paul Mackerras <paulus@samba.org>
    Cc: Pratyush Anand <panand@redhat.com>
    Cc: Russell King <linux@armlinux.org.uk>
    Cc: Will Deacon <will.deacon@arm.com>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    9b1bbf6e
binfmt_elf.c 62.9 KB