All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/5] Use ELF_ET_DYN_BASE only for PIE
@ 2017-06-23 20:59 Kees Cook
  2017-06-23 20:59 ` [PATCH v2 1/5] binfmt_elf: " Kees Cook
                   ` (5 more replies)
  0 siblings, 6 replies; 29+ messages in thread
From: Kees Cook @ 2017-06-23 20:59 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Kees Cook, Rik van Riel, Ard Biesheuvel, Daniel Micay,
	Qualys Security Advisory, Russell King, Catalin Marinas,
	Will Deacon, Benjamin Herrenschmidt, Paul Mackerras,
	Michael Ellerman, Martin Schwidefsky, Heiko Carstens,
	Thomas Gleixner, Ingo Molnar, H. Peter Anvin, x86,
	Alexander Viro, Pratyush Anand, James Hogan, Dmitry Safonov,
	Grzegorz Andrejczuk, Masahiro Yamada, linux-kernel,
	linux-arm-kernel, linuxppc-dev, linux-s390, linux-fsdevel,
	kernel-hardening

This is v2 (to refresh the 5 patches in -mm) for moving ELF_ET_DYN_BASE
safely lower. Changes are clarifications in the commit logs (suggested
by mpe), a compat think-o fix for arm64 (thanks to Ard), and to add
Rik and mpe's Acks.

Quoting patch 1/5:

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 below 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
above 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. For 32-bit,
4MB is used as the traditional minimum load location, likely to avoid
historically requiring a 4MB page table entry when only a portion of the
first 4MB would be used (since the NULL address is avoided).

Thanks to PaX Team, Daniel Micay, and Rik van Riel for inspiration and
suggestions on how to implement this solution.

-Kees

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [kernel-hardening] [PATCH v2 0/5] Use ELF_ET_DYN_BASE only for PIE
@ 2017-06-23 20:59 Kees Cook
  2017-06-23 20:59 ` [PATCH v2 1/5] binfmt_elf: " Kees Cook
                   ` (5 more replies)
  0 siblings, 6 replies; 29+ messages in thread
From: Kees Cook @ 2017-06-23 20:59 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Kees Cook, Rik van Riel, Ard Biesheuvel, Daniel Micay,
	Qualys Security Advisory, Russell King, Catalin Marinas,
	Will Deacon, Benjamin Herrenschmidt, Paul Mackerras,
	Michael Ellerman, Martin Schwidefsky, Heiko Carstens,
	Thomas Gleixner, Ingo Molnar, H. Peter Anvin, x86,
	Alexander Viro, Pratyush Anand, James Hogan, Dmitry Safonov,
	Grzegorz Andrejczuk, Masahiro Yamada, linux-kernel,
	linux-arm-kernel, linuxppc-dev, linux-s390, linux-fsdevel,
	kernel-hardening

This is v2 (to refresh the 5 patches in -mm) for moving ELF_ET_DYN_BASE
safely lower. Changes are clarifications in the commit logs (suggested
by mpe), a compat think-o fix for arm64 (thanks to Ard), and to add
Rik and mpe's Acks.

Quoting patch 1/5:

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 below 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
above 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. For 32-bit,
4MB is used as the traditional minimum load location, likely to avoid
historically requiring a 4MB page table entry when only a portion of the
first 4MB would be used (since the NULL address is avoided).

Thanks to PaX Team, Daniel Micay, and Rik van Riel for inspiration and
suggestions on how to implement this solution.

-Kees

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH v2 0/5] Use ELF_ET_DYN_BASE only for PIE
@ 2017-06-23 20:59 Kees Cook
  2017-06-23 20:59 ` [PATCH v2 1/5] binfmt_elf: " Kees Cook
                   ` (5 more replies)
  0 siblings, 6 replies; 29+ messages in thread
From: Kees Cook @ 2017-06-23 20:59 UTC (permalink / raw)
  To: linux-arm-kernel

This is v2 (to refresh the 5 patches in -mm) for moving ELF_ET_DYN_BASE
safely lower. Changes are clarifications in the commit logs (suggested
by mpe), a compat think-o fix for arm64 (thanks to Ard), and to add
Rik and mpe's Acks.

Quoting patch 1/5:

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 below 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
above 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. For 32-bit,
4MB is used as the traditional minimum load location, likely to avoid
historically requiring a 4MB page table entry when only a portion of the
first 4MB would be used (since the NULL address is avoided).

Thanks to PaX Team, Daniel Micay, and Rik van Riel for inspiration and
suggestions on how to implement this solution.

-Kees

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH v2 1/5] binfmt_elf: Use ELF_ET_DYN_BASE only for PIE
  2017-06-23 20:59 [PATCH v2 0/5] Use ELF_ET_DYN_BASE only for PIE Kees Cook
@ 2017-06-23 20:59 ` Kees Cook
  2017-06-24 19:16   ` Kees Cook
  2017-06-23 20:59 ` [PATCH v2 2/5] arm: Move ELF_ET_DYN_BASE to 4MB Kees Cook
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 29+ messages in thread
From: Kees Cook @ 2017-06-23 20:59 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Kees Cook, stable, x86, Rik van Riel, Ard Biesheuvel,
	Daniel Micay, Qualys Security Advisory, Russell King,
	Catalin Marinas, Will Deacon, Benjamin Herrenschmidt,
	Paul Mackerras, Michael Ellerman, Martin Schwidefsky,
	Heiko Carstens, Thomas Gleixner, Ingo Molnar, H. Peter Anvin,
	Alexander Viro, Pratyush Anand, James Hogan, Dmitry Safonov,
	Grzegorz Andrejczuk, Masahiro Yamada, linux-kernel,
	linux-arm-kernel, linuxppc-dev, linux-s390, linux-fsdevel,
	kernel-hardening

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 below 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
above 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. For 32-bit,
4MB is used as the traditional minimum load location, likely to avoid
historically requiring a 4MB page table entry when only a portion of the
first 4MB would be used (since the NULL address is avoided).

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")
Cc: stable@vger.kernel.org
Cc: x86@kernel.org
Signed-off-by: Kees Cook <keescook@chromium.org>
Acked-by: Rik van Riel <riel@redhat.com>
---
 arch/x86/include/asm/elf.h | 13 +++++-----
 fs/binfmt_elf.c            | 59 +++++++++++++++++++++++++++++++++++++++-------
 2 files changed, 58 insertions(+), 14 deletions(-)

diff --git a/arch/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h
index e8ab9a46bc68..1c18d83d3f09 100644
--- 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,
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index ef4fb234bb5b..879ff9c7ffd0 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -925,17 +925,60 @@ static int load_elf_binary(struct linux_binprm *bprm)
 		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) {
-- 
2.7.4

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [kernel-hardening] [PATCH v2 1/5] binfmt_elf: Use ELF_ET_DYN_BASE only for PIE
@ 2017-06-23 20:59 ` Kees Cook
  2017-06-24 19:16   ` Kees Cook
  0 siblings, 1 reply; 29+ messages in thread
From: Kees Cook @ 2017-06-23 20:59 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Kees Cook, stable, x86, Rik van Riel, Ard Biesheuvel,
	Daniel Micay, Qualys Security Advisory, Russell King,
	Catalin Marinas, Will Deacon, Benjamin Herrenschmidt,
	Paul Mackerras, Michael Ellerman, Martin Schwidefsky,
	Heiko Carstens, Thomas Gleixner, Ingo Molnar, H. Peter Anvin,
	Alexander Viro, Pratyush Anand, James Hogan, Dmitry Safonov,
	Grzegorz Andrejczuk, Masahiro Yamada, linux-kernel,
	linux-arm-kernel, linuxppc-dev, linux-s390, linux-fsdevel,
	kernel-hardening

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 below 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
above 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. For 32-bit,
4MB is used as the traditional minimum load location, likely to avoid
historically requiring a 4MB page table entry when only a portion of the
first 4MB would be used (since the NULL address is avoided).

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")
Cc: stable@vger.kernel.org
Cc: x86@kernel.org
Signed-off-by: Kees Cook <keescook@chromium.org>
Acked-by: Rik van Riel <riel@redhat.com>
---
 arch/x86/include/asm/elf.h | 13 +++++-----
 fs/binfmt_elf.c            | 59 +++++++++++++++++++++++++++++++++++++++-------
 2 files changed, 58 insertions(+), 14 deletions(-)

diff --git a/arch/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h
index e8ab9a46bc68..1c18d83d3f09 100644
--- 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,
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index ef4fb234bb5b..879ff9c7ffd0 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -925,17 +925,60 @@ static int load_elf_binary(struct linux_binprm *bprm)
 		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) {
-- 
2.7.4

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH v2 1/5] binfmt_elf: Use ELF_ET_DYN_BASE only for PIE
@ 2017-06-23 20:59 ` Kees Cook
  2017-06-24 19:16   ` Kees Cook
  0 siblings, 1 reply; 29+ messages in thread
From: Kees Cook @ 2017-06-23 20:59 UTC (permalink / raw)
  To: linux-arm-kernel

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 below 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
above 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. For 32-bit,
4MB is used as the traditional minimum load location, likely to avoid
historically requiring a 4MB page table entry when only a portion of the
first 4MB would be used (since the NULL address is avoided).

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")
Cc: stable at vger.kernel.org
Cc: x86 at kernel.org
Signed-off-by: Kees Cook <keescook@chromium.org>
Acked-by: Rik van Riel <riel@redhat.com>
---
 arch/x86/include/asm/elf.h | 13 +++++-----
 fs/binfmt_elf.c            | 59 +++++++++++++++++++++++++++++++++++++++-------
 2 files changed, 58 insertions(+), 14 deletions(-)

diff --git a/arch/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h
index e8ab9a46bc68..1c18d83d3f09 100644
--- 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,
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index ef4fb234bb5b..879ff9c7ffd0 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -925,17 +925,60 @@ static int load_elf_binary(struct linux_binprm *bprm)
 		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) {
-- 
2.7.4

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH v2 2/5] arm: Move ELF_ET_DYN_BASE to 4MB
  2017-06-23 20:59 [PATCH v2 0/5] Use ELF_ET_DYN_BASE only for PIE Kees Cook
  2017-06-23 20:59 ` [PATCH v2 1/5] binfmt_elf: " Kees Cook
@ 2017-06-23 20:59 ` Kees Cook
  2017-06-23 20:59 ` [PATCH v2 3/5] arm64: Move ELF_ET_DYN_BASE to 4GB / 4MB Kees Cook
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 29+ messages in thread
From: Kees Cook @ 2017-06-23 20:59 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Kees Cook, stable, Russell King, Rik van Riel, Ard Biesheuvel,
	Daniel Micay, Qualys Security Advisory, Russell King,
	Catalin Marinas, Will Deacon, Benjamin Herrenschmidt,
	Paul Mackerras, Michael Ellerman, Martin Schwidefsky,
	Heiko Carstens, Thomas Gleixner, Ingo Molnar, H. Peter Anvin,
	x86, Alexander Viro, Pratyush Anand, James Hogan, Dmitry Safonov,
	Grzegorz Andrejczuk, Masahiro Yamada, linux-kernel,
	linux-arm-kernel, linuxppc-dev, linux-s390, linux-fsdevel,
	kernel-hardening

Now that explicitly executed loaders are loaded in the mmap region, we
have more freedom to decide where we position PIE binaries in the address
space to avoid possible collisions with mmap or stack regions.

4MB is chosen here mainly to have parity with x86, where this is the
traditional minimum load location, likely to avoid historically requiring
a 4MB page table entry when only a portion of the first 4MB would be used
(since the NULL address is avoided). For ARM the position could be 0x8000,
the standard ET_EXEC load address, but that is needlessly close to the
NULL address, and anyone running PIE on 32-bit ARM will have an MMU, so
the tight mapping is not needed.

Cc: stable@vger.kernel.org
Cc: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 arch/arm/include/asm/elf.h | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/arch/arm/include/asm/elf.h b/arch/arm/include/asm/elf.h
index d2315ffd8f12..f13ae153fb24 100644
--- a/arch/arm/include/asm/elf.h
+++ b/arch/arm/include/asm/elf.h
@@ -112,12 +112,8 @@ int dump_task_regs(struct task_struct *t, elf_gregset_t *elfregs);
 #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. */
+#define ELF_ET_DYN_BASE		0x400000UL
 
 /* When the program starts, a1 contains a pointer to a function to be 
    registered with atexit, as per the SVR4 ABI.  A value of 0 means we 
-- 
2.7.4

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [kernel-hardening] [PATCH v2 2/5] arm: Move ELF_ET_DYN_BASE to 4MB
@ 2017-06-23 20:59 ` Kees Cook
  0 siblings, 0 replies; 29+ messages in thread
From: Kees Cook @ 2017-06-23 20:59 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Kees Cook, stable, Russell King, Rik van Riel, Ard Biesheuvel,
	Daniel Micay, Qualys Security Advisory, Russell King,
	Catalin Marinas, Will Deacon, Benjamin Herrenschmidt,
	Paul Mackerras, Michael Ellerman, Martin Schwidefsky,
	Heiko Carstens, Thomas Gleixner, Ingo Molnar, H. Peter Anvin,
	x86, Alexander Viro, Pratyush Anand, James Hogan, Dmitry Safonov,
	Grzegorz Andrejczuk, Masahiro Yamada, linux-kernel,
	linux-arm-kernel, linuxppc-dev, linux-s390, linux-fsdevel,
	kernel-hardening

Now that explicitly executed loaders are loaded in the mmap region, we
have more freedom to decide where we position PIE binaries in the address
space to avoid possible collisions with mmap or stack regions.

4MB is chosen here mainly to have parity with x86, where this is the
traditional minimum load location, likely to avoid historically requiring
a 4MB page table entry when only a portion of the first 4MB would be used
(since the NULL address is avoided). For ARM the position could be 0x8000,
the standard ET_EXEC load address, but that is needlessly close to the
NULL address, and anyone running PIE on 32-bit ARM will have an MMU, so
the tight mapping is not needed.

Cc: stable@vger.kernel.org
Cc: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 arch/arm/include/asm/elf.h | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/arch/arm/include/asm/elf.h b/arch/arm/include/asm/elf.h
index d2315ffd8f12..f13ae153fb24 100644
--- a/arch/arm/include/asm/elf.h
+++ b/arch/arm/include/asm/elf.h
@@ -112,12 +112,8 @@ int dump_task_regs(struct task_struct *t, elf_gregset_t *elfregs);
 #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. */
+#define ELF_ET_DYN_BASE		0x400000UL
 
 /* When the program starts, a1 contains a pointer to a function to be 
    registered with atexit, as per the SVR4 ABI.  A value of 0 means we 
-- 
2.7.4

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH v2 2/5] arm: Move ELF_ET_DYN_BASE to 4MB
@ 2017-06-23 20:59 ` Kees Cook
  0 siblings, 0 replies; 29+ messages in thread
From: Kees Cook @ 2017-06-23 20:59 UTC (permalink / raw)
  To: linux-arm-kernel

Now that explicitly executed loaders are loaded in the mmap region, we
have more freedom to decide where we position PIE binaries in the address
space to avoid possible collisions with mmap or stack regions.

4MB is chosen here mainly to have parity with x86, where this is the
traditional minimum load location, likely to avoid historically requiring
a 4MB page table entry when only a portion of the first 4MB would be used
(since the NULL address is avoided). For ARM the position could be 0x8000,
the standard ET_EXEC load address, but that is needlessly close to the
NULL address, and anyone running PIE on 32-bit ARM will have an MMU, so
the tight mapping is not needed.

Cc: stable at vger.kernel.org
Cc: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 arch/arm/include/asm/elf.h | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/arch/arm/include/asm/elf.h b/arch/arm/include/asm/elf.h
index d2315ffd8f12..f13ae153fb24 100644
--- a/arch/arm/include/asm/elf.h
+++ b/arch/arm/include/asm/elf.h
@@ -112,12 +112,8 @@ int dump_task_regs(struct task_struct *t, elf_gregset_t *elfregs);
 #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. */
+#define ELF_ET_DYN_BASE		0x400000UL
 
 /* When the program starts, a1 contains a pointer to a function to be 
    registered with atexit, as per the SVR4 ABI.  A value of 0 means we 
-- 
2.7.4

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH v2 3/5] arm64: Move ELF_ET_DYN_BASE to 4GB / 4MB
  2017-06-23 20:59 [PATCH v2 0/5] Use ELF_ET_DYN_BASE only for PIE Kees Cook
  2017-06-23 20:59 ` [PATCH v2 1/5] binfmt_elf: " Kees Cook
  2017-06-23 20:59 ` [PATCH v2 2/5] arm: Move ELF_ET_DYN_BASE to 4MB Kees Cook
@ 2017-06-23 20:59 ` Kees Cook
  2017-06-23 20:59 ` [PATCH v2 4/5] powerpc: " Kees Cook
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 29+ messages in thread
From: Kees Cook @ 2017-06-23 20:59 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Kees Cook, stable, Ard Biesheuvel, Catalin Marinas, Mark Rutland,
	Rik van Riel, Daniel Micay, Qualys Security Advisory,
	Russell King, Will Deacon, Benjamin Herrenschmidt,
	Paul Mackerras, Michael Ellerman, Martin Schwidefsky,
	Heiko Carstens, Thomas Gleixner, Ingo Molnar, H. Peter Anvin,
	x86, Alexander Viro, Pratyush Anand, James Hogan, Dmitry Safonov,
	Grzegorz Andrejczuk, Masahiro Yamada, linux-kernel,
	linux-arm-kernel, linuxppc-dev, linux-s390, linux-fsdevel,
	kernel-hardening

Now that explicitly executed loaders are loaded in the mmap region, we
have more freedom to decide where we position PIE binaries in the address
space to avoid possible collisions with mmap or stack regions.

For 64-bit, align to 4GB to allow runtimes to use the entire 32-bit
address space for 32-bit pointers. On 32-bit use 4MB, to match ARM. This
could be 0x8000, the standard ET_EXEC load address, but that is needlessly
close to the NULL address, and anyone running arm compat PIE will have an
MMU, so the tight mapping is not needed.

Cc: stable@vger.kernel.org
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 arch/arm64/include/asm/elf.h | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
index 5d1700425efe..8790fb09f689 100644
--- a/arch/arm64/include/asm/elf.h
+++ b/arch/arm64/include/asm/elf.h
@@ -113,12 +113,11 @@
 #define ELF_EXEC_PAGESIZE	PAGE_SIZE
 
 /*
- * 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.
+ * 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	(2 * TASK_SIZE_64 / 3)
+#define ELF_ET_DYN_BASE		0x100000000UL
 
 #ifndef __ASSEMBLY__
 
@@ -173,7 +172,8 @@ extern int arch_setup_additional_pages(struct linux_binprm *bprm,
 
 #ifdef CONFIG_COMPAT
 
-#define COMPAT_ELF_ET_DYN_BASE		(2 * TASK_SIZE_32 / 3)
+/* PIE load location for compat arm. Must match ARM ELF_ET_DYN_BASE. */
+#define COMPAT_ELF_ET_DYN_BASE		0x000400000UL
 
 /* AArch32 registers. */
 #define COMPAT_ELF_NGREG		18
-- 
2.7.4

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [kernel-hardening] [PATCH v2 3/5] arm64: Move ELF_ET_DYN_BASE to 4GB / 4MB
@ 2017-06-23 20:59 ` Kees Cook
  0 siblings, 0 replies; 29+ messages in thread
From: Kees Cook @ 2017-06-23 20:59 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Kees Cook, stable, Ard Biesheuvel, Catalin Marinas, Mark Rutland,
	Rik van Riel, Daniel Micay, Qualys Security Advisory,
	Russell King, Will Deacon, Benjamin Herrenschmidt,
	Paul Mackerras, Michael Ellerman, Martin Schwidefsky,
	Heiko Carstens, Thomas Gleixner, Ingo Molnar, H. Peter Anvin,
	x86, Alexander Viro, Pratyush Anand, James Hogan, Dmitry Safonov,
	Grzegorz Andrejczuk, Masahiro Yamada, linux-kernel,
	linux-arm-kernel, linuxppc-dev, linux-s390, linux-fsdevel,
	kernel-hardening

Now that explicitly executed loaders are loaded in the mmap region, we
have more freedom to decide where we position PIE binaries in the address
space to avoid possible collisions with mmap or stack regions.

For 64-bit, align to 4GB to allow runtimes to use the entire 32-bit
address space for 32-bit pointers. On 32-bit use 4MB, to match ARM. This
could be 0x8000, the standard ET_EXEC load address, but that is needlessly
close to the NULL address, and anyone running arm compat PIE will have an
MMU, so the tight mapping is not needed.

Cc: stable@vger.kernel.org
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 arch/arm64/include/asm/elf.h | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
index 5d1700425efe..8790fb09f689 100644
--- a/arch/arm64/include/asm/elf.h
+++ b/arch/arm64/include/asm/elf.h
@@ -113,12 +113,11 @@
 #define ELF_EXEC_PAGESIZE	PAGE_SIZE
 
 /*
- * 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.
+ * 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	(2 * TASK_SIZE_64 / 3)
+#define ELF_ET_DYN_BASE		0x100000000UL
 
 #ifndef __ASSEMBLY__
 
@@ -173,7 +172,8 @@ extern int arch_setup_additional_pages(struct linux_binprm *bprm,
 
 #ifdef CONFIG_COMPAT
 
-#define COMPAT_ELF_ET_DYN_BASE		(2 * TASK_SIZE_32 / 3)
+/* PIE load location for compat arm. Must match ARM ELF_ET_DYN_BASE. */
+#define COMPAT_ELF_ET_DYN_BASE		0x000400000UL
 
 /* AArch32 registers. */
 #define COMPAT_ELF_NGREG		18
-- 
2.7.4

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH v2 3/5] arm64: Move ELF_ET_DYN_BASE to 4GB / 4MB
@ 2017-06-23 20:59 ` Kees Cook
  0 siblings, 0 replies; 29+ messages in thread
From: Kees Cook @ 2017-06-23 20:59 UTC (permalink / raw)
  To: linux-arm-kernel

Now that explicitly executed loaders are loaded in the mmap region, we
have more freedom to decide where we position PIE binaries in the address
space to avoid possible collisions with mmap or stack regions.

For 64-bit, align to 4GB to allow runtimes to use the entire 32-bit
address space for 32-bit pointers. On 32-bit use 4MB, to match ARM. This
could be 0x8000, the standard ET_EXEC load address, but that is needlessly
close to the NULL address, and anyone running arm compat PIE will have an
MMU, so the tight mapping is not needed.

Cc: stable at vger.kernel.org
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 arch/arm64/include/asm/elf.h | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
index 5d1700425efe..8790fb09f689 100644
--- a/arch/arm64/include/asm/elf.h
+++ b/arch/arm64/include/asm/elf.h
@@ -113,12 +113,11 @@
 #define ELF_EXEC_PAGESIZE	PAGE_SIZE
 
 /*
- * 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.
+ * 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	(2 * TASK_SIZE_64 / 3)
+#define ELF_ET_DYN_BASE		0x100000000UL
 
 #ifndef __ASSEMBLY__
 
@@ -173,7 +172,8 @@ extern int arch_setup_additional_pages(struct linux_binprm *bprm,
 
 #ifdef CONFIG_COMPAT
 
-#define COMPAT_ELF_ET_DYN_BASE		(2 * TASK_SIZE_32 / 3)
+/* PIE load location for compat arm. Must match ARM ELF_ET_DYN_BASE. */
+#define COMPAT_ELF_ET_DYN_BASE		0x000400000UL
 
 /* AArch32 registers. */
 #define COMPAT_ELF_NGREG		18
-- 
2.7.4

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH v2 4/5] powerpc: Move ELF_ET_DYN_BASE to 4GB / 4MB
  2017-06-23 20:59 [PATCH v2 0/5] Use ELF_ET_DYN_BASE only for PIE Kees Cook
                   ` (2 preceding siblings ...)
  2017-06-23 20:59 ` [PATCH v2 3/5] arm64: Move ELF_ET_DYN_BASE to 4GB / 4MB Kees Cook
@ 2017-06-23 20:59 ` Kees Cook
  2017-06-23 21:00 ` [PATCH v2 5/5] s390: " Kees Cook
  2017-06-24  9:11 ` [PATCH v2 0/5] Use ELF_ET_DYN_BASE only for PIE Russell King - ARM Linux
  5 siblings, 0 replies; 29+ messages in thread
From: Kees Cook @ 2017-06-23 20:59 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Kees Cook, stable, Rik van Riel, Ard Biesheuvel, Daniel Micay,
	Qualys Security Advisory, Russell King, Catalin Marinas,
	Will Deacon, Benjamin Herrenschmidt, Paul Mackerras,
	Michael Ellerman, Martin Schwidefsky, Heiko Carstens,
	Thomas Gleixner, Ingo Molnar, H. Peter Anvin, x86,
	Alexander Viro, Pratyush Anand, James Hogan, Dmitry Safonov,
	Grzegorz Andrejczuk, Masahiro Yamada, linux-kernel,
	linux-arm-kernel, linuxppc-dev, linux-s390, linux-fsdevel,
	kernel-hardening

Now that explicitly executed loaders are loaded in the mmap region, we
have more freedom to decide where we position PIE binaries in the address
space to avoid possible collisions with mmap or stack regions.

For 64-bit, align to 4GB to allow runtimes to use the entire 32-bit
address space for 32-bit pointers. On 32-bit use 4MB, which is the
traditional x86 minimum load location, likely to avoid historically
requiring a 4MB page table entry when only a portion of the first 4MB
would be used (since the NULL address is avoided).

Cc: stable@vger.kernel.org
Signed-off-by: Kees Cook <keescook@chromium.org>
Acked-by: Michael Ellerman <mpe@ellerman.id.au>
---
 arch/powerpc/include/asm/elf.h | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/arch/powerpc/include/asm/elf.h b/arch/powerpc/include/asm/elf.h
index 09bde6e34f5d..548d9a411a0d 100644
--- a/arch/powerpc/include/asm/elf.h
+++ b/arch/powerpc/include/asm/elf.h
@@ -23,12 +23,13 @@
 #define CORE_DUMP_USE_REGSET
 #define ELF_EXEC_PAGESIZE	PAGE_SIZE
 
-/* 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	0x20000000
+/*
+ * 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		(is_32bit_task() ? 0x000400000UL : \
+						   0x100000000UL)
 
 #define ELF_CORE_EFLAGS (is_elf2_task() ? 2 : 0)
 
-- 
2.7.4

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [kernel-hardening] [PATCH v2 4/5] powerpc: Move ELF_ET_DYN_BASE to 4GB / 4MB
@ 2017-06-23 20:59 ` Kees Cook
  0 siblings, 0 replies; 29+ messages in thread
From: Kees Cook @ 2017-06-23 20:59 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Kees Cook, stable, Rik van Riel, Ard Biesheuvel, Daniel Micay,
	Qualys Security Advisory, Russell King, Catalin Marinas,
	Will Deacon, Benjamin Herrenschmidt, Paul Mackerras,
	Michael Ellerman, Martin Schwidefsky, Heiko Carstens,
	Thomas Gleixner, Ingo Molnar, H. Peter Anvin, x86,
	Alexander Viro, Pratyush Anand, James Hogan, Dmitry Safonov,
	Grzegorz Andrejczuk, Masahiro Yamada, linux-kernel,
	linux-arm-kernel, linuxppc-dev, linux-s390, linux-fsdevel,
	kernel-hardening

Now that explicitly executed loaders are loaded in the mmap region, we
have more freedom to decide where we position PIE binaries in the address
space to avoid possible collisions with mmap or stack regions.

For 64-bit, align to 4GB to allow runtimes to use the entire 32-bit
address space for 32-bit pointers. On 32-bit use 4MB, which is the
traditional x86 minimum load location, likely to avoid historically
requiring a 4MB page table entry when only a portion of the first 4MB
would be used (since the NULL address is avoided).

Cc: stable@vger.kernel.org
Signed-off-by: Kees Cook <keescook@chromium.org>
Acked-by: Michael Ellerman <mpe@ellerman.id.au>
---
 arch/powerpc/include/asm/elf.h | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/arch/powerpc/include/asm/elf.h b/arch/powerpc/include/asm/elf.h
index 09bde6e34f5d..548d9a411a0d 100644
--- a/arch/powerpc/include/asm/elf.h
+++ b/arch/powerpc/include/asm/elf.h
@@ -23,12 +23,13 @@
 #define CORE_DUMP_USE_REGSET
 #define ELF_EXEC_PAGESIZE	PAGE_SIZE
 
-/* 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	0x20000000
+/*
+ * 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		(is_32bit_task() ? 0x000400000UL : \
+						   0x100000000UL)
 
 #define ELF_CORE_EFLAGS (is_elf2_task() ? 2 : 0)
 
-- 
2.7.4

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH v2 4/5] powerpc: Move ELF_ET_DYN_BASE to 4GB / 4MB
@ 2017-06-23 20:59 ` Kees Cook
  0 siblings, 0 replies; 29+ messages in thread
From: Kees Cook @ 2017-06-23 20:59 UTC (permalink / raw)
  To: linux-arm-kernel

Now that explicitly executed loaders are loaded in the mmap region, we
have more freedom to decide where we position PIE binaries in the address
space to avoid possible collisions with mmap or stack regions.

For 64-bit, align to 4GB to allow runtimes to use the entire 32-bit
address space for 32-bit pointers. On 32-bit use 4MB, which is the
traditional x86 minimum load location, likely to avoid historically
requiring a 4MB page table entry when only a portion of the first 4MB
would be used (since the NULL address is avoided).

Cc: stable at vger.kernel.org
Signed-off-by: Kees Cook <keescook@chromium.org>
Acked-by: Michael Ellerman <mpe@ellerman.id.au>
---
 arch/powerpc/include/asm/elf.h | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/arch/powerpc/include/asm/elf.h b/arch/powerpc/include/asm/elf.h
index 09bde6e34f5d..548d9a411a0d 100644
--- a/arch/powerpc/include/asm/elf.h
+++ b/arch/powerpc/include/asm/elf.h
@@ -23,12 +23,13 @@
 #define CORE_DUMP_USE_REGSET
 #define ELF_EXEC_PAGESIZE	PAGE_SIZE
 
-/* 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	0x20000000
+/*
+ * 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		(is_32bit_task() ? 0x000400000UL : \
+						   0x100000000UL)
 
 #define ELF_CORE_EFLAGS (is_elf2_task() ? 2 : 0)
 
-- 
2.7.4

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH v2 5/5] s390: Move ELF_ET_DYN_BASE to 4GB / 4MB
  2017-06-23 20:59 [PATCH v2 0/5] Use ELF_ET_DYN_BASE only for PIE Kees Cook
                   ` (3 preceding siblings ...)
  2017-06-23 20:59 ` [PATCH v2 4/5] powerpc: " Kees Cook
@ 2017-06-23 21:00 ` Kees Cook
  2017-06-24  9:11 ` [PATCH v2 0/5] Use ELF_ET_DYN_BASE only for PIE Russell King - ARM Linux
  5 siblings, 0 replies; 29+ messages in thread
From: Kees Cook @ 2017-06-23 21:00 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Kees Cook, stable, Heiko Carstens, Martin Schwidefsky,
	Rik van Riel, Ard Biesheuvel, Daniel Micay,
	Qualys Security Advisory, Russell King, Catalin Marinas,
	Will Deacon, Benjamin Herrenschmidt, Paul Mackerras,
	Michael Ellerman, Thomas Gleixner, Ingo Molnar, H. Peter Anvin,
	x86, Alexander Viro, Pratyush Anand, James Hogan, Dmitry Safonov,
	Grzegorz Andrejczuk, Masahiro Yamada, linux-kernel,
	linux-arm-kernel, linuxppc-dev, linux-s390, linux-fsdevel,
	kernel-hardening

Now that explicitly executed loaders are loaded in the mmap region, we
have more freedom to decide where we position PIE binaries in the address
space to avoid possible collisions with mmap or stack regions.

For 64-bit, align to 4GB to allow runtimes to use the entire 32-bit
address space for 32-bit pointers. On 32-bit use 4MB, which is the
traditional x86 minimum load location, likely to avoid historically
requiring a 4MB page table entry when only a portion of the first 4MB
would be used (since the NULL address is avoided). For s390 the position
could be 0x10000, but that is needlessly close to the NULL address.

Cc: stable@vger.kernel.org
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 arch/s390/include/asm/elf.h | 15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/arch/s390/include/asm/elf.h b/arch/s390/include/asm/elf.h
index e8f623041769..7c58d599f91b 100644
--- a/arch/s390/include/asm/elf.h
+++ b/arch/s390/include/asm/elf.h
@@ -161,14 +161,13 @@ extern unsigned int vdso_enabled;
 #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. 64-bit
-   tasks are aligned to 4GB. */
-#define ELF_ET_DYN_BASE (is_compat_task() ? \
-				(STACK_TOP / 3 * 2) : \
-				(STACK_TOP / 3 * 2) & ~((1UL << 32) - 1))
+/*
+ * 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		(is_compat_task() ? 0x000400000UL : \
+						    0x100000000UL)
 
 /* This yields a mask that user programs can use to figure out what
    instruction set this CPU supports. */
-- 
2.7.4

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [kernel-hardening] [PATCH v2 5/5] s390: Move ELF_ET_DYN_BASE to 4GB / 4MB
@ 2017-06-23 21:00 ` Kees Cook
  0 siblings, 0 replies; 29+ messages in thread
From: Kees Cook @ 2017-06-23 21:00 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Kees Cook, stable, Heiko Carstens, Martin Schwidefsky,
	Rik van Riel, Ard Biesheuvel, Daniel Micay,
	Qualys Security Advisory, Russell King, Catalin Marinas,
	Will Deacon, Benjamin Herrenschmidt, Paul Mackerras,
	Michael Ellerman, Thomas Gleixner, Ingo Molnar, H. Peter Anvin,
	x86, Alexander Viro, Pratyush Anand, James Hogan, Dmitry Safonov,
	Grzegorz Andrejczuk, Masahiro Yamada, linux-kernel,
	linux-arm-kernel, linuxppc-dev, linux-s390, linux-fsdevel,
	kernel-hardening

Now that explicitly executed loaders are loaded in the mmap region, we
have more freedom to decide where we position PIE binaries in the address
space to avoid possible collisions with mmap or stack regions.

For 64-bit, align to 4GB to allow runtimes to use the entire 32-bit
address space for 32-bit pointers. On 32-bit use 4MB, which is the
traditional x86 minimum load location, likely to avoid historically
requiring a 4MB page table entry when only a portion of the first 4MB
would be used (since the NULL address is avoided). For s390 the position
could be 0x10000, but that is needlessly close to the NULL address.

Cc: stable@vger.kernel.org
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 arch/s390/include/asm/elf.h | 15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/arch/s390/include/asm/elf.h b/arch/s390/include/asm/elf.h
index e8f623041769..7c58d599f91b 100644
--- a/arch/s390/include/asm/elf.h
+++ b/arch/s390/include/asm/elf.h
@@ -161,14 +161,13 @@ extern unsigned int vdso_enabled;
 #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. 64-bit
-   tasks are aligned to 4GB. */
-#define ELF_ET_DYN_BASE (is_compat_task() ? \
-				(STACK_TOP / 3 * 2) : \
-				(STACK_TOP / 3 * 2) & ~((1UL << 32) - 1))
+/*
+ * 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		(is_compat_task() ? 0x000400000UL : \
+						    0x100000000UL)
 
 /* This yields a mask that user programs can use to figure out what
    instruction set this CPU supports. */
-- 
2.7.4

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH v2 5/5] s390: Move ELF_ET_DYN_BASE to 4GB / 4MB
@ 2017-06-23 21:00 ` Kees Cook
  0 siblings, 0 replies; 29+ messages in thread
From: Kees Cook @ 2017-06-23 21:00 UTC (permalink / raw)
  To: linux-arm-kernel

Now that explicitly executed loaders are loaded in the mmap region, we
have more freedom to decide where we position PIE binaries in the address
space to avoid possible collisions with mmap or stack regions.

For 64-bit, align to 4GB to allow runtimes to use the entire 32-bit
address space for 32-bit pointers. On 32-bit use 4MB, which is the
traditional x86 minimum load location, likely to avoid historically
requiring a 4MB page table entry when only a portion of the first 4MB
would be used (since the NULL address is avoided). For s390 the position
could be 0x10000, but that is needlessly close to the NULL address.

Cc: stable at vger.kernel.org
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 arch/s390/include/asm/elf.h | 15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/arch/s390/include/asm/elf.h b/arch/s390/include/asm/elf.h
index e8f623041769..7c58d599f91b 100644
--- a/arch/s390/include/asm/elf.h
+++ b/arch/s390/include/asm/elf.h
@@ -161,14 +161,13 @@ extern unsigned int vdso_enabled;
 #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. 64-bit
-   tasks are aligned to 4GB. */
-#define ELF_ET_DYN_BASE (is_compat_task() ? \
-				(STACK_TOP / 3 * 2) : \
-				(STACK_TOP / 3 * 2) & ~((1UL << 32) - 1))
+/*
+ * 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		(is_compat_task() ? 0x000400000UL : \
+						    0x100000000UL)
 
 /* This yields a mask that user programs can use to figure out what
    instruction set this CPU supports. */
-- 
2.7.4

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH v2 0/5] Use ELF_ET_DYN_BASE only for PIE
  2017-06-23 20:59 [PATCH v2 0/5] Use ELF_ET_DYN_BASE only for PIE Kees Cook
                   ` (4 preceding siblings ...)
  2017-06-23 21:00 ` [PATCH v2 5/5] s390: " Kees Cook
@ 2017-06-24  9:11 ` Russell King - ARM Linux
  2017-06-24 13:58   ` Kees Cook
  5 siblings, 1 reply; 29+ messages in thread
From: Russell King - ARM Linux @ 2017-06-24  9:11 UTC (permalink / raw)
  To: Kees Cook
  Cc: Andrew Morton, Rik van Riel, Ard Biesheuvel, Daniel Micay,
	Qualys Security Advisory, Catalin Marinas, Will Deacon,
	Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Martin Schwidefsky, Heiko Carstens, Thomas Gleixner, Ingo Molnar,
	H. Peter Anvin, x86, Alexander Viro, Pratyush Anand, James Hogan,
	Dmitry Safonov, Grzegorz Andrejczuk, Masahiro Yamada,
	linux-kernel, linux-arm-kernel, linuxppc-dev, linux-s390,
	linux-fsdevel, kernel-hardening

On Fri, Jun 23, 2017 at 01:59:55PM -0700, Kees Cook wrote:
> This is v2 (to refresh the 5 patches in -mm) for moving ELF_ET_DYN_BASE
> safely lower. Changes are clarifications in the commit logs (suggested
> by mpe), a compat think-o fix for arm64 (thanks to Ard), and to add
> Rik and mpe's Acks.
> 
> Quoting patch 1/5:
> 
> 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.

With existing kernels on ARM:

00010000-00017000 r-xp 00000000 08:01 270810     /bin/cat
00026000-00027000 r--p 00006000 08:01 270810     /bin/cat
00027000-00028000 rw-p 00007000 08:01 270810     /bin/cat
7f661000-7f679000 r-xp 00000000 08:01 281659     /lib/arm-linux-gnueabihf/ld-2.23.so
7f688000-7f689000 r--p 00017000 08:01 281659     /lib/arm-linux-gnueabihf/ld-2.23.so
7f689000-7f68a000 rw-p 00018000 08:01 281659     /lib/arm-linux-gnueabihf/ld-2.23.so

If the loader is loaded at 4MB, this means the size of an ET_EXEC
program is limited to less than 4MB - and distros aren't yet
building everything as PIE on ARM.

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [kernel-hardening] Re: [PATCH v2 0/5] Use ELF_ET_DYN_BASE only for PIE
@ 2017-06-24  9:11 ` Russell King - ARM Linux
  2017-06-24 13:58   ` Kees Cook
  0 siblings, 1 reply; 29+ messages in thread
From: Russell King - ARM Linux @ 2017-06-24  9:11 UTC (permalink / raw)
  To: Kees Cook
  Cc: Andrew Morton, Rik van Riel, Ard Biesheuvel, Daniel Micay,
	Qualys Security Advisory, Catalin Marinas, Will Deacon,
	Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Martin Schwidefsky, Heiko Carstens, Thomas Gleixner, Ingo Molnar,
	H. Peter Anvin, x86, Alexander Viro, Pratyush Anand, James Hogan,
	Dmitry Safonov, Grzegorz Andrejczuk, Masahiro Yamada,
	linux-kernel, linux-arm-kernel, linuxppc-dev, linux-s390,
	linux-fsdevel, kernel-hardening

On Fri, Jun 23, 2017 at 01:59:55PM -0700, Kees Cook wrote:
> This is v2 (to refresh the 5 patches in -mm) for moving ELF_ET_DYN_BASE
> safely lower. Changes are clarifications in the commit logs (suggested
> by mpe), a compat think-o fix for arm64 (thanks to Ard), and to add
> Rik and mpe's Acks.
> 
> Quoting patch 1/5:
> 
> 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.

With existing kernels on ARM:

00010000-00017000 r-xp 00000000 08:01 270810     /bin/cat
00026000-00027000 r--p 00006000 08:01 270810     /bin/cat
00027000-00028000 rw-p 00007000 08:01 270810     /bin/cat
7f661000-7f679000 r-xp 00000000 08:01 281659     /lib/arm-linux-gnueabihf/ld-2.23.so
7f688000-7f689000 r--p 00017000 08:01 281659     /lib/arm-linux-gnueabihf/ld-2.23.so
7f689000-7f68a000 rw-p 00018000 08:01 281659     /lib/arm-linux-gnueabihf/ld-2.23.so

If the loader is loaded at 4MB, this means the size of an ET_EXEC
program is limited to less than 4MB - and distros aren't yet
building everything as PIE on ARM.

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH v2 0/5] Use ELF_ET_DYN_BASE only for PIE
@ 2017-06-24  9:11 ` Russell King - ARM Linux
  2017-06-24 13:58   ` Kees Cook
  0 siblings, 1 reply; 29+ messages in thread
From: Russell King - ARM Linux @ 2017-06-24  9:11 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Jun 23, 2017 at 01:59:55PM -0700, Kees Cook wrote:
> This is v2 (to refresh the 5 patches in -mm) for moving ELF_ET_DYN_BASE
> safely lower. Changes are clarifications in the commit logs (suggested
> by mpe), a compat think-o fix for arm64 (thanks to Ard), and to add
> Rik and mpe's Acks.
> 
> Quoting patch 1/5:
> 
> 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.

With existing kernels on ARM:

00010000-00017000 r-xp 00000000 08:01 270810     /bin/cat
00026000-00027000 r--p 00006000 08:01 270810     /bin/cat
00027000-00028000 rw-p 00007000 08:01 270810     /bin/cat
7f661000-7f679000 r-xp 00000000 08:01 281659     /lib/arm-linux-gnueabihf/ld-2.23.so
7f688000-7f689000 r--p 00017000 08:01 281659     /lib/arm-linux-gnueabihf/ld-2.23.so
7f689000-7f68a000 rw-p 00018000 08:01 281659     /lib/arm-linux-gnueabihf/ld-2.23.so

If the loader is loaded at 4MB, this means the size of an ET_EXEC
program is limited to less than 4MB - and distros aren't yet
building everything as PIE on ARM.

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH v2 0/5] Use ELF_ET_DYN_BASE only for PIE
  2017-06-24  9:11 ` [PATCH v2 0/5] Use ELF_ET_DYN_BASE only for PIE Russell King - ARM Linux
@ 2017-06-24 13:58   ` Kees Cook
  0 siblings, 0 replies; 29+ messages in thread
From: Kees Cook @ 2017-06-24 13:58 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Andrew Morton, Rik van Riel, Ard Biesheuvel, Daniel Micay,
	Qualys Security Advisory, Catalin Marinas, Will Deacon,
	Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Martin Schwidefsky, Heiko Carstens, Thomas Gleixner, Ingo Molnar,
	H. Peter Anvin, x86, Alexander Viro, Pratyush Anand, James Hogan,
	Dmitry Safonov, Grzegorz Andrejczuk, Masahiro Yamada, LKML,
	linux-arm-kernel, linuxppc-dev, linux-s390, linux-fsdevel,
	kernel-hardening

On Sat, Jun 24, 2017 at 2:11 AM, Russell King - ARM Linux
<linux@armlinux.org.uk> wrote:
> On Fri, Jun 23, 2017 at 01:59:55PM -0700, Kees Cook wrote:
>> This is v2 (to refresh the 5 patches in -mm) for moving ELF_ET_DYN_BASE
>> safely lower. Changes are clarifications in the commit logs (suggested
>> by mpe), a compat think-o fix for arm64 (thanks to Ard), and to add
>> Rik and mpe's Acks.
>>
>> Quoting patch 1/5:
>>
>> 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.
>
> With existing kernels on ARM:
>
> 00010000-00017000 r-xp 00000000 08:01 270810     /bin/cat
> 00026000-00027000 r--p 00006000 08:01 270810     /bin/cat
> 00027000-00028000 rw-p 00007000 08:01 270810     /bin/cat
> 7f661000-7f679000 r-xp 00000000 08:01 281659     /lib/arm-linux-gnueabihf/ld-2.23.so
> 7f688000-7f689000 r--p 00017000 08:01 281659     /lib/arm-linux-gnueabihf/ld-2.23.so
> 7f689000-7f68a000 rw-p 00018000 08:01 281659     /lib/arm-linux-gnueabihf/ld-2.23.so
>
> If the loader is loaded at 4MB, this means the size of an ET_EXEC
> program is limited to less than 4MB - and distros aren't yet
> building everything as PIE on ARM.

The loader isn't loaded at 4MB; that's what patch 1 changes: loaders
are moved into the mmap region so they will not collide with either
ET_EXEC nor PIE (ET_DYN-with-INTERP).

(After this patch, the name "ELF_ET_DYN_BASE" becomes a bit misleading...)

-Kees

-- 
Kees Cook
Pixel Security

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [kernel-hardening] Re: [PATCH v2 0/5] Use ELF_ET_DYN_BASE only for PIE
@ 2017-06-24 13:58   ` Kees Cook
  0 siblings, 0 replies; 29+ messages in thread
From: Kees Cook @ 2017-06-24 13:58 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Andrew Morton, Rik van Riel, Ard Biesheuvel, Daniel Micay,
	Qualys Security Advisory, Catalin Marinas, Will Deacon,
	Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Martin Schwidefsky, Heiko Carstens, Thomas Gleixner, Ingo Molnar,
	H. Peter Anvin, x86, Alexander Viro, Pratyush Anand, James Hogan,
	Dmitry Safonov, Grzegorz Andrejczuk, Masahiro Yamada, LKML,
	linux-arm-kernel, linuxppc-dev, linux-s390, linux-fsdevel,
	kernel-hardening

On Sat, Jun 24, 2017 at 2:11 AM, Russell King - ARM Linux
<linux@armlinux.org.uk> wrote:
> On Fri, Jun 23, 2017 at 01:59:55PM -0700, Kees Cook wrote:
>> This is v2 (to refresh the 5 patches in -mm) for moving ELF_ET_DYN_BASE
>> safely lower. Changes are clarifications in the commit logs (suggested
>> by mpe), a compat think-o fix for arm64 (thanks to Ard), and to add
>> Rik and mpe's Acks.
>>
>> Quoting patch 1/5:
>>
>> 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.
>
> With existing kernels on ARM:
>
> 00010000-00017000 r-xp 00000000 08:01 270810     /bin/cat
> 00026000-00027000 r--p 00006000 08:01 270810     /bin/cat
> 00027000-00028000 rw-p 00007000 08:01 270810     /bin/cat
> 7f661000-7f679000 r-xp 00000000 08:01 281659     /lib/arm-linux-gnueabihf/ld-2.23.so
> 7f688000-7f689000 r--p 00017000 08:01 281659     /lib/arm-linux-gnueabihf/ld-2.23.so
> 7f689000-7f68a000 rw-p 00018000 08:01 281659     /lib/arm-linux-gnueabihf/ld-2.23.so
>
> If the loader is loaded at 4MB, this means the size of an ET_EXEC
> program is limited to less than 4MB - and distros aren't yet
> building everything as PIE on ARM.

The loader isn't loaded at 4MB; that's what patch 1 changes: loaders
are moved into the mmap region so they will not collide with either
ET_EXEC nor PIE (ET_DYN-with-INTERP).

(After this patch, the name "ELF_ET_DYN_BASE" becomes a bit misleading...)

-Kees

-- 
Kees Cook
Pixel Security

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH v2 0/5] Use ELF_ET_DYN_BASE only for PIE
@ 2017-06-24 13:58   ` Kees Cook
  0 siblings, 0 replies; 29+ messages in thread
From: Kees Cook @ 2017-06-24 13:58 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Andrew Morton, Rik van Riel, Ard Biesheuvel, Daniel Micay,
	Qualys Security Advisory, Catalin Marinas, Will Deacon,
	Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Martin Schwidefsky, Heiko Carstens, Thomas Gleixner, Ingo Molnar,
	H. Peter Anvin, x86, Alexander Viro, Pratyush Anand, James Hogan,
	Dmitry Safonov, Grzegorz Andrejczuk, Masahiro Yamada, LKML,
	linux-arm-kernel, linuxppc-dev, linux-s390, linux-fsdevel,
	kernel-hardening

On Sat, Jun 24, 2017 at 2:11 AM, Russell King - ARM Linux
<linux@armlinux.org.uk> wrote:
> On Fri, Jun 23, 2017 at 01:59:55PM -0700, Kees Cook wrote:
>> This is v2 (to refresh the 5 patches in -mm) for moving ELF_ET_DYN_BASE
>> safely lower. Changes are clarifications in the commit logs (suggested
>> by mpe), a compat think-o fix for arm64 (thanks to Ard), and to add
>> Rik and mpe's Acks.
>>
>> Quoting patch 1/5:
>>
>> 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.
>
> With existing kernels on ARM:
>
> 00010000-00017000 r-xp 00000000 08:01 270810     /bin/cat
> 00026000-00027000 r--p 00006000 08:01 270810     /bin/cat
> 00027000-00028000 rw-p 00007000 08:01 270810     /bin/cat
> 7f661000-7f679000 r-xp 00000000 08:01 281659     /lib/arm-linux-gnueabihf/ld-2.23.so
> 7f688000-7f689000 r--p 00017000 08:01 281659     /lib/arm-linux-gnueabihf/ld-2.23.so
> 7f689000-7f68a000 rw-p 00018000 08:01 281659     /lib/arm-linux-gnueabihf/ld-2.23.so
>
> If the loader is loaded at 4MB, this means the size of an ET_EXEC
> program is limited to less than 4MB - and distros aren't yet
> building everything as PIE on ARM.

The loader isn't loaded at 4MB; that's what patch 1 changes: loaders
are moved into the mmap region so they will not collide with either
ET_EXEC nor PIE (ET_DYN-with-INTERP).

(After this patch, the name "ELF_ET_DYN_BASE" becomes a bit misleading...)

-Kees

-- 
Kees Cook
Pixel Security

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH v2 0/5] Use ELF_ET_DYN_BASE only for PIE
@ 2017-06-24 13:58   ` Kees Cook
  0 siblings, 0 replies; 29+ messages in thread
From: Kees Cook @ 2017-06-24 13:58 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Jun 24, 2017 at 2:11 AM, Russell King - ARM Linux
<linux@armlinux.org.uk> wrote:
> On Fri, Jun 23, 2017 at 01:59:55PM -0700, Kees Cook wrote:
>> This is v2 (to refresh the 5 patches in -mm) for moving ELF_ET_DYN_BASE
>> safely lower. Changes are clarifications in the commit logs (suggested
>> by mpe), a compat think-o fix for arm64 (thanks to Ard), and to add
>> Rik and mpe's Acks.
>>
>> Quoting patch 1/5:
>>
>> 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.
>
> With existing kernels on ARM:
>
> 00010000-00017000 r-xp 00000000 08:01 270810     /bin/cat
> 00026000-00027000 r--p 00006000 08:01 270810     /bin/cat
> 00027000-00028000 rw-p 00007000 08:01 270810     /bin/cat
> 7f661000-7f679000 r-xp 00000000 08:01 281659     /lib/arm-linux-gnueabihf/ld-2.23.so
> 7f688000-7f689000 r--p 00017000 08:01 281659     /lib/arm-linux-gnueabihf/ld-2.23.so
> 7f689000-7f68a000 rw-p 00018000 08:01 281659     /lib/arm-linux-gnueabihf/ld-2.23.so
>
> If the loader is loaded at 4MB, this means the size of an ET_EXEC
> program is limited to less than 4MB - and distros aren't yet
> building everything as PIE on ARM.

The loader isn't loaded at 4MB; that's what patch 1 changes: loaders
are moved into the mmap region so they will not collide with either
ET_EXEC nor PIE (ET_DYN-with-INTERP).

(After this patch, the name "ELF_ET_DYN_BASE" becomes a bit misleading...)

-Kees

-- 
Kees Cook
Pixel Security

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH v2 1/5] binfmt_elf: Use ELF_ET_DYN_BASE only for PIE
  2017-06-23 20:59 ` [PATCH v2 1/5] binfmt_elf: " Kees Cook
@ 2017-06-24 19:16   ` Kees Cook
  0 siblings, 0 replies; 29+ messages in thread
From: Kees Cook @ 2017-06-24 19:16 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Kees Cook, # 3.4.x, x86, Rik van Riel, Ard Biesheuvel,
	Daniel Micay, Qualys Security Advisory, Russell King,
	Catalin Marinas, Will Deacon, Benjamin Herrenschmidt,
	Paul Mackerras, Michael Ellerman, Martin Schwidefsky,
	Heiko Carstens, Thomas Gleixner, Ingo Molnar, H. Peter Anvin,
	Alexander Viro, Pratyush Anand, James Hogan, Dmitry Safonov,
	Grzegorz Andrejczuk, Masahiro Yamada, LKML, linux-arm-kernel,
	linuxppc-dev, linux-s390, linux-fsdevel, kernel-hardening

On Fri, Jun 23, 2017 at 1:59 PM, Kees Cook <keescook@chromium.org> wrote:
> For 32-bit tasks when RLIMIT_STACK is set to RLIM_INFINITY, programs
> are loaded below 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
> above 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).

It was pointed out by rmk that I described this inaccurately. I mix up
my own visualization of the address space (above/below in
/proc/$pid/maps) with actual value comparisons (above/below
numerically). This paragraph should read:


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).


Andrew, are you able to manually adjust this commit log in -mm, or
should I resend the patch with this paragraph corrected?

Thanks!

-Kees

-- 
Kees Cook
Pixel Security

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [kernel-hardening] Re: [PATCH v2 1/5] binfmt_elf: Use ELF_ET_DYN_BASE only for PIE
@ 2017-06-24 19:16   ` Kees Cook
  0 siblings, 0 replies; 29+ messages in thread
From: Kees Cook @ 2017-06-24 19:16 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Kees Cook, # 3.4.x, x86, Rik van Riel, Ard Biesheuvel,
	Daniel Micay, Qualys Security Advisory, Russell King,
	Catalin Marinas, Will Deacon, Benjamin Herrenschmidt,
	Paul Mackerras, Michael Ellerman, Martin Schwidefsky,
	Heiko Carstens, Thomas Gleixner, Ingo Molnar, H. Peter Anvin,
	Alexander Viro, Pratyush Anand, James Hogan, Dmitry Safonov,
	Grzegorz Andrejczuk, Masahiro Yamada, LKML, linux-arm-kernel,
	linuxppc-dev, linux-s390, linux-fsdevel, kernel-hardening

On Fri, Jun 23, 2017 at 1:59 PM, Kees Cook <keescook@chromium.org> wrote:
> For 32-bit tasks when RLIMIT_STACK is set to RLIM_INFINITY, programs
> are loaded below 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
> above 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).

It was pointed out by rmk that I described this inaccurately. I mix up
my own visualization of the address space (above/below in
/proc/$pid/maps) with actual value comparisons (above/below
numerically). This paragraph should read:


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).


Andrew, are you able to manually adjust this commit log in -mm, or
should I resend the patch with this paragraph corrected?

Thanks!

-Kees

-- 
Kees Cook
Pixel Security

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH v2 1/5] binfmt_elf: Use ELF_ET_DYN_BASE only for PIE
@ 2017-06-24 19:16   ` Kees Cook
  0 siblings, 0 replies; 29+ messages in thread
From: Kees Cook @ 2017-06-24 19:16 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Kees Cook, # 3.4.x, x86, Rik van Riel, Ard Biesheuvel,
	Daniel Micay, Qualys Security Advisory, Russell King,
	Catalin Marinas, Will Deacon, Benjamin Herrenschmidt,
	Paul Mackerras, Michael Ellerman, Martin Schwidefsky,
	Heiko Carstens, Thomas Gleixner, Ingo Molnar, H. Peter Anvin,
	Alexander Viro, Pratyush Anand, James Hogan, Dmitry Safonov,
	Grzegorz Andrejczuk, Masahiro Yamada, LKML, linux-arm-kernel,
	linuxppc-dev, linux-s390, linux-fsdevel, kernel-hardening

On Fri, Jun 23, 2017 at 1:59 PM, Kees Cook <keescook@chromium.org> wrote:
> For 32-bit tasks when RLIMIT_STACK is set to RLIM_INFINITY, programs
> are loaded below 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
> above 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).

It was pointed out by rmk that I described this inaccurately. I mix up
my own visualization of the address space (above/below in
/proc/$pid/maps) with actual value comparisons (above/below
numerically). This paragraph should read:


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).


Andrew, are you able to manually adjust this commit log in -mm, or
should I resend the patch with this paragraph corrected?

Thanks!

-Kees

-- 
Kees Cook
Pixel Security

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH v2 1/5] binfmt_elf: Use ELF_ET_DYN_BASE only for PIE
@ 2017-06-24 19:16   ` Kees Cook
  0 siblings, 0 replies; 29+ messages in thread
From: Kees Cook @ 2017-06-24 19:16 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Jun 23, 2017 at 1:59 PM, Kees Cook <keescook@chromium.org> wrote:
> For 32-bit tasks when RLIMIT_STACK is set to RLIM_INFINITY, programs
> are loaded below 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
> above 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).

It was pointed out by rmk that I described this inaccurately. I mix up
my own visualization of the address space (above/below in
/proc/$pid/maps) with actual value comparisons (above/below
numerically). This paragraph should read:


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).


Andrew, are you able to manually adjust this commit log in -mm, or
should I resend the patch with this paragraph corrected?

Thanks!

-Kees

-- 
Kees Cook
Pixel Security

^ permalink raw reply	[flat|nested] 29+ messages in thread

end of thread, other threads:[~2017-06-24 19:16 UTC | newest]

Thread overview: 29+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-06-23 20:59 [PATCH v2 0/5] Use ELF_ET_DYN_BASE only for PIE Kees Cook
2017-06-23 20:59 ` [PATCH v2 1/5] binfmt_elf: " Kees Cook
2017-06-24 19:16   ` Kees Cook
2017-06-23 20:59 ` [PATCH v2 2/5] arm: Move ELF_ET_DYN_BASE to 4MB Kees Cook
2017-06-23 20:59 ` [PATCH v2 3/5] arm64: Move ELF_ET_DYN_BASE to 4GB / 4MB Kees Cook
2017-06-23 20:59 ` [PATCH v2 4/5] powerpc: " Kees Cook
2017-06-23 21:00 ` [PATCH v2 5/5] s390: " Kees Cook
2017-06-24  9:11 ` [PATCH v2 0/5] Use ELF_ET_DYN_BASE only for PIE Russell King - ARM Linux
2017-06-24 13:58   ` Kees Cook

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.