All of lore.kernel.org
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	stable@vger.kernel.org, Kees Cook <keescook@chromium.org>,
	Rik van Riel <riel@redhat.com>,
	Daniel Micay <danielmicay@gmail.com>,
	Qualys Security Advisory <qsa@qualys.com>,
	Thomas Gleixner <tglx@linutronix.de>,
	Ingo Molnar <mingo@redhat.com>, "H. Peter Anvin" <hpa@zytor.com>,
	Alexander Viro <viro@zeniv.linux.org.uk>,
	Dmitry Safonov <dsafonov@virtuozzo.com>,
	Andy Lutomirski <luto@amacapital.net>,
	Grzegorz Andrejczuk <grzegorz.andrejczuk@intel.com>,
	Masahiro Yamada <yamada.masahiro@socionext.com>,
	Benjamin Herrenschmidt <benh@kernel.crashing.org>,
	Catalin Marinas <catalin.marinas@arm.com>,
	Heiko Carstens <heiko.carstens@de.ibm.com>,
	James Hogan <james.hogan@imgtec.com>,
	Martin Schwidefsky <schwidefsky@de.ibm.com>,
	Michael Ellerman <mpe@ellerman.id.au>,
	Paul Mackerras <paulus@samba.org>,
	Pratyush Anand <panand@redhat.com>,
	Russell King <linux@armlinux.org.uk>,
	Will Deacon <will.deacon@arm.com>,
	Andrew Morton <akpm@linux-foundation.org>,
	Linus Torvalds <torvalds@linux-foundation.org>
Subject: [PATCH 4.11 55/88] binfmt_elf: use ELF_ET_DYN_BASE only for PIE
Date: Wed, 19 Jul 2017 12:08:17 +0200	[thread overview]
Message-ID: <20170719100829.273891729@linuxfoundation.org> (raw)
In-Reply-To: <20170719100820.364094938@linuxfoundation.org>

4.11-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Kees Cook <keescook@chromium.org>

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.

Fixes: d1fd836dcf00 ("mm: split ET_DYN ASLR from mmap ASLR")
Link: http://lkml.kernel.org/r/20170621173201.GA114489@beast
Signed-off-by: Kees Cook <keescook@chromium.org>
Acked-by: Rik 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: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

---
 arch/x86/include/asm/elf.h |   13 +++++----
 fs/binfmt_elf.c            |   59 ++++++++++++++++++++++++++++++++++++++-------
 2 files changed, 58 insertions(+), 14 deletions(-)

--- a/arch/x86/include/asm/elf.h
+++ b/arch/x86/include/asm/elf.h
@@ -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,
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -927,17 +927,60 @@ static int load_elf_binary(struct linux_
 		elf_flags = MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE;
 
 		vaddr = elf_ppnt->p_vaddr;
+		/*
+		 * If we are loading ET_EXEC or we have already performed
+		 * the ET_DYN load_addr calculations, proceed normally.
+		 */
 		if (loc->elf_ex.e_type == ET_EXEC || load_addr_set) {
 			elf_flags |= MAP_FIXED;
 		} else if (loc->elf_ex.e_type == ET_DYN) {
-			/* Try and get dynamic programs out of the way of the
-			 * default mmap base, as well as whatever program they
-			 * might try to exec.  This is because the brk will
-			 * follow the loader, and is not movable.  */
-			load_bias = ELF_ET_DYN_BASE - vaddr;
-			if (current->flags & PF_RANDOMIZE)
-				load_bias += arch_mmap_rnd();
-			load_bias = ELF_PAGESTART(load_bias);
+			/*
+			 * This logic is run once for the first LOAD Program
+			 * Header for ET_DYN binaries to calculate the
+			 * randomization (load_bias) for all the LOAD
+			 * Program Headers, and to calculate the entire
+			 * size of the ELF mapping (total_size). (Note that
+			 * load_addr_set is set to true later once the
+			 * initial mapping is performed.)
+			 *
+			 * There are effectively two types of ET_DYN
+			 * binaries: programs (i.e. PIE: ET_DYN with INTERP)
+			 * and loaders (ET_DYN without INTERP, since they
+			 * _are_ the ELF interpreter). The loaders must
+			 * be loaded away from programs since the program
+			 * may otherwise collide with the loader (especially
+			 * for ET_EXEC which does not have a randomized
+			 * position). For example to handle invocations of
+			 * "./ld.so someprog" to test out a new version of
+			 * the loader, the subsequent program that the
+			 * loader loads must avoid the loader itself, so
+			 * they cannot share the same load range. Sufficient
+			 * room for the brk must be allocated with the
+			 * loader as well, since brk must be available with
+			 * the loader.
+			 *
+			 * Therefore, programs are loaded offset from
+			 * ELF_ET_DYN_BASE and loaders are loaded into the
+			 * independently randomized mmap region (0 load_bias
+			 * without MAP_FIXED).
+			 */
+			if (elf_interpreter) {
+				load_bias = ELF_ET_DYN_BASE;
+				if (current->flags & PF_RANDOMIZE)
+					load_bias += arch_mmap_rnd();
+				elf_flags |= MAP_FIXED;
+			} else
+				load_bias = 0;
+
+			/*
+			 * Since load_bias is used for all subsequent loading
+			 * calculations, we must lower it by the first vaddr
+			 * so that the remaining calculations based on the
+			 * ELF vaddrs will be correctly offset. The result
+			 * is then page aligned.
+			 */
+			load_bias = ELF_PAGESTART(load_bias - vaddr);
+
 			total_size = total_mapping_size(elf_phdata,
 							loc->elf_ex.e_phnum);
 			if (!total_size) {

  parent reply	other threads:[~2017-07-19 10:19 UTC|newest]

Thread overview: 81+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-07-19 10:07 [PATCH 4.11 00/88] 4.11.12-stable review Greg Kroah-Hartman
2017-07-19 10:07 ` [PATCH 4.11 01/88] net/phy: micrel: configure intterupts after autoneg workaround Greg Kroah-Hartman
2017-07-19 10:07 ` [PATCH 4.11 02/88] ipv6: avoid unregistering inet6_dev for loopback Greg Kroah-Hartman
2017-07-19 10:07 ` [PATCH 4.11 03/88] netvsc: dont access netdev->num_rx_queues directly Greg Kroah-Hartman
2017-07-19 10:07 ` [PATCH 4.11 04/88] sfc: Fix MCDI command size for filter operations Greg Kroah-Hartman
2017-07-19 10:07 ` [PATCH 4.11 06/88] net: dp83640: Avoid NULL pointer dereference Greg Kroah-Hartman
2017-07-19 10:07 ` [PATCH 4.11 07/88] tcp: reset sk_rx_dst in tcp_disconnect() Greg Kroah-Hartman
2017-07-19 10:07 ` [PATCH 4.11 08/88] net: prevent sign extension in dev_get_stats() Greg Kroah-Hartman
2017-07-19 10:07 ` [PATCH 4.11 09/88] virtio-net: serialize tx routine during reset Greg Kroah-Hartman
2017-07-19 10:07 ` [PATCH 4.11 10/88] net: sched: Fix one possible panic when no destroy callback Greg Kroah-Hartman
2017-07-19 10:07 ` [PATCH 4.11 11/88] mlxsw: spectrum_router: Fix NULL pointer dereference Greg Kroah-Hartman
2017-07-19 10:07 ` [PATCH 4.11 12/88] rocker: move dereference before free Greg Kroah-Hartman
2017-07-19 10:07 ` [PATCH 4.11 13/88] bpf: prevent leaking pointer via xadd on unpriviledged Greg Kroah-Hartman
2017-07-19 10:07 ` [PATCH 4.11 15/88] net/mlx5: Cancel delayed recovery work when unloading the driver Greg Kroah-Hartman
2017-07-19 10:07 ` [PATCH 4.11 16/88] net/mlx5e: Fix TX carrier errors report in get stats ndo Greg Kroah-Hartman
2017-07-19 10:07 ` [PATCH 4.11 17/88] ipv6: dad: dont remove dynamic addresses if link is down Greg Kroah-Hartman
2017-07-19 10:07 ` [PATCH 4.11 18/88] vxlan: fix hlist corruption Greg Kroah-Hartman
2017-07-19 10:07 ` [PATCH 4.11 19/88] geneve: " Greg Kroah-Hartman
2017-07-19 10:07 ` [PATCH 4.11 20/88] net: core: Fix slab-out-of-bounds in netdev_stats_to_stats64 Greg Kroah-Hartman
2017-07-19 10:07 ` [PATCH 4.11 21/88] liquidio: fix bug in soft reset failure detection Greg Kroah-Hartman
2017-07-19 10:07 ` [PATCH 4.11 23/88] vrf: fix bug_on triggered by rx when destroying a vrf Greg Kroah-Hartman
2017-07-19 10:07 ` [PATCH 4.11 24/88] rds: tcp: use sock_create_lite() to create the accept socket Greg Kroah-Hartman
2017-07-19 10:07 ` [PATCH 4.11 25/88] net/mlx5e: Initialize CEEs getpermhwaddr address buffer to 0xff Greg Kroah-Hartman
2017-07-19 10:07 ` [PATCH 4.11 26/88] cxgb4: fix BUG() on interrupt deallocating path of ULD Greg Kroah-Hartman
2017-07-19 10:07 ` [PATCH 4.11 27/88] tap: convert a mutex to a spinlock Greg Kroah-Hartman
2017-07-19 10:07 ` [PATCH 4.11 28/88] bridge: mdb: fix leak on complete_info ptr on fail path Greg Kroah-Hartman
2017-07-19 10:07 ` [PATCH 4.11 30/88] sfc: dont read beyond unicast address list Greg Kroah-Hartman
2017-07-19 10:07 ` [PATCH 4.11 31/88] Adding asm-prototypes.h for genksyms to generate crc Greg Kroah-Hartman
2017-07-19 10:07 ` [PATCH 4.11 32/88] sed regex in Makefile.build requires line break between exported symbols Greg Kroah-Hartman
2017-07-19 10:07 ` [PATCH 4.11 33/88] Adding the type of " Greg Kroah-Hartman
2017-07-19 10:07 ` [PATCH 4.11 34/88] sparc64: Fix gup_huge_pmd Greg Kroah-Hartman
2017-07-19 10:07 ` [PATCH 4.11 35/88] block: Fix a blk_exit_rl() regression Greg Kroah-Hartman
2017-07-19 10:07 ` [PATCH 4.11 36/88] brcmfmac: Fix a memory leak in error handling path in brcmf_cfg80211_attach Greg Kroah-Hartman
2017-07-19 10:07 ` [PATCH 4.11 37/88] brcmfmac: Fix glom_skb leak in brcmf_sdiod_recv_chain Greg Kroah-Hartman
2017-07-19 10:08 ` [PATCH 4.11 38/88] efi: Process the MEMATTR table only if EFI_MEMMAP is enabled Greg Kroah-Hartman
2017-07-19 10:08 ` Greg Kroah-Hartman
2017-07-19 10:08 ` [PATCH 4.11 39/88] cfg80211: Define nla_policy for NL80211_ATTR_LOCAL_MESH_POWER_MODE Greg Kroah-Hartman
2017-07-19 10:08 ` [PATCH 4.11 40/88] cfg80211: Validate frequencies nested in NL80211_ATTR_SCAN_FREQUENCIES Greg Kroah-Hartman
2017-07-19 10:08 ` [PATCH 4.11 41/88] cfg80211: Check if PMKID attribute is of expected size Greg Kroah-Hartman
2017-07-19 10:08 ` [PATCH 4.11 42/88] cfg80211: Check if NAN service ID " Greg Kroah-Hartman
2017-07-19 10:08 ` [PATCH 4.11 43/88] drm/amdgpu/gfx6: properly cache mc_arb_ramcfg Greg Kroah-Hartman
2017-07-19 10:08 ` [PATCH 4.11 44/88] irqchip/gic-v3: Fix out-of-bound access in gic_set_affinity Greg Kroah-Hartman
2017-07-19 10:08 ` [PATCH 4.11 45/88] parisc: Report SIGSEGV instead of SIGBUS when running out of stack Greg Kroah-Hartman
2017-07-19 10:08 ` [PATCH 4.11 46/88] parisc: use compat_sys_keyctl() Greg Kroah-Hartman
2017-07-19 10:08 ` [PATCH 4.11 47/88] parisc: DMA API: return error instead of BUG_ON for dma ops on non dma devs Greg Kroah-Hartman
2017-07-19 10:08 ` [PATCH 4.11 48/88] parisc/mm: Ensure IRQs are off in switch_mm() Greg Kroah-Hartman
2017-07-19 10:08 ` [PATCH 4.11 49/88] tools/lib/lockdep: Reduce MAX_LOCK_DEPTH to avoid overflowing lock_chain/: Depth Greg Kroah-Hartman
2017-07-19 10:08 ` [PATCH 4.11 50/88] thp, mm: fix crash due race in MADV_FREE handling Greg Kroah-Hartman
2017-07-19 10:08 ` [PATCH 4.11 51/88] kernel/extable.c: mark core_kernel_text notrace Greg Kroah-Hartman
2017-07-19 10:08 ` [PATCH 4.11 52/88] mm/list_lru.c: fix list_lru_count_node() to be race free Greg Kroah-Hartman
2017-07-19 10:08 ` [PATCH 4.11 53/88] fs/dcache.c: fix spin lockup issue on nlru->lock Greg Kroah-Hartman
2017-07-19 10:08 ` [PATCH 4.11 54/88] checkpatch: silence perl 5.26.0 unescaped left brace warnings Greg Kroah-Hartman
2017-07-19 10:08 ` Greg Kroah-Hartman [this message]
2017-07-19 10:08 ` [PATCH 4.11 56/88] arm: move ELF_ET_DYN_BASE to 4MB Greg Kroah-Hartman
2017-07-19 10:08 ` [PATCH 4.11 57/88] arm64: move ELF_ET_DYN_BASE to 4GB / 4MB Greg Kroah-Hartman
2017-07-19 10:08 ` [PATCH 4.11 58/88] powerpc: " Greg Kroah-Hartman
2017-07-19 10:08 ` [PATCH 4.11 59/88] s390: reduce ELF_ET_DYN_BASE Greg Kroah-Hartman
2017-07-19 10:08 ` [PATCH 4.11 60/88] exec: Limit arg stack to at most 75% of _STK_LIM Greg Kroah-Hartman
2017-07-19 10:08 ` [PATCH 4.11 61/88] powerpc/kexec: Fix radix to hash kexec due to IAMR/AMOR Greg Kroah-Hartman
2017-07-19 10:08 ` [PATCH 4.11 62/88] ARM64: dts: marvell: armada37xx: Fix timer interrupt specifiers Greg Kroah-Hartman
2017-07-19 10:08 ` [PATCH 4.11 63/88] arm64: Preventing READ_IMPLIES_EXEC propagation Greg Kroah-Hartman
2017-07-19 10:08 ` [PATCH 4.11 64/88] vt: fix unchecked __put_user() in tioclinux ioctls Greg Kroah-Hartman
2017-07-19 10:08 ` [PATCH 4.11 65/88] rcu: Add memory barriers for NOCB leader wakeup Greg Kroah-Hartman
2017-07-19 10:08 ` [PATCH 4.11 66/88] nvmem: core: fix leaks on registration errors Greg Kroah-Hartman
2017-07-19 10:08 ` [PATCH 4.11 67/88] Drivers: hv: vmbus: Close timing hole that can corrupt per-cpu page Greg Kroah-Hartman
2017-07-19 10:08 ` [PATCH 4.11 68/88] mnt: In umount propagation reparent in a separate pass Greg Kroah-Hartman
2017-07-19 10:08 ` [PATCH 4.11 69/88] mnt: In propgate_umount handle visiting mounts in any order Greg Kroah-Hartman
2017-07-19 10:08 ` [PATCH 4.11 70/88] mnt: Make propagate_umount less slow for overlapping mount propagation trees Greg Kroah-Hartman
2017-07-19 10:08 ` [PATCH 4.11 71/88] selftests/capabilities: Fix the test_execve test Greg Kroah-Hartman
2017-07-19 10:08 ` [PATCH 4.11 74/88] crypto: atmel - only treat EBUSY as transient if backlog Greg Kroah-Hartman
2017-07-19 10:08 ` [PATCH 4.11 75/88] crypto: sha1-ssse3 - Disable avx2 Greg Kroah-Hartman
2017-07-19 10:08 ` [PATCH 4.11 78/88] sched/fair, cpumask: Export for_each_cpu_wrap() Greg Kroah-Hartman
2017-07-19 10:08 ` [PATCH 4.11 79/88] sched/topology: Fix building of overlapping sched-groups Greg Kroah-Hartman
2017-07-19 10:08 ` [PATCH 4.11 80/88] sched/topology: Optimize build_group_mask() Greg Kroah-Hartman
2017-07-19 10:08 ` [PATCH 4.11 81/88] sched/topology: Fix overlapping sched_group_mask Greg Kroah-Hartman
2017-07-19 10:08 ` [PATCH 4.11 82/88] PM / wakeirq: Convert to SRCU Greg Kroah-Hartman
2017-07-19 10:08 ` [PATCH 4.11 84/88] PM / QoS: return -EINVAL for bogus strings Greg Kroah-Hartman
2017-07-19 10:08 ` [PATCH 4.11 88/88] kvm: vmx: allow host to access guest MSR_IA32_BNDCFGS Greg Kroah-Hartman
2017-07-19 10:27 ` [PATCH 4.11 00/88] 4.11.12-stable review Greg Kroah-Hartman
2017-07-19 20:34 ` Guenter Roeck
2017-07-19 23:38 ` Shuah Khan

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170719100829.273891729@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=akpm@linux-foundation.org \
    --cc=benh@kernel.crashing.org \
    --cc=catalin.marinas@arm.com \
    --cc=danielmicay@gmail.com \
    --cc=dsafonov@virtuozzo.com \
    --cc=grzegorz.andrejczuk@intel.com \
    --cc=heiko.carstens@de.ibm.com \
    --cc=hpa@zytor.com \
    --cc=james.hogan@imgtec.com \
    --cc=keescook@chromium.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux@armlinux.org.uk \
    --cc=luto@amacapital.net \
    --cc=mingo@redhat.com \
    --cc=mpe@ellerman.id.au \
    --cc=panand@redhat.com \
    --cc=paulus@samba.org \
    --cc=qsa@qualys.com \
    --cc=riel@redhat.com \
    --cc=schwidefsky@de.ibm.com \
    --cc=stable@vger.kernel.org \
    --cc=tglx@linutronix.de \
    --cc=torvalds@linux-foundation.org \
    --cc=viro@zeniv.linux.org.uk \
    --cc=will.deacon@arm.com \
    --cc=yamada.masahiro@socionext.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.