stable.vger.kernel.org archive mirror
 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.4 28/57] binfmt_elf: use ELF_ET_DYN_BASE only for PIE
Date: Wed, 19 Jul 2017 13:12:34 +0200	[thread overview]
Message-ID: <20170719111251.094932467@linuxfoundation.org> (raw)
In-Reply-To: <20170719111249.973558472@linuxfoundation.org>

4.4-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
@@ -905,17 +905,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 11:13 UTC|newest]

Thread overview: 61+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-07-19 11:12 [PATCH 4.4 00/57] 4.4.78-stable review Greg Kroah-Hartman
2017-07-19 11:12 ` [PATCH 4.4 01/57] net_sched: fix error recovery at qdisc creation Greg Kroah-Hartman
2017-07-19 11:12 ` [PATCH 4.4 02/57] net: sched: Fix one possible panic when no destroy callback Greg Kroah-Hartman
2017-07-19 11:12 ` [PATCH 4.4 03/57] net/phy: micrel: configure intterupts after autoneg workaround Greg Kroah-Hartman
2017-07-19 11:12 ` [PATCH 4.4 04/57] ipv6: avoid unregistering inet6_dev for loopback Greg Kroah-Hartman
2017-07-19 11:12 ` [PATCH 4.4 05/57] net: dp83640: Avoid NULL pointer dereference Greg Kroah-Hartman
2017-07-19 11:12 ` [PATCH 4.4 06/57] tcp: reset sk_rx_dst in tcp_disconnect() Greg Kroah-Hartman
2017-07-19 11:12 ` [PATCH 4.4 07/57] net: prevent sign extension in dev_get_stats() Greg Kroah-Hartman
2017-07-19 11:12 ` [PATCH 4.4 08/57] bpf: prevent leaking pointer via xadd on unpriviledged Greg Kroah-Hartman
2017-07-19 11:12 ` [PATCH 4.4 10/57] ipv6: dad: dont remove dynamic addresses if link is down Greg Kroah-Hartman
2017-07-19 11:12 ` [PATCH 4.4 12/57] vrf: fix bug_on triggered by rx when destroying a vrf Greg Kroah-Hartman
2017-07-19 11:12 ` [PATCH 4.4 13/57] rds: tcp: use sock_create_lite() to create the accept socket Greg Kroah-Hartman
2017-07-19 11:12 ` [PATCH 4.4 15/57] cfg80211: Define nla_policy for NL80211_ATTR_LOCAL_MESH_POWER_MODE Greg Kroah-Hartman
2017-07-19 11:12 ` [PATCH 4.4 16/57] cfg80211: Validate frequencies nested in NL80211_ATTR_SCAN_FREQUENCIES Greg Kroah-Hartman
2017-07-19 11:12 ` [PATCH 4.4 17/57] cfg80211: Check if PMKID attribute is of expected size Greg Kroah-Hartman
2017-07-19 11:12 ` [PATCH 4.4 18/57] irqchip/gic-v3: Fix out-of-bound access in gic_set_affinity Greg Kroah-Hartman
2017-07-19 11:12 ` [PATCH 4.4 19/57] parisc: Report SIGSEGV instead of SIGBUS when running out of stack Greg Kroah-Hartman
2017-07-19 11:12 ` [PATCH 4.4 20/57] parisc: use compat_sys_keyctl() Greg Kroah-Hartman
2017-07-19 11:12 ` [PATCH 4.4 21/57] parisc: DMA API: return error instead of BUG_ON for dma ops on non dma devs Greg Kroah-Hartman
2017-07-19 11:12 ` [PATCH 4.4 22/57] parisc/mm: Ensure IRQs are off in switch_mm() Greg Kroah-Hartman
2017-07-19 11:12 ` [PATCH 4.4 23/57] tools/lib/lockdep: Reduce MAX_LOCK_DEPTH to avoid overflowing lock_chain/: Depth Greg Kroah-Hartman
2017-07-19 11:12 ` [PATCH 4.4 24/57] kernel/extable.c: mark core_kernel_text notrace Greg Kroah-Hartman
2017-07-19 11:12 ` [PATCH 4.4 25/57] mm/list_lru.c: fix list_lru_count_node() to be race free Greg Kroah-Hartman
2017-07-19 11:12 ` [PATCH 4.4 26/57] fs/dcache.c: fix spin lockup issue on nlru->lock Greg Kroah-Hartman
2017-07-19 11:12 ` [PATCH 4.4 27/57] checkpatch: silence perl 5.26.0 unescaped left brace warnings Greg Kroah-Hartman
2017-07-19 11:12 ` Greg Kroah-Hartman [this message]
2017-07-19 11:12 ` [PATCH 4.4 29/57] arm: move ELF_ET_DYN_BASE to 4MB Greg Kroah-Hartman
2017-07-19 11:12 ` [PATCH 4.4 30/57] arm64: move ELF_ET_DYN_BASE to 4GB / 4MB Greg Kroah-Hartman
2017-07-19 11:12 ` [PATCH 4.4 31/57] powerpc: " Greg Kroah-Hartman
2017-07-19 11:12 ` [PATCH 4.4 32/57] s390: reduce ELF_ET_DYN_BASE Greg Kroah-Hartman
2017-07-19 11:12 ` [PATCH 4.4 33/57] exec: Limit arg stack to at most 75% of _STK_LIM Greg Kroah-Hartman
2017-07-19 11:12 ` [PATCH 4.4 34/57] vt: fix unchecked __put_user() in tioclinux ioctls Greg Kroah-Hartman
2017-07-19 11:12 ` [PATCH 4.4 35/57] mnt: In umount propagation reparent in a separate pass Greg Kroah-Hartman
2017-07-19 11:12 ` [PATCH 4.4 36/57] mnt: In propgate_umount handle visiting mounts in any order Greg Kroah-Hartman
2017-07-19 11:12 ` [PATCH 4.4 37/57] mnt: Make propagate_umount less slow for overlapping mount propagation trees Greg Kroah-Hartman
2017-07-19 11:12 ` [PATCH 4.4 38/57] selftests/capabilities: Fix the test_execve test Greg Kroah-Hartman
2017-07-19 11:12 ` [PATCH 4.4 39/57] tpm: Get rid of chip->pdev Greg Kroah-Hartman
2017-07-19 11:12 ` [PATCH 4.4 40/57] tpm: Provide strong locking for device removal Greg Kroah-Hartman
2017-07-25 22:56   ` Ben Hutchings
2017-07-26 19:56     ` Greg Kroah-Hartman
2017-07-26 20:03       ` Jason Gunthorpe
2017-07-28 22:42         ` Greg Kroah-Hartman
2017-07-31 22:22           ` Jarkko Sakkinen
2017-08-04 19:59             ` Greg Kroah-Hartman
2017-08-04 21:44               ` Greg Kroah-Hartman
2017-08-06 12:47                 ` Jarkko Sakkinen
2017-08-08 21:05                   ` Jarkko Sakkinen
2017-08-08 21:14                     ` Greg Kroah-Hartman
2017-07-19 11:12 ` [PATCH 4.4 41/57] Add "shutdown" to "struct class" Greg Kroah-Hartman
2017-07-19 11:12 ` [PATCH 4.4 42/57] tpm: Issue a TPM2_Shutdown for TPM2 devices Greg Kroah-Hartman
2017-07-19 11:12 ` [PATCH 4.4 45/57] crypto: atmel - only treat EBUSY as transient if backlog Greg Kroah-Hartman
2017-07-19 11:12 ` [PATCH 4.4 46/57] crypto: sha1-ssse3 - Disable avx2 Greg Kroah-Hartman
2017-07-19 11:12 ` [PATCH 4.4 48/57] sched/topology: Fix overlapping sched_group_mask Greg Kroah-Hartman
2017-07-19 11:12 ` [PATCH 4.4 49/57] sched/topology: Optimize build_group_mask() Greg Kroah-Hartman
2017-07-19 11:12 ` [PATCH 4.4 50/57] PM / wakeirq: Convert to SRCU Greg Kroah-Hartman
2017-07-19 11:12 ` [PATCH 4.4 51/57] PM / QoS: return -EINVAL for bogus strings Greg Kroah-Hartman
2017-07-19 11:12 ` [PATCH 4.4 52/57] tracing: Use SOFTIRQ_OFFSET for softirq dectection for more accurate results Greg Kroah-Hartman
2017-07-19 11:12 ` [PATCH 4.4 53/57] KVM: x86: disable MPX if host did not enable MPX XSAVE features Greg Kroah-Hartman
2017-07-19 11:13 ` [PATCH 4.4 57/57] kvm: vmx: allow host to access guest MSR_IA32_BNDCFGS Greg Kroah-Hartman
2017-07-19 20:33 ` [PATCH 4.4 00/57] 4.4.78-stable review Guenter Roeck
2017-07-19 23:39 ` 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=20170719111251.094932467@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).