All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS
@ 2015-02-23 18:37 Hector Marco
  2015-02-23 19:34   ` Kees Cook
  0 siblings, 1 reply; 56+ messages in thread
From: Hector Marco @ 2015-02-23 18:37 UTC (permalink / raw)
  To: LKML; +Cc: ismael Ripoll, Kees Cook - ASLRv3

[PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS

The issue appears on PIE linked executables when all memory areas of a process are randomized. In 
this case, the attack "offset2lib" de-randomizes all library areas on 64 bit Linux systems in less 
than one second.


Further details of the PoC attack at:
http://cybersecurity.upv.es/attacks/offset2lib/offset2lib.html


This patch loads the PIE linked executable in a different area than the libraries. The successful 
fix can be tested with a simple pie compiled application:


$ ./show_mmaps_pie
54859ccd6000-54859ccd7000 r-xp  ...  /tmp/show_mmaps_pie
54859ced6000-54859ced7000 r--p  ...  /tmp/show_mmaps_pie
54859ced7000-54859ced8000 rw-p  ...  /tmp/show_mmaps_pie
7f75be764000-7f75be91f000 r-xp  ...  /lib/x86_64-linux-gnu/libc.so.6
7f75be91f000-7f75beb1f000 ---p  ...  /lib/x86_64-linux-gnu/libc.so.6
7f75beb1f000-7f75beb23000 r--p  ...  /lib/x86_64-linux-gnu/libc.so.6
7f75beb23000-7f75beb25000 rw-p  ...  /lib/x86_64-linux-gnu/libc.so.6
7f75beb25000-7f75beb2a000 rw-p  ...
7f75beb2a000-7f75beb4d000 r-xp  ...  /lib64/ld-linux-x86-64.so.2
7f75bed45000-7f75bed46000 rw-p  ...
7f75bed46000-7f75bed47000 r-xp  ...
7f75bed47000-7f75bed4c000 rw-p  ...
7f75bed4c000-7f75bed4d000 r--p  ...  /lib64/ld-linux-x86-64.so.2
7f75bed4d000-7f75bed4e000 rw-p  ...  /lib64/ld-linux-x86-64.so.2
7f75bed4e000-7f75bed4f000 rw-p  ...
7fffb3741000-7fffb3762000 rw-p  ...  [stack]
7fffb377b000-7fffb377d000 r--p  ...  [vvar]
7fffb377d000-7fffb377f000 r-xp  ...  [vdso]


Once corrected, the PIE linked application is loaded in a different area.

We updated the "Fixing Offset2lib weakness" page:
http://cybersecurity.upv.es/solutions/aslrv2/aslrv2.html


Signed-off-by: Hector Marco-Gisbert <hecmargi@upv.es>
Signed-off-by: Ismael Ripoll <iripoll@upv.es>


diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 97d07ed..ee7ea7e 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1,7 +1,6 @@
  config ARM
  	bool
  	default y
-	select ARCH_BINFMT_ELF_RANDOMIZE_PIE
  	select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
  	select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
  	select ARCH_HAVE_CUSTOM_GPIO_H
diff --git a/arch/arm/include/asm/elf.h b/arch/arm/include/asm/elf.h
index afb9caf..6755cd8 100644
--- a/arch/arm/include/asm/elf.h
+++ b/arch/arm/include/asm/elf.h
@@ -115,7 +115,8 @@ int dump_task_regs(struct task_struct *t, elf_gregset_t *elfregs);
     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	(2 * TASK_SIZE / 3)
+extern unsigned long randomize_et_dyn(unsigned long base);
+#define ELF_ET_DYN_BASE	(randomize_et_dyn(2 * TASK_SIZE / 3))

  /* 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
diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c
index 5e85ed3..9177100 100644
--- a/arch/arm/mm/mmap.c
+++ b/arch/arm/mm/mmap.c
@@ -30,6 +30,17 @@ static int mmap_is_legacy(void)
  	return sysctl_legacy_va_layout;
  }

+static unsigned long mmap_rnd(void)
+{
+	unsigned long rnd = 0;
+
+	/* 8 bits of randomness in 20 address space bits */
+	if (current->flags & PF_RANDOMIZE)
+		rnd = (long)get_random_int() % (1 << 8);
+
+	return rnd << PAGE_SHIFT;
+}
+
  static unsigned long mmap_base(unsigned long rnd)
  {
  	unsigned long gap = rlimit(RLIMIT_STACK);
@@ -230,3 +241,13 @@ int devmem_is_allowed(unsigned long pfn)
  }

  #endif
+
+unsigned long randomize_et_dyn(unsigned long base)
+{
+	unsigned long ret;
+	if ((current->personality & ADDR_NO_RANDOMIZE) ||
+		!(current->flags & PF_RANDOMIZE))
+		return base;
+	ret = base + mmap_rnd();
+	return (ret > base) ? ret : base;
+}
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index b1f9a20..5580d90 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -1,6 +1,5 @@
  config ARM64
  	def_bool y
-	select ARCH_BINFMT_ELF_RANDOMIZE_PIE
  	select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
  	select ARCH_HAS_GCOV_PROFILE_ALL
  	select ARCH_HAS_SG_CHAIN
diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
index 1f65be3..01d3aab 100644
--- a/arch/arm64/include/asm/elf.h
+++ b/arch/arm64/include/asm/elf.h
@@ -126,7 +126,7 @@ typedef struct user_fpsimd_state elf_fpregset_t;
   * that it will "exec", and that there is sufficient room for the brk.
   */
  extern unsigned long randomize_et_dyn(unsigned long base);
-#define ELF_ET_DYN_BASE	(2 * TASK_SIZE_64 / 3)
+#define ELF_ET_DYN_BASE	(randomize_et_dyn(2 * TASK_SIZE_64 / 3))

  /*
   * When the program starts, a1 contains a pointer to a function to be
@@ -169,7 +169,7 @@ extern unsigned long arch_randomize_brk(struct mm_struct *mm);
  #define COMPAT_ELF_PLATFORM		("v8l")
  #endif

-#define COMPAT_ELF_ET_DYN_BASE		(2 * TASK_SIZE_32 / 3)
+#define COMPAT_ELF_ET_DYN_BASE		(randomize_et_dyn(2 * TASK_SIZE_32 / 3))

  /* AArch32 registers. */
  #define COMPAT_ELF_NGREG		18
diff --git a/arch/arm64/mm/mmap.c b/arch/arm64/mm/mmap.c
index 54922d1..980110c50 100644
--- a/arch/arm64/mm/mmap.c
+++ b/arch/arm64/mm/mmap.c
@@ -89,6 +89,16 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
  }
  EXPORT_SYMBOL_GPL(arch_pick_mmap_layout);

+unsigned long randomize_et_dyn(unsigned long base)
+{
+	unsigned long ret;
+	if ((current->personality & ADDR_NO_RANDOMIZE) ||
+		!(current->flags & PF_RANDOMIZE))
+		return base;
+	ret = base + mmap_rnd();
+	return (ret > base) ? ret : base;
+}
+

  /*
   * You really shouldn't be using read() or write() on /dev/mem.  This might go
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 3289969..31cc248 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -23,7 +23,6 @@ config MIPS
  	select HAVE_KRETPROBES
  	select HAVE_DEBUG_KMEMLEAK
  	select HAVE_SYSCALL_TRACEPOINTS
-	select ARCH_BINFMT_ELF_RANDOMIZE_PIE
  	select HAVE_ARCH_TRANSPARENT_HUGEPAGE if CPU_SUPPORTS_HUGEPAGES && 64BIT
  	select RTC_LIB if !MACH_LOONGSON
  	select GENERIC_ATOMIC64 if !64BIT
diff --git a/arch/mips/include/asm/elf.h b/arch/mips/include/asm/elf.h
index eb4d95d..fcac4c99 100644
--- a/arch/mips/include/asm/elf.h
+++ b/arch/mips/include/asm/elf.h
@@ -402,7 +402,8 @@ extern const char *__elf_platform;
     that it will "exec", and that there is sufficient room for the brk.	*/

  #ifndef ELF_ET_DYN_BASE
-#define ELF_ET_DYN_BASE		(TASK_SIZE / 3 * 2)
+extern unsigned long randomize_et_dyn(unsigned long base);
+#define ELF_ET_DYN_BASE		(randomize_et_dyn(TASK_SIZE / 3 * 2))
  #endif

  #define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
diff --git a/arch/mips/mm/mmap.c b/arch/mips/mm/mmap.c
index f1baadd..20ad644 100644
--- a/arch/mips/mm/mmap.c
+++ b/arch/mips/mm/mmap.c
@@ -196,3 +196,13 @@ int __virt_addr_valid(const volatile void *kaddr)
  	return pfn_valid(PFN_DOWN(virt_to_phys(kaddr)));
  }
  EXPORT_SYMBOL_GPL(__virt_addr_valid);
+
+unsigned long randomize_et_dyn(unsigned long base)
+{
+	unsigned long ret;
+	if ((current->personality & ADDR_NO_RANDOMIZE) ||
+		!(current->flags & PF_RANDOMIZE))
+		return base;
+	ret = base + brk_rnd();
+	return (ret > base) ? ret : base;
+}
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index a2a168e..fa4c877 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -88,7 +88,6 @@ config PPC
  	select ARCH_MIGHT_HAVE_PC_PARPORT
  	select ARCH_MIGHT_HAVE_PC_SERIO
  	select BINFMT_ELF
-	select ARCH_BINFMT_ELF_RANDOMIZE_PIE
  	select OF
  	select OF_EARLY_FLATTREE
  	select OF_RESERVED_MEM
diff --git a/arch/powerpc/include/asm/elf.h b/arch/powerpc/include/asm/elf.h
index 57d289a..4080425 100644
--- a/arch/powerpc/include/asm/elf.h
+++ b/arch/powerpc/include/asm/elf.h
@@ -28,7 +28,8 @@
     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
+extern unsigned long randomize_et_dyn(unsigned long base);
+#define ELF_ET_DYN_BASE	(randomize_et_dyn(0x20000000))

  #define ELF_CORE_EFLAGS (is_elf2_task() ? 2 : 0)

diff --git a/arch/powerpc/mm/mmap.c b/arch/powerpc/mm/mmap.c
index cb8bdbe..3e642e7 100644
--- a/arch/powerpc/mm/mmap.c
+++ b/arch/powerpc/mm/mmap.c
@@ -97,3 +97,13 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
  		mm->get_unmapped_area = arch_get_unmapped_area_topdown;
  	}
  }
+
+unsigned long randomize_et_dyn(unsigned long base)
+{
+	unsigned long ret;
+	if ((current->personality & ADDR_NO_RANDOMIZE) ||
+		!(current->flags & PF_RANDOMIZE))
+		return base;
+	ret = base + mmap_rnd();
+	return (ret > base) ? ret : base;
+}
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index ba397bd..dcfe16c 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -85,7 +85,6 @@ config X86
  	select HAVE_CMPXCHG_DOUBLE
  	select HAVE_ARCH_KMEMCHECK
  	select HAVE_USER_RETURN_NOTIFIER
-	select ARCH_BINFMT_ELF_RANDOMIZE_PIE
  	select HAVE_ARCH_JUMP_LABEL
  	select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
  	select SPARSE_IRQ
diff --git a/arch/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h
index ca3347a..92c6ac4 100644
--- a/arch/x86/include/asm/elf.h
+++ b/arch/x86/include/asm/elf.h
@@ -249,7 +249,8 @@ extern int force_personality32;
     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)
+extern unsigned long randomize_et_dyn(unsigned long base);
+#define ELF_ET_DYN_BASE		(randomize_et_dyn(TASK_SIZE / 3 * 2))

  /* 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/arch/x86/mm/mmap.c b/arch/x86/mm/mmap.c
index 919b912..7b86605 100644
--- a/arch/x86/mm/mmap.c
+++ b/arch/x86/mm/mmap.c
@@ -122,3 +122,12 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
  		mm->get_unmapped_area = arch_get_unmapped_area_topdown;
  	}
  }
+unsigned long randomize_et_dyn(unsigned long base)
+{
+	unsigned long ret;
+	if ((current->personality & ADDR_NO_RANDOMIZE) ||
+		!(current->flags & PF_RANDOMIZE))
+		return base;
+	ret = base + mmap_rnd();
+	return (ret > base) ? ret : base;
+}
diff --git a/fs/Kconfig.binfmt b/fs/Kconfig.binfmt
index c055d56..1186190 100644
--- a/fs/Kconfig.binfmt
+++ b/fs/Kconfig.binfmt
@@ -27,8 +27,6 @@ config COMPAT_BINFMT_ELF
  	bool
  	depends on COMPAT && BINFMT_ELF

-config ARCH_BINFMT_ELF_RANDOMIZE_PIE
-	bool

  config ARCH_BINFMT_ELF_STATE
  	bool
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 02b1691..72f7ff5 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -908,21 +908,7 @@ static int load_elf_binary(struct linux_binprm *bprm)
  			 * 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.  */
-#ifdef CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE
-			/* Memory randomization might have been switched off
-			 * in runtime via sysctl or explicit setting of
-			 * personality flags.
-			 * If that is the case, retain the original non-zero
-			 * load_bias value in order to establish proper
-			 * non-randomized mappings.
-			 */
-			if (current->flags & PF_RANDOMIZE)
-				load_bias = 0;
-			else
-				load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
-#else
  			load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
-#endif
  		}

  		error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt,

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

* Re: [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS
@ 2015-02-23 19:34   ` Kees Cook
  0 siblings, 0 replies; 56+ messages in thread
From: Kees Cook @ 2015-02-23 19:34 UTC (permalink / raw)
  To: Hector Marco, Andrew Morton
  Cc: LKML, ismael Ripoll, x86, linux-arm-kernel,
	Linux MIPS Mailing List, linuxppc-dev

(I've added some additional CCs to make sure the arch maintainers
notice this patch.)

This patch seems white-space damaged to me. I had to do a lot of
manual editing to get it to apply. Please use "git format-patch", if
you're not already. What version of the kernel was this based on?

On Mon, Feb 23, 2015 at 10:37 AM, Hector Marco <hecmargi@upv.es> wrote:
> [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS
>
> The issue appears on PIE linked executables when all memory areas of a
> process are randomized. In this case, the attack "offset2lib" de-randomizes
> all library areas on 64 bit Linux systems in less than one second.
>
>
> Further details of the PoC attack at:
> http://cybersecurity.upv.es/attacks/offset2lib/offset2lib.html
>
>
> This patch loads the PIE linked executable in a different area than the
> libraries. The successful fix can be tested with a simple pie compiled
> application:
>
>
> $ ./show_mmaps_pie
> 54859ccd6000-54859ccd7000 r-xp  ...  /tmp/show_mmaps_pie
> 54859ced6000-54859ced7000 r--p  ...  /tmp/show_mmaps_pie
> 54859ced7000-54859ced8000 rw-p  ...  /tmp/show_mmaps_pie
> 7f75be764000-7f75be91f000 r-xp  ...  /lib/x86_64-linux-gnu/libc.so.6
> 7f75be91f000-7f75beb1f000 ---p  ...  /lib/x86_64-linux-gnu/libc.so.6
> 7f75beb1f000-7f75beb23000 r--p  ...  /lib/x86_64-linux-gnu/libc.so.6
> 7f75beb23000-7f75beb25000 rw-p  ...  /lib/x86_64-linux-gnu/libc.so.6
> 7f75beb25000-7f75beb2a000 rw-p  ...
> 7f75beb2a000-7f75beb4d000 r-xp  ...  /lib64/ld-linux-x86-64.so.2
> 7f75bed45000-7f75bed46000 rw-p  ...
> 7f75bed46000-7f75bed47000 r-xp  ...
> 7f75bed47000-7f75bed4c000 rw-p  ...
> 7f75bed4c000-7f75bed4d000 r--p  ...  /lib64/ld-linux-x86-64.so.2
> 7f75bed4d000-7f75bed4e000 rw-p  ...  /lib64/ld-linux-x86-64.so.2
> 7f75bed4e000-7f75bed4f000 rw-p  ...
> 7fffb3741000-7fffb3762000 rw-p  ...  [stack]
> 7fffb377b000-7fffb377d000 r--p  ...  [vvar]
> 7fffb377d000-7fffb377f000 r-xp  ...  [vdso]
>
>
> Once corrected, the PIE linked application is loaded in a different area.

Thanks for working on this!

>
> We updated the "Fixing Offset2lib weakness" page:
> http://cybersecurity.upv.es/solutions/aslrv2/aslrv2.html
>
>
> Signed-off-by: Hector Marco-Gisbert <hecmargi@upv.es>
> Signed-off-by: Ismael Ripoll <iripoll@upv.es>

Acked-by: Kees Cook <keescook@chromium.org>

>
>
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index 97d07ed..ee7ea7e 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -1,7 +1,6 @@
>  config ARM
>         bool
>         default y
> -       select ARCH_BINFMT_ELF_RANDOMIZE_PIE
>         select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
>         select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
>         select ARCH_HAVE_CUSTOM_GPIO_H
> diff --git a/arch/arm/include/asm/elf.h b/arch/arm/include/asm/elf.h
> index afb9caf..6755cd8 100644
> --- a/arch/arm/include/asm/elf.h
> +++ b/arch/arm/include/asm/elf.h
> @@ -115,7 +115,8 @@ int dump_task_regs(struct task_struct *t, elf_gregset_t
> *elfregs);
>     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        (2 * TASK_SIZE / 3)
> +extern unsigned long randomize_et_dyn(unsigned long base);
> +#define ELF_ET_DYN_BASE        (randomize_et_dyn(2 * TASK_SIZE / 3))
>
>  /* 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
> diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c
> index 5e85ed3..9177100 100644
> --- a/arch/arm/mm/mmap.c
> +++ b/arch/arm/mm/mmap.c
> @@ -30,6 +30,17 @@ static int mmap_is_legacy(void)
>         return sysctl_legacy_va_layout;
>  }
>
> +static unsigned long mmap_rnd(void)
> +{
> +       unsigned long rnd = 0;
> +
> +       /* 8 bits of randomness in 20 address space bits */
> +       if (current->flags & PF_RANDOMIZE)
> +               rnd = (long)get_random_int() % (1 << 8);
> +
> +       return rnd << PAGE_SHIFT;
> +}
> +
>  static unsigned long mmap_base(unsigned long rnd)
>  {
>         unsigned long gap = rlimit(RLIMIT_STACK);
> @@ -230,3 +241,13 @@ int devmem_is_allowed(unsigned long pfn)
>  }
>
>  #endif
> +
> +unsigned long randomize_et_dyn(unsigned long base)
> +{
> +       unsigned long ret;
> +       if ((current->personality & ADDR_NO_RANDOMIZE) ||
> +               !(current->flags & PF_RANDOMIZE))
> +               return base;
> +       ret = base + mmap_rnd();
> +       return (ret > base) ? ret : base;
> +}
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index b1f9a20..5580d90 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -1,6 +1,5 @@
>  config ARM64
>         def_bool y
> -       select ARCH_BINFMT_ELF_RANDOMIZE_PIE
>         select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
>         select ARCH_HAS_GCOV_PROFILE_ALL
>         select ARCH_HAS_SG_CHAIN
> diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
> index 1f65be3..01d3aab 100644
> --- a/arch/arm64/include/asm/elf.h
> +++ b/arch/arm64/include/asm/elf.h
> @@ -126,7 +126,7 @@ typedef struct user_fpsimd_state elf_fpregset_t;
>   * that it will "exec", and that there is sufficient room for the brk.
>   */
>  extern unsigned long randomize_et_dyn(unsigned long base);
> -#define ELF_ET_DYN_BASE        (2 * TASK_SIZE_64 / 3)
> +#define ELF_ET_DYN_BASE        (randomize_et_dyn(2 * TASK_SIZE_64 / 3))
>
>  /*
>   * When the program starts, a1 contains a pointer to a function to be
> @@ -169,7 +169,7 @@ extern unsigned long arch_randomize_brk(struct mm_struct
> *mm);
>  #define COMPAT_ELF_PLATFORM            ("v8l")
>  #endif
>
> -#define COMPAT_ELF_ET_DYN_BASE         (2 * TASK_SIZE_32 / 3)
> +#define COMPAT_ELF_ET_DYN_BASE         (randomize_et_dyn(2 * TASK_SIZE_32 /
> 3))
>
>  /* AArch32 registers. */
>  #define COMPAT_ELF_NGREG               18
> diff --git a/arch/arm64/mm/mmap.c b/arch/arm64/mm/mmap.c
> index 54922d1..980110c50 100644
> --- a/arch/arm64/mm/mmap.c
> +++ b/arch/arm64/mm/mmap.c
> @@ -89,6 +89,16 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
>  }
>  EXPORT_SYMBOL_GPL(arch_pick_mmap_layout);
>
> +unsigned long randomize_et_dyn(unsigned long base)
> +{
> +       unsigned long ret;
> +       if ((current->personality & ADDR_NO_RANDOMIZE) ||
> +               !(current->flags & PF_RANDOMIZE))
> +               return base;
> +       ret = base + mmap_rnd();
> +       return (ret > base) ? ret : base;
> +}
> +
>
>  /*
>   * You really shouldn't be using read() or write() on /dev/mem.  This might
> go
> diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
> index 3289969..31cc248 100644
> --- a/arch/mips/Kconfig
> +++ b/arch/mips/Kconfig
> @@ -23,7 +23,6 @@ config MIPS
>         select HAVE_KRETPROBES
>         select HAVE_DEBUG_KMEMLEAK
>         select HAVE_SYSCALL_TRACEPOINTS
> -       select ARCH_BINFMT_ELF_RANDOMIZE_PIE
>         select HAVE_ARCH_TRANSPARENT_HUGEPAGE if CPU_SUPPORTS_HUGEPAGES &&
> 64BIT
>         select RTC_LIB if !MACH_LOONGSON
>         select GENERIC_ATOMIC64 if !64BIT
> diff --git a/arch/mips/include/asm/elf.h b/arch/mips/include/asm/elf.h
> index eb4d95d..fcac4c99 100644
> --- a/arch/mips/include/asm/elf.h
> +++ b/arch/mips/include/asm/elf.h
> @@ -402,7 +402,8 @@ extern const char *__elf_platform;
>     that it will "exec", and that there is sufficient room for the brk. */
>
>  #ifndef ELF_ET_DYN_BASE
> -#define ELF_ET_DYN_BASE                (TASK_SIZE / 3 * 2)
> +extern unsigned long randomize_et_dyn(unsigned long base);
> +#define ELF_ET_DYN_BASE                (randomize_et_dyn(TASK_SIZE / 3 *
> 2))
>  #endif
>
>  #define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
> diff --git a/arch/mips/mm/mmap.c b/arch/mips/mm/mmap.c
> index f1baadd..20ad644 100644
> --- a/arch/mips/mm/mmap.c
> +++ b/arch/mips/mm/mmap.c
> @@ -196,3 +196,13 @@ int __virt_addr_valid(const volatile void *kaddr)
>         return pfn_valid(PFN_DOWN(virt_to_phys(kaddr)));
>  }
>  EXPORT_SYMBOL_GPL(__virt_addr_valid);
> +
> +unsigned long randomize_et_dyn(unsigned long base)
> +{
> +       unsigned long ret;
> +       if ((current->personality & ADDR_NO_RANDOMIZE) ||
> +               !(current->flags & PF_RANDOMIZE))
> +               return base;
> +       ret = base + brk_rnd();
> +       return (ret > base) ? ret : base;
> +}
> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
> index a2a168e..fa4c877 100644
> --- a/arch/powerpc/Kconfig
> +++ b/arch/powerpc/Kconfig
> @@ -88,7 +88,6 @@ config PPC
>         select ARCH_MIGHT_HAVE_PC_PARPORT
>         select ARCH_MIGHT_HAVE_PC_SERIO
>         select BINFMT_ELF
> -       select ARCH_BINFMT_ELF_RANDOMIZE_PIE
>         select OF
>         select OF_EARLY_FLATTREE
>         select OF_RESERVED_MEM
> diff --git a/arch/powerpc/include/asm/elf.h b/arch/powerpc/include/asm/elf.h
> index 57d289a..4080425 100644
> --- a/arch/powerpc/include/asm/elf.h
> +++ b/arch/powerpc/include/asm/elf.h
> @@ -28,7 +28,8 @@
>     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
> +extern unsigned long randomize_et_dyn(unsigned long base);
> +#define ELF_ET_DYN_BASE        (randomize_et_dyn(0x20000000))
>
>  #define ELF_CORE_EFLAGS (is_elf2_task() ? 2 : 0)
>
> diff --git a/arch/powerpc/mm/mmap.c b/arch/powerpc/mm/mmap.c
> index cb8bdbe..3e642e7 100644
> --- a/arch/powerpc/mm/mmap.c
> +++ b/arch/powerpc/mm/mmap.c
> @@ -97,3 +97,13 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
>                 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
>         }
>  }
> +
> +unsigned long randomize_et_dyn(unsigned long base)
> +{
> +       unsigned long ret;
> +       if ((current->personality & ADDR_NO_RANDOMIZE) ||
> +               !(current->flags & PF_RANDOMIZE))
> +               return base;
> +       ret = base + mmap_rnd();
> +       return (ret > base) ? ret : base;
> +}
> diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
> index ba397bd..dcfe16c 100644
> --- a/arch/x86/Kconfig
> +++ b/arch/x86/Kconfig
> @@ -85,7 +85,6 @@ config X86
>         select HAVE_CMPXCHG_DOUBLE
>         select HAVE_ARCH_KMEMCHECK
>         select HAVE_USER_RETURN_NOTIFIER
> -       select ARCH_BINFMT_ELF_RANDOMIZE_PIE
>         select HAVE_ARCH_JUMP_LABEL
>         select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
>         select SPARSE_IRQ
> diff --git a/arch/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h
> index ca3347a..92c6ac4 100644
> --- a/arch/x86/include/asm/elf.h
> +++ b/arch/x86/include/asm/elf.h
> @@ -249,7 +249,8 @@ extern int force_personality32;
>     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)
> +extern unsigned long randomize_et_dyn(unsigned long base);
> +#define ELF_ET_DYN_BASE                (randomize_et_dyn(TASK_SIZE / 3 *
> 2))
>
>  /* 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/arch/x86/mm/mmap.c b/arch/x86/mm/mmap.c
> index 919b912..7b86605 100644
> --- a/arch/x86/mm/mmap.c
> +++ b/arch/x86/mm/mmap.c
> @@ -122,3 +122,12 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
>                 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
>         }
>  }
> +unsigned long randomize_et_dyn(unsigned long base)
> +{
> +       unsigned long ret;
> +       if ((current->personality & ADDR_NO_RANDOMIZE) ||
> +               !(current->flags & PF_RANDOMIZE))
> +               return base;
> +       ret = base + mmap_rnd();
> +       return (ret > base) ? ret : base;
> +}
> diff --git a/fs/Kconfig.binfmt b/fs/Kconfig.binfmt
> index c055d56..1186190 100644
> --- a/fs/Kconfig.binfmt
> +++ b/fs/Kconfig.binfmt
> @@ -27,8 +27,6 @@ config COMPAT_BINFMT_ELF
>         bool
>         depends on COMPAT && BINFMT_ELF
>
> -config ARCH_BINFMT_ELF_RANDOMIZE_PIE
> -       bool
>
>  config ARCH_BINFMT_ELF_STATE
>         bool
> diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
> index 02b1691..72f7ff5 100644
> --- a/fs/binfmt_elf.c
> +++ b/fs/binfmt_elf.c
> @@ -908,21 +908,7 @@ static int load_elf_binary(struct linux_binprm *bprm)
>                          * 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.  */
> -#ifdef CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE
> -                       /* Memory randomization might have been switched off
> -                        * in runtime via sysctl or explicit setting of
> -                        * personality flags.
> -                        * If that is the case, retain the original non-zero
> -                        * load_bias value in order to establish proper
> -                        * non-randomized mappings.
> -                        */
> -                       if (current->flags & PF_RANDOMIZE)
> -                               load_bias = 0;
> -                       else
> -                               load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE -
> vaddr);
> -#else
>                         load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
> -#endif
>                 }
>
>                 error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt,

I think this is much cleaner now without
ARCH_BINFMT_ELF_RANDOMIZE_PIE. I imagine there could be some follow-up
cleanups to standardize (or at least clearly document) the intended
levels of entropy in the 4 ASLR regions on each architecture, as it
currently varies a bit.

Thanks!

-Kees

-- 
Kees Cook
Chrome OS Security

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

* Re: [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS
@ 2015-02-23 19:34   ` Kees Cook
  0 siblings, 0 replies; 56+ messages in thread
From: Kees Cook @ 2015-02-23 19:34 UTC (permalink / raw)
  To: Hector Marco, Andrew Morton
  Cc: LKML, ismael Ripoll, x86, linux-arm-kernel,
	Linux MIPS Mailing List, linuxppc-dev

(I've added some additional CCs to make sure the arch maintainers
notice this patch.)

This patch seems white-space damaged to me. I had to do a lot of
manual editing to get it to apply. Please use "git format-patch", if
you're not already. What version of the kernel was this based on?

On Mon, Feb 23, 2015 at 10:37 AM, Hector Marco <hecmargi@upv.es> wrote:
> [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS
>
> The issue appears on PIE linked executables when all memory areas of a
> process are randomized. In this case, the attack "offset2lib" de-randomizes
> all library areas on 64 bit Linux systems in less than one second.
>
>
> Further details of the PoC attack at:
> http://cybersecurity.upv.es/attacks/offset2lib/offset2lib.html
>
>
> This patch loads the PIE linked executable in a different area than the
> libraries. The successful fix can be tested with a simple pie compiled
> application:
>
>
> $ ./show_mmaps_pie
> 54859ccd6000-54859ccd7000 r-xp  ...  /tmp/show_mmaps_pie
> 54859ced6000-54859ced7000 r--p  ...  /tmp/show_mmaps_pie
> 54859ced7000-54859ced8000 rw-p  ...  /tmp/show_mmaps_pie
> 7f75be764000-7f75be91f000 r-xp  ...  /lib/x86_64-linux-gnu/libc.so.6
> 7f75be91f000-7f75beb1f000 ---p  ...  /lib/x86_64-linux-gnu/libc.so.6
> 7f75beb1f000-7f75beb23000 r--p  ...  /lib/x86_64-linux-gnu/libc.so.6
> 7f75beb23000-7f75beb25000 rw-p  ...  /lib/x86_64-linux-gnu/libc.so.6
> 7f75beb25000-7f75beb2a000 rw-p  ...
> 7f75beb2a000-7f75beb4d000 r-xp  ...  /lib64/ld-linux-x86-64.so.2
> 7f75bed45000-7f75bed46000 rw-p  ...
> 7f75bed46000-7f75bed47000 r-xp  ...
> 7f75bed47000-7f75bed4c000 rw-p  ...
> 7f75bed4c000-7f75bed4d000 r--p  ...  /lib64/ld-linux-x86-64.so.2
> 7f75bed4d000-7f75bed4e000 rw-p  ...  /lib64/ld-linux-x86-64.so.2
> 7f75bed4e000-7f75bed4f000 rw-p  ...
> 7fffb3741000-7fffb3762000 rw-p  ...  [stack]
> 7fffb377b000-7fffb377d000 r--p  ...  [vvar]
> 7fffb377d000-7fffb377f000 r-xp  ...  [vdso]
>
>
> Once corrected, the PIE linked application is loaded in a different area.

Thanks for working on this!

>
> We updated the "Fixing Offset2lib weakness" page:
> http://cybersecurity.upv.es/solutions/aslrv2/aslrv2.html
>
>
> Signed-off-by: Hector Marco-Gisbert <hecmargi@upv.es>
> Signed-off-by: Ismael Ripoll <iripoll@upv.es>

Acked-by: Kees Cook <keescook@chromium.org>

>
>
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index 97d07ed..ee7ea7e 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -1,7 +1,6 @@
>  config ARM
>         bool
>         default y
> -       select ARCH_BINFMT_ELF_RANDOMIZE_PIE
>         select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
>         select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
>         select ARCH_HAVE_CUSTOM_GPIO_H
> diff --git a/arch/arm/include/asm/elf.h b/arch/arm/include/asm/elf.h
> index afb9caf..6755cd8 100644
> --- a/arch/arm/include/asm/elf.h
> +++ b/arch/arm/include/asm/elf.h
> @@ -115,7 +115,8 @@ int dump_task_regs(struct task_struct *t, elf_gregset_t
> *elfregs);
>     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        (2 * TASK_SIZE / 3)
> +extern unsigned long randomize_et_dyn(unsigned long base);
> +#define ELF_ET_DYN_BASE        (randomize_et_dyn(2 * TASK_SIZE / 3))
>
>  /* 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
> diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c
> index 5e85ed3..9177100 100644
> --- a/arch/arm/mm/mmap.c
> +++ b/arch/arm/mm/mmap.c
> @@ -30,6 +30,17 @@ static int mmap_is_legacy(void)
>         return sysctl_legacy_va_layout;
>  }
>
> +static unsigned long mmap_rnd(void)
> +{
> +       unsigned long rnd = 0;
> +
> +       /* 8 bits of randomness in 20 address space bits */
> +       if (current->flags & PF_RANDOMIZE)
> +               rnd = (long)get_random_int() % (1 << 8);
> +
> +       return rnd << PAGE_SHIFT;
> +}
> +
>  static unsigned long mmap_base(unsigned long rnd)
>  {
>         unsigned long gap = rlimit(RLIMIT_STACK);
> @@ -230,3 +241,13 @@ int devmem_is_allowed(unsigned long pfn)
>  }
>
>  #endif
> +
> +unsigned long randomize_et_dyn(unsigned long base)
> +{
> +       unsigned long ret;
> +       if ((current->personality & ADDR_NO_RANDOMIZE) ||
> +               !(current->flags & PF_RANDOMIZE))
> +               return base;
> +       ret = base + mmap_rnd();
> +       return (ret > base) ? ret : base;
> +}
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index b1f9a20..5580d90 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -1,6 +1,5 @@
>  config ARM64
>         def_bool y
> -       select ARCH_BINFMT_ELF_RANDOMIZE_PIE
>         select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
>         select ARCH_HAS_GCOV_PROFILE_ALL
>         select ARCH_HAS_SG_CHAIN
> diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
> index 1f65be3..01d3aab 100644
> --- a/arch/arm64/include/asm/elf.h
> +++ b/arch/arm64/include/asm/elf.h
> @@ -126,7 +126,7 @@ typedef struct user_fpsimd_state elf_fpregset_t;
>   * that it will "exec", and that there is sufficient room for the brk.
>   */
>  extern unsigned long randomize_et_dyn(unsigned long base);
> -#define ELF_ET_DYN_BASE        (2 * TASK_SIZE_64 / 3)
> +#define ELF_ET_DYN_BASE        (randomize_et_dyn(2 * TASK_SIZE_64 / 3))
>
>  /*
>   * When the program starts, a1 contains a pointer to a function to be
> @@ -169,7 +169,7 @@ extern unsigned long arch_randomize_brk(struct mm_struct
> *mm);
>  #define COMPAT_ELF_PLATFORM            ("v8l")
>  #endif
>
> -#define COMPAT_ELF_ET_DYN_BASE         (2 * TASK_SIZE_32 / 3)
> +#define COMPAT_ELF_ET_DYN_BASE         (randomize_et_dyn(2 * TASK_SIZE_32 /
> 3))
>
>  /* AArch32 registers. */
>  #define COMPAT_ELF_NGREG               18
> diff --git a/arch/arm64/mm/mmap.c b/arch/arm64/mm/mmap.c
> index 54922d1..980110c50 100644
> --- a/arch/arm64/mm/mmap.c
> +++ b/arch/arm64/mm/mmap.c
> @@ -89,6 +89,16 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
>  }
>  EXPORT_SYMBOL_GPL(arch_pick_mmap_layout);
>
> +unsigned long randomize_et_dyn(unsigned long base)
> +{
> +       unsigned long ret;
> +       if ((current->personality & ADDR_NO_RANDOMIZE) ||
> +               !(current->flags & PF_RANDOMIZE))
> +               return base;
> +       ret = base + mmap_rnd();
> +       return (ret > base) ? ret : base;
> +}
> +
>
>  /*
>   * You really shouldn't be using read() or write() on /dev/mem.  This might
> go
> diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
> index 3289969..31cc248 100644
> --- a/arch/mips/Kconfig
> +++ b/arch/mips/Kconfig
> @@ -23,7 +23,6 @@ config MIPS
>         select HAVE_KRETPROBES
>         select HAVE_DEBUG_KMEMLEAK
>         select HAVE_SYSCALL_TRACEPOINTS
> -       select ARCH_BINFMT_ELF_RANDOMIZE_PIE
>         select HAVE_ARCH_TRANSPARENT_HUGEPAGE if CPU_SUPPORTS_HUGEPAGES &&
> 64BIT
>         select RTC_LIB if !MACH_LOONGSON
>         select GENERIC_ATOMIC64 if !64BIT
> diff --git a/arch/mips/include/asm/elf.h b/arch/mips/include/asm/elf.h
> index eb4d95d..fcac4c99 100644
> --- a/arch/mips/include/asm/elf.h
> +++ b/arch/mips/include/asm/elf.h
> @@ -402,7 +402,8 @@ extern const char *__elf_platform;
>     that it will "exec", and that there is sufficient room for the brk. */
>
>  #ifndef ELF_ET_DYN_BASE
> -#define ELF_ET_DYN_BASE                (TASK_SIZE / 3 * 2)
> +extern unsigned long randomize_et_dyn(unsigned long base);
> +#define ELF_ET_DYN_BASE                (randomize_et_dyn(TASK_SIZE / 3 *
> 2))
>  #endif
>
>  #define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
> diff --git a/arch/mips/mm/mmap.c b/arch/mips/mm/mmap.c
> index f1baadd..20ad644 100644
> --- a/arch/mips/mm/mmap.c
> +++ b/arch/mips/mm/mmap.c
> @@ -196,3 +196,13 @@ int __virt_addr_valid(const volatile void *kaddr)
>         return pfn_valid(PFN_DOWN(virt_to_phys(kaddr)));
>  }
>  EXPORT_SYMBOL_GPL(__virt_addr_valid);
> +
> +unsigned long randomize_et_dyn(unsigned long base)
> +{
> +       unsigned long ret;
> +       if ((current->personality & ADDR_NO_RANDOMIZE) ||
> +               !(current->flags & PF_RANDOMIZE))
> +               return base;
> +       ret = base + brk_rnd();
> +       return (ret > base) ? ret : base;
> +}
> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
> index a2a168e..fa4c877 100644
> --- a/arch/powerpc/Kconfig
> +++ b/arch/powerpc/Kconfig
> @@ -88,7 +88,6 @@ config PPC
>         select ARCH_MIGHT_HAVE_PC_PARPORT
>         select ARCH_MIGHT_HAVE_PC_SERIO
>         select BINFMT_ELF
> -       select ARCH_BINFMT_ELF_RANDOMIZE_PIE
>         select OF
>         select OF_EARLY_FLATTREE
>         select OF_RESERVED_MEM
> diff --git a/arch/powerpc/include/asm/elf.h b/arch/powerpc/include/asm/elf.h
> index 57d289a..4080425 100644
> --- a/arch/powerpc/include/asm/elf.h
> +++ b/arch/powerpc/include/asm/elf.h
> @@ -28,7 +28,8 @@
>     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
> +extern unsigned long randomize_et_dyn(unsigned long base);
> +#define ELF_ET_DYN_BASE        (randomize_et_dyn(0x20000000))
>
>  #define ELF_CORE_EFLAGS (is_elf2_task() ? 2 : 0)
>
> diff --git a/arch/powerpc/mm/mmap.c b/arch/powerpc/mm/mmap.c
> index cb8bdbe..3e642e7 100644
> --- a/arch/powerpc/mm/mmap.c
> +++ b/arch/powerpc/mm/mmap.c
> @@ -97,3 +97,13 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
>                 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
>         }
>  }
> +
> +unsigned long randomize_et_dyn(unsigned long base)
> +{
> +       unsigned long ret;
> +       if ((current->personality & ADDR_NO_RANDOMIZE) ||
> +               !(current->flags & PF_RANDOMIZE))
> +               return base;
> +       ret = base + mmap_rnd();
> +       return (ret > base) ? ret : base;
> +}
> diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
> index ba397bd..dcfe16c 100644
> --- a/arch/x86/Kconfig
> +++ b/arch/x86/Kconfig
> @@ -85,7 +85,6 @@ config X86
>         select HAVE_CMPXCHG_DOUBLE
>         select HAVE_ARCH_KMEMCHECK
>         select HAVE_USER_RETURN_NOTIFIER
> -       select ARCH_BINFMT_ELF_RANDOMIZE_PIE
>         select HAVE_ARCH_JUMP_LABEL
>         select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
>         select SPARSE_IRQ
> diff --git a/arch/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h
> index ca3347a..92c6ac4 100644
> --- a/arch/x86/include/asm/elf.h
> +++ b/arch/x86/include/asm/elf.h
> @@ -249,7 +249,8 @@ extern int force_personality32;
>     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)
> +extern unsigned long randomize_et_dyn(unsigned long base);
> +#define ELF_ET_DYN_BASE                (randomize_et_dyn(TASK_SIZE / 3 *
> 2))
>
>  /* 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/arch/x86/mm/mmap.c b/arch/x86/mm/mmap.c
> index 919b912..7b86605 100644
> --- a/arch/x86/mm/mmap.c
> +++ b/arch/x86/mm/mmap.c
> @@ -122,3 +122,12 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
>                 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
>         }
>  }
> +unsigned long randomize_et_dyn(unsigned long base)
> +{
> +       unsigned long ret;
> +       if ((current->personality & ADDR_NO_RANDOMIZE) ||
> +               !(current->flags & PF_RANDOMIZE))
> +               return base;
> +       ret = base + mmap_rnd();
> +       return (ret > base) ? ret : base;
> +}
> diff --git a/fs/Kconfig.binfmt b/fs/Kconfig.binfmt
> index c055d56..1186190 100644
> --- a/fs/Kconfig.binfmt
> +++ b/fs/Kconfig.binfmt
> @@ -27,8 +27,6 @@ config COMPAT_BINFMT_ELF
>         bool
>         depends on COMPAT && BINFMT_ELF
>
> -config ARCH_BINFMT_ELF_RANDOMIZE_PIE
> -       bool
>
>  config ARCH_BINFMT_ELF_STATE
>         bool
> diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
> index 02b1691..72f7ff5 100644
> --- a/fs/binfmt_elf.c
> +++ b/fs/binfmt_elf.c
> @@ -908,21 +908,7 @@ static int load_elf_binary(struct linux_binprm *bprm)
>                          * 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.  */
> -#ifdef CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE
> -                       /* Memory randomization might have been switched off
> -                        * in runtime via sysctl or explicit setting of
> -                        * personality flags.
> -                        * If that is the case, retain the original non-zero
> -                        * load_bias value in order to establish proper
> -                        * non-randomized mappings.
> -                        */
> -                       if (current->flags & PF_RANDOMIZE)
> -                               load_bias = 0;
> -                       else
> -                               load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE -
> vaddr);
> -#else
>                         load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
> -#endif
>                 }
>
>                 error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt,

I think this is much cleaner now without
ARCH_BINFMT_ELF_RANDOMIZE_PIE. I imagine there could be some follow-up
cleanups to standardize (or at least clearly document) the intended
levels of entropy in the 4 ASLR regions on each architecture, as it
currently varies a bit.

Thanks!

-Kees

-- 
Kees Cook
Chrome OS Security

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

* Re: [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS
@ 2015-02-23 19:34   ` Kees Cook
  0 siblings, 0 replies; 56+ messages in thread
From: Kees Cook @ 2015-02-23 19:34 UTC (permalink / raw)
  To: Hector Marco, Andrew Morton
  Cc: Linux MIPS Mailing List, x86, LKML, ismael Ripoll, linuxppc-dev,
	linux-arm-kernel

(I've added some additional CCs to make sure the arch maintainers
notice this patch.)

This patch seems white-space damaged to me. I had to do a lot of
manual editing to get it to apply. Please use "git format-patch", if
you're not already. What version of the kernel was this based on?

On Mon, Feb 23, 2015 at 10:37 AM, Hector Marco <hecmargi@upv.es> wrote:
> [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS
>
> The issue appears on PIE linked executables when all memory areas of a
> process are randomized. In this case, the attack "offset2lib" de-randomizes
> all library areas on 64 bit Linux systems in less than one second.
>
>
> Further details of the PoC attack at:
> http://cybersecurity.upv.es/attacks/offset2lib/offset2lib.html
>
>
> This patch loads the PIE linked executable in a different area than the
> libraries. The successful fix can be tested with a simple pie compiled
> application:
>
>
> $ ./show_mmaps_pie
> 54859ccd6000-54859ccd7000 r-xp  ...  /tmp/show_mmaps_pie
> 54859ced6000-54859ced7000 r--p  ...  /tmp/show_mmaps_pie
> 54859ced7000-54859ced8000 rw-p  ...  /tmp/show_mmaps_pie
> 7f75be764000-7f75be91f000 r-xp  ...  /lib/x86_64-linux-gnu/libc.so.6
> 7f75be91f000-7f75beb1f000 ---p  ...  /lib/x86_64-linux-gnu/libc.so.6
> 7f75beb1f000-7f75beb23000 r--p  ...  /lib/x86_64-linux-gnu/libc.so.6
> 7f75beb23000-7f75beb25000 rw-p  ...  /lib/x86_64-linux-gnu/libc.so.6
> 7f75beb25000-7f75beb2a000 rw-p  ...
> 7f75beb2a000-7f75beb4d000 r-xp  ...  /lib64/ld-linux-x86-64.so.2
> 7f75bed45000-7f75bed46000 rw-p  ...
> 7f75bed46000-7f75bed47000 r-xp  ...
> 7f75bed47000-7f75bed4c000 rw-p  ...
> 7f75bed4c000-7f75bed4d000 r--p  ...  /lib64/ld-linux-x86-64.so.2
> 7f75bed4d000-7f75bed4e000 rw-p  ...  /lib64/ld-linux-x86-64.so.2
> 7f75bed4e000-7f75bed4f000 rw-p  ...
> 7fffb3741000-7fffb3762000 rw-p  ...  [stack]
> 7fffb377b000-7fffb377d000 r--p  ...  [vvar]
> 7fffb377d000-7fffb377f000 r-xp  ...  [vdso]
>
>
> Once corrected, the PIE linked application is loaded in a different area.

Thanks for working on this!

>
> We updated the "Fixing Offset2lib weakness" page:
> http://cybersecurity.upv.es/solutions/aslrv2/aslrv2.html
>
>
> Signed-off-by: Hector Marco-Gisbert <hecmargi@upv.es>
> Signed-off-by: Ismael Ripoll <iripoll@upv.es>

Acked-by: Kees Cook <keescook@chromium.org>

>
>
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index 97d07ed..ee7ea7e 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -1,7 +1,6 @@
>  config ARM
>         bool
>         default y
> -       select ARCH_BINFMT_ELF_RANDOMIZE_PIE
>         select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
>         select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
>         select ARCH_HAVE_CUSTOM_GPIO_H
> diff --git a/arch/arm/include/asm/elf.h b/arch/arm/include/asm/elf.h
> index afb9caf..6755cd8 100644
> --- a/arch/arm/include/asm/elf.h
> +++ b/arch/arm/include/asm/elf.h
> @@ -115,7 +115,8 @@ int dump_task_regs(struct task_struct *t, elf_gregset_t
> *elfregs);
>     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        (2 * TASK_SIZE / 3)
> +extern unsigned long randomize_et_dyn(unsigned long base);
> +#define ELF_ET_DYN_BASE        (randomize_et_dyn(2 * TASK_SIZE / 3))
>
>  /* 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
> diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c
> index 5e85ed3..9177100 100644
> --- a/arch/arm/mm/mmap.c
> +++ b/arch/arm/mm/mmap.c
> @@ -30,6 +30,17 @@ static int mmap_is_legacy(void)
>         return sysctl_legacy_va_layout;
>  }
>
> +static unsigned long mmap_rnd(void)
> +{
> +       unsigned long rnd = 0;
> +
> +       /* 8 bits of randomness in 20 address space bits */
> +       if (current->flags & PF_RANDOMIZE)
> +               rnd = (long)get_random_int() % (1 << 8);
> +
> +       return rnd << PAGE_SHIFT;
> +}
> +
>  static unsigned long mmap_base(unsigned long rnd)
>  {
>         unsigned long gap = rlimit(RLIMIT_STACK);
> @@ -230,3 +241,13 @@ int devmem_is_allowed(unsigned long pfn)
>  }
>
>  #endif
> +
> +unsigned long randomize_et_dyn(unsigned long base)
> +{
> +       unsigned long ret;
> +       if ((current->personality & ADDR_NO_RANDOMIZE) ||
> +               !(current->flags & PF_RANDOMIZE))
> +               return base;
> +       ret = base + mmap_rnd();
> +       return (ret > base) ? ret : base;
> +}
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index b1f9a20..5580d90 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -1,6 +1,5 @@
>  config ARM64
>         def_bool y
> -       select ARCH_BINFMT_ELF_RANDOMIZE_PIE
>         select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
>         select ARCH_HAS_GCOV_PROFILE_ALL
>         select ARCH_HAS_SG_CHAIN
> diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
> index 1f65be3..01d3aab 100644
> --- a/arch/arm64/include/asm/elf.h
> +++ b/arch/arm64/include/asm/elf.h
> @@ -126,7 +126,7 @@ typedef struct user_fpsimd_state elf_fpregset_t;
>   * that it will "exec", and that there is sufficient room for the brk.
>   */
>  extern unsigned long randomize_et_dyn(unsigned long base);
> -#define ELF_ET_DYN_BASE        (2 * TASK_SIZE_64 / 3)
> +#define ELF_ET_DYN_BASE        (randomize_et_dyn(2 * TASK_SIZE_64 / 3))
>
>  /*
>   * When the program starts, a1 contains a pointer to a function to be
> @@ -169,7 +169,7 @@ extern unsigned long arch_randomize_brk(struct mm_struct
> *mm);
>  #define COMPAT_ELF_PLATFORM            ("v8l")
>  #endif
>
> -#define COMPAT_ELF_ET_DYN_BASE         (2 * TASK_SIZE_32 / 3)
> +#define COMPAT_ELF_ET_DYN_BASE         (randomize_et_dyn(2 * TASK_SIZE_32 /
> 3))
>
>  /* AArch32 registers. */
>  #define COMPAT_ELF_NGREG               18
> diff --git a/arch/arm64/mm/mmap.c b/arch/arm64/mm/mmap.c
> index 54922d1..980110c50 100644
> --- a/arch/arm64/mm/mmap.c
> +++ b/arch/arm64/mm/mmap.c
> @@ -89,6 +89,16 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
>  }
>  EXPORT_SYMBOL_GPL(arch_pick_mmap_layout);
>
> +unsigned long randomize_et_dyn(unsigned long base)
> +{
> +       unsigned long ret;
> +       if ((current->personality & ADDR_NO_RANDOMIZE) ||
> +               !(current->flags & PF_RANDOMIZE))
> +               return base;
> +       ret = base + mmap_rnd();
> +       return (ret > base) ? ret : base;
> +}
> +
>
>  /*
>   * You really shouldn't be using read() or write() on /dev/mem.  This might
> go
> diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
> index 3289969..31cc248 100644
> --- a/arch/mips/Kconfig
> +++ b/arch/mips/Kconfig
> @@ -23,7 +23,6 @@ config MIPS
>         select HAVE_KRETPROBES
>         select HAVE_DEBUG_KMEMLEAK
>         select HAVE_SYSCALL_TRACEPOINTS
> -       select ARCH_BINFMT_ELF_RANDOMIZE_PIE
>         select HAVE_ARCH_TRANSPARENT_HUGEPAGE if CPU_SUPPORTS_HUGEPAGES &&
> 64BIT
>         select RTC_LIB if !MACH_LOONGSON
>         select GENERIC_ATOMIC64 if !64BIT
> diff --git a/arch/mips/include/asm/elf.h b/arch/mips/include/asm/elf.h
> index eb4d95d..fcac4c99 100644
> --- a/arch/mips/include/asm/elf.h
> +++ b/arch/mips/include/asm/elf.h
> @@ -402,7 +402,8 @@ extern const char *__elf_platform;
>     that it will "exec", and that there is sufficient room for the brk. */
>
>  #ifndef ELF_ET_DYN_BASE
> -#define ELF_ET_DYN_BASE                (TASK_SIZE / 3 * 2)
> +extern unsigned long randomize_et_dyn(unsigned long base);
> +#define ELF_ET_DYN_BASE                (randomize_et_dyn(TASK_SIZE / 3 *
> 2))
>  #endif
>
>  #define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
> diff --git a/arch/mips/mm/mmap.c b/arch/mips/mm/mmap.c
> index f1baadd..20ad644 100644
> --- a/arch/mips/mm/mmap.c
> +++ b/arch/mips/mm/mmap.c
> @@ -196,3 +196,13 @@ int __virt_addr_valid(const volatile void *kaddr)
>         return pfn_valid(PFN_DOWN(virt_to_phys(kaddr)));
>  }
>  EXPORT_SYMBOL_GPL(__virt_addr_valid);
> +
> +unsigned long randomize_et_dyn(unsigned long base)
> +{
> +       unsigned long ret;
> +       if ((current->personality & ADDR_NO_RANDOMIZE) ||
> +               !(current->flags & PF_RANDOMIZE))
> +               return base;
> +       ret = base + brk_rnd();
> +       return (ret > base) ? ret : base;
> +}
> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
> index a2a168e..fa4c877 100644
> --- a/arch/powerpc/Kconfig
> +++ b/arch/powerpc/Kconfig
> @@ -88,7 +88,6 @@ config PPC
>         select ARCH_MIGHT_HAVE_PC_PARPORT
>         select ARCH_MIGHT_HAVE_PC_SERIO
>         select BINFMT_ELF
> -       select ARCH_BINFMT_ELF_RANDOMIZE_PIE
>         select OF
>         select OF_EARLY_FLATTREE
>         select OF_RESERVED_MEM
> diff --git a/arch/powerpc/include/asm/elf.h b/arch/powerpc/include/asm/elf.h
> index 57d289a..4080425 100644
> --- a/arch/powerpc/include/asm/elf.h
> +++ b/arch/powerpc/include/asm/elf.h
> @@ -28,7 +28,8 @@
>     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
> +extern unsigned long randomize_et_dyn(unsigned long base);
> +#define ELF_ET_DYN_BASE        (randomize_et_dyn(0x20000000))
>
>  #define ELF_CORE_EFLAGS (is_elf2_task() ? 2 : 0)
>
> diff --git a/arch/powerpc/mm/mmap.c b/arch/powerpc/mm/mmap.c
> index cb8bdbe..3e642e7 100644
> --- a/arch/powerpc/mm/mmap.c
> +++ b/arch/powerpc/mm/mmap.c
> @@ -97,3 +97,13 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
>                 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
>         }
>  }
> +
> +unsigned long randomize_et_dyn(unsigned long base)
> +{
> +       unsigned long ret;
> +       if ((current->personality & ADDR_NO_RANDOMIZE) ||
> +               !(current->flags & PF_RANDOMIZE))
> +               return base;
> +       ret = base + mmap_rnd();
> +       return (ret > base) ? ret : base;
> +}
> diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
> index ba397bd..dcfe16c 100644
> --- a/arch/x86/Kconfig
> +++ b/arch/x86/Kconfig
> @@ -85,7 +85,6 @@ config X86
>         select HAVE_CMPXCHG_DOUBLE
>         select HAVE_ARCH_KMEMCHECK
>         select HAVE_USER_RETURN_NOTIFIER
> -       select ARCH_BINFMT_ELF_RANDOMIZE_PIE
>         select HAVE_ARCH_JUMP_LABEL
>         select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
>         select SPARSE_IRQ
> diff --git a/arch/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h
> index ca3347a..92c6ac4 100644
> --- a/arch/x86/include/asm/elf.h
> +++ b/arch/x86/include/asm/elf.h
> @@ -249,7 +249,8 @@ extern int force_personality32;
>     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)
> +extern unsigned long randomize_et_dyn(unsigned long base);
> +#define ELF_ET_DYN_BASE                (randomize_et_dyn(TASK_SIZE / 3 *
> 2))
>
>  /* 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/arch/x86/mm/mmap.c b/arch/x86/mm/mmap.c
> index 919b912..7b86605 100644
> --- a/arch/x86/mm/mmap.c
> +++ b/arch/x86/mm/mmap.c
> @@ -122,3 +122,12 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
>                 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
>         }
>  }
> +unsigned long randomize_et_dyn(unsigned long base)
> +{
> +       unsigned long ret;
> +       if ((current->personality & ADDR_NO_RANDOMIZE) ||
> +               !(current->flags & PF_RANDOMIZE))
> +               return base;
> +       ret = base + mmap_rnd();
> +       return (ret > base) ? ret : base;
> +}
> diff --git a/fs/Kconfig.binfmt b/fs/Kconfig.binfmt
> index c055d56..1186190 100644
> --- a/fs/Kconfig.binfmt
> +++ b/fs/Kconfig.binfmt
> @@ -27,8 +27,6 @@ config COMPAT_BINFMT_ELF
>         bool
>         depends on COMPAT && BINFMT_ELF
>
> -config ARCH_BINFMT_ELF_RANDOMIZE_PIE
> -       bool
>
>  config ARCH_BINFMT_ELF_STATE
>         bool
> diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
> index 02b1691..72f7ff5 100644
> --- a/fs/binfmt_elf.c
> +++ b/fs/binfmt_elf.c
> @@ -908,21 +908,7 @@ static int load_elf_binary(struct linux_binprm *bprm)
>                          * 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.  */
> -#ifdef CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE
> -                       /* Memory randomization might have been switched off
> -                        * in runtime via sysctl or explicit setting of
> -                        * personality flags.
> -                        * If that is the case, retain the original non-zero
> -                        * load_bias value in order to establish proper
> -                        * non-randomized mappings.
> -                        */
> -                       if (current->flags & PF_RANDOMIZE)
> -                               load_bias = 0;
> -                       else
> -                               load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE -
> vaddr);
> -#else
>                         load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
> -#endif
>                 }
>
>                 error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt,

I think this is much cleaner now without
ARCH_BINFMT_ELF_RANDOMIZE_PIE. I imagine there could be some follow-up
cleanups to standardize (or at least clearly document) the intended
levels of entropy in the 4 ASLR regions on each architecture, as it
currently varies a bit.

Thanks!

-Kees

-- 
Kees Cook
Chrome OS Security

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

* [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS
@ 2015-02-23 19:34   ` Kees Cook
  0 siblings, 0 replies; 56+ messages in thread
From: Kees Cook @ 2015-02-23 19:34 UTC (permalink / raw)
  To: linux-arm-kernel

(I've added some additional CCs to make sure the arch maintainers
notice this patch.)

This patch seems white-space damaged to me. I had to do a lot of
manual editing to get it to apply. Please use "git format-patch", if
you're not already. What version of the kernel was this based on?

On Mon, Feb 23, 2015 at 10:37 AM, Hector Marco <hecmargi@upv.es> wrote:
> [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS
>
> The issue appears on PIE linked executables when all memory areas of a
> process are randomized. In this case, the attack "offset2lib" de-randomizes
> all library areas on 64 bit Linux systems in less than one second.
>
>
> Further details of the PoC attack at:
> http://cybersecurity.upv.es/attacks/offset2lib/offset2lib.html
>
>
> This patch loads the PIE linked executable in a different area than the
> libraries. The successful fix can be tested with a simple pie compiled
> application:
>
>
> $ ./show_mmaps_pie
> 54859ccd6000-54859ccd7000 r-xp  ...  /tmp/show_mmaps_pie
> 54859ced6000-54859ced7000 r--p  ...  /tmp/show_mmaps_pie
> 54859ced7000-54859ced8000 rw-p  ...  /tmp/show_mmaps_pie
> 7f75be764000-7f75be91f000 r-xp  ...  /lib/x86_64-linux-gnu/libc.so.6
> 7f75be91f000-7f75beb1f000 ---p  ...  /lib/x86_64-linux-gnu/libc.so.6
> 7f75beb1f000-7f75beb23000 r--p  ...  /lib/x86_64-linux-gnu/libc.so.6
> 7f75beb23000-7f75beb25000 rw-p  ...  /lib/x86_64-linux-gnu/libc.so.6
> 7f75beb25000-7f75beb2a000 rw-p  ...
> 7f75beb2a000-7f75beb4d000 r-xp  ...  /lib64/ld-linux-x86-64.so.2
> 7f75bed45000-7f75bed46000 rw-p  ...
> 7f75bed46000-7f75bed47000 r-xp  ...
> 7f75bed47000-7f75bed4c000 rw-p  ...
> 7f75bed4c000-7f75bed4d000 r--p  ...  /lib64/ld-linux-x86-64.so.2
> 7f75bed4d000-7f75bed4e000 rw-p  ...  /lib64/ld-linux-x86-64.so.2
> 7f75bed4e000-7f75bed4f000 rw-p  ...
> 7fffb3741000-7fffb3762000 rw-p  ...  [stack]
> 7fffb377b000-7fffb377d000 r--p  ...  [vvar]
> 7fffb377d000-7fffb377f000 r-xp  ...  [vdso]
>
>
> Once corrected, the PIE linked application is loaded in a different area.

Thanks for working on this!

>
> We updated the "Fixing Offset2lib weakness" page:
> http://cybersecurity.upv.es/solutions/aslrv2/aslrv2.html
>
>
> Signed-off-by: Hector Marco-Gisbert <hecmargi@upv.es>
> Signed-off-by: Ismael Ripoll <iripoll@upv.es>

Acked-by: Kees Cook <keescook@chromium.org>

>
>
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index 97d07ed..ee7ea7e 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -1,7 +1,6 @@
>  config ARM
>         bool
>         default y
> -       select ARCH_BINFMT_ELF_RANDOMIZE_PIE
>         select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
>         select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
>         select ARCH_HAVE_CUSTOM_GPIO_H
> diff --git a/arch/arm/include/asm/elf.h b/arch/arm/include/asm/elf.h
> index afb9caf..6755cd8 100644
> --- a/arch/arm/include/asm/elf.h
> +++ b/arch/arm/include/asm/elf.h
> @@ -115,7 +115,8 @@ int dump_task_regs(struct task_struct *t, elf_gregset_t
> *elfregs);
>     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        (2 * TASK_SIZE / 3)
> +extern unsigned long randomize_et_dyn(unsigned long base);
> +#define ELF_ET_DYN_BASE        (randomize_et_dyn(2 * TASK_SIZE / 3))
>
>  /* 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
> diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c
> index 5e85ed3..9177100 100644
> --- a/arch/arm/mm/mmap.c
> +++ b/arch/arm/mm/mmap.c
> @@ -30,6 +30,17 @@ static int mmap_is_legacy(void)
>         return sysctl_legacy_va_layout;
>  }
>
> +static unsigned long mmap_rnd(void)
> +{
> +       unsigned long rnd = 0;
> +
> +       /* 8 bits of randomness in 20 address space bits */
> +       if (current->flags & PF_RANDOMIZE)
> +               rnd = (long)get_random_int() % (1 << 8);
> +
> +       return rnd << PAGE_SHIFT;
> +}
> +
>  static unsigned long mmap_base(unsigned long rnd)
>  {
>         unsigned long gap = rlimit(RLIMIT_STACK);
> @@ -230,3 +241,13 @@ int devmem_is_allowed(unsigned long pfn)
>  }
>
>  #endif
> +
> +unsigned long randomize_et_dyn(unsigned long base)
> +{
> +       unsigned long ret;
> +       if ((current->personality & ADDR_NO_RANDOMIZE) ||
> +               !(current->flags & PF_RANDOMIZE))
> +               return base;
> +       ret = base + mmap_rnd();
> +       return (ret > base) ? ret : base;
> +}
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index b1f9a20..5580d90 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -1,6 +1,5 @@
>  config ARM64
>         def_bool y
> -       select ARCH_BINFMT_ELF_RANDOMIZE_PIE
>         select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
>         select ARCH_HAS_GCOV_PROFILE_ALL
>         select ARCH_HAS_SG_CHAIN
> diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
> index 1f65be3..01d3aab 100644
> --- a/arch/arm64/include/asm/elf.h
> +++ b/arch/arm64/include/asm/elf.h
> @@ -126,7 +126,7 @@ typedef struct user_fpsimd_state elf_fpregset_t;
>   * that it will "exec", and that there is sufficient room for the brk.
>   */
>  extern unsigned long randomize_et_dyn(unsigned long base);
> -#define ELF_ET_DYN_BASE        (2 * TASK_SIZE_64 / 3)
> +#define ELF_ET_DYN_BASE        (randomize_et_dyn(2 * TASK_SIZE_64 / 3))
>
>  /*
>   * When the program starts, a1 contains a pointer to a function to be
> @@ -169,7 +169,7 @@ extern unsigned long arch_randomize_brk(struct mm_struct
> *mm);
>  #define COMPAT_ELF_PLATFORM            ("v8l")
>  #endif
>
> -#define COMPAT_ELF_ET_DYN_BASE         (2 * TASK_SIZE_32 / 3)
> +#define COMPAT_ELF_ET_DYN_BASE         (randomize_et_dyn(2 * TASK_SIZE_32 /
> 3))
>
>  /* AArch32 registers. */
>  #define COMPAT_ELF_NGREG               18
> diff --git a/arch/arm64/mm/mmap.c b/arch/arm64/mm/mmap.c
> index 54922d1..980110c50 100644
> --- a/arch/arm64/mm/mmap.c
> +++ b/arch/arm64/mm/mmap.c
> @@ -89,6 +89,16 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
>  }
>  EXPORT_SYMBOL_GPL(arch_pick_mmap_layout);
>
> +unsigned long randomize_et_dyn(unsigned long base)
> +{
> +       unsigned long ret;
> +       if ((current->personality & ADDR_NO_RANDOMIZE) ||
> +               !(current->flags & PF_RANDOMIZE))
> +               return base;
> +       ret = base + mmap_rnd();
> +       return (ret > base) ? ret : base;
> +}
> +
>
>  /*
>   * You really shouldn't be using read() or write() on /dev/mem.  This might
> go
> diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
> index 3289969..31cc248 100644
> --- a/arch/mips/Kconfig
> +++ b/arch/mips/Kconfig
> @@ -23,7 +23,6 @@ config MIPS
>         select HAVE_KRETPROBES
>         select HAVE_DEBUG_KMEMLEAK
>         select HAVE_SYSCALL_TRACEPOINTS
> -       select ARCH_BINFMT_ELF_RANDOMIZE_PIE
>         select HAVE_ARCH_TRANSPARENT_HUGEPAGE if CPU_SUPPORTS_HUGEPAGES &&
> 64BIT
>         select RTC_LIB if !MACH_LOONGSON
>         select GENERIC_ATOMIC64 if !64BIT
> diff --git a/arch/mips/include/asm/elf.h b/arch/mips/include/asm/elf.h
> index eb4d95d..fcac4c99 100644
> --- a/arch/mips/include/asm/elf.h
> +++ b/arch/mips/include/asm/elf.h
> @@ -402,7 +402,8 @@ extern const char *__elf_platform;
>     that it will "exec", and that there is sufficient room for the brk. */
>
>  #ifndef ELF_ET_DYN_BASE
> -#define ELF_ET_DYN_BASE                (TASK_SIZE / 3 * 2)
> +extern unsigned long randomize_et_dyn(unsigned long base);
> +#define ELF_ET_DYN_BASE                (randomize_et_dyn(TASK_SIZE / 3 *
> 2))
>  #endif
>
>  #define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
> diff --git a/arch/mips/mm/mmap.c b/arch/mips/mm/mmap.c
> index f1baadd..20ad644 100644
> --- a/arch/mips/mm/mmap.c
> +++ b/arch/mips/mm/mmap.c
> @@ -196,3 +196,13 @@ int __virt_addr_valid(const volatile void *kaddr)
>         return pfn_valid(PFN_DOWN(virt_to_phys(kaddr)));
>  }
>  EXPORT_SYMBOL_GPL(__virt_addr_valid);
> +
> +unsigned long randomize_et_dyn(unsigned long base)
> +{
> +       unsigned long ret;
> +       if ((current->personality & ADDR_NO_RANDOMIZE) ||
> +               !(current->flags & PF_RANDOMIZE))
> +               return base;
> +       ret = base + brk_rnd();
> +       return (ret > base) ? ret : base;
> +}
> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
> index a2a168e..fa4c877 100644
> --- a/arch/powerpc/Kconfig
> +++ b/arch/powerpc/Kconfig
> @@ -88,7 +88,6 @@ config PPC
>         select ARCH_MIGHT_HAVE_PC_PARPORT
>         select ARCH_MIGHT_HAVE_PC_SERIO
>         select BINFMT_ELF
> -       select ARCH_BINFMT_ELF_RANDOMIZE_PIE
>         select OF
>         select OF_EARLY_FLATTREE
>         select OF_RESERVED_MEM
> diff --git a/arch/powerpc/include/asm/elf.h b/arch/powerpc/include/asm/elf.h
> index 57d289a..4080425 100644
> --- a/arch/powerpc/include/asm/elf.h
> +++ b/arch/powerpc/include/asm/elf.h
> @@ -28,7 +28,8 @@
>     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
> +extern unsigned long randomize_et_dyn(unsigned long base);
> +#define ELF_ET_DYN_BASE        (randomize_et_dyn(0x20000000))
>
>  #define ELF_CORE_EFLAGS (is_elf2_task() ? 2 : 0)
>
> diff --git a/arch/powerpc/mm/mmap.c b/arch/powerpc/mm/mmap.c
> index cb8bdbe..3e642e7 100644
> --- a/arch/powerpc/mm/mmap.c
> +++ b/arch/powerpc/mm/mmap.c
> @@ -97,3 +97,13 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
>                 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
>         }
>  }
> +
> +unsigned long randomize_et_dyn(unsigned long base)
> +{
> +       unsigned long ret;
> +       if ((current->personality & ADDR_NO_RANDOMIZE) ||
> +               !(current->flags & PF_RANDOMIZE))
> +               return base;
> +       ret = base + mmap_rnd();
> +       return (ret > base) ? ret : base;
> +}
> diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
> index ba397bd..dcfe16c 100644
> --- a/arch/x86/Kconfig
> +++ b/arch/x86/Kconfig
> @@ -85,7 +85,6 @@ config X86
>         select HAVE_CMPXCHG_DOUBLE
>         select HAVE_ARCH_KMEMCHECK
>         select HAVE_USER_RETURN_NOTIFIER
> -       select ARCH_BINFMT_ELF_RANDOMIZE_PIE
>         select HAVE_ARCH_JUMP_LABEL
>         select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
>         select SPARSE_IRQ
> diff --git a/arch/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h
> index ca3347a..92c6ac4 100644
> --- a/arch/x86/include/asm/elf.h
> +++ b/arch/x86/include/asm/elf.h
> @@ -249,7 +249,8 @@ extern int force_personality32;
>     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)
> +extern unsigned long randomize_et_dyn(unsigned long base);
> +#define ELF_ET_DYN_BASE                (randomize_et_dyn(TASK_SIZE / 3 *
> 2))
>
>  /* 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/arch/x86/mm/mmap.c b/arch/x86/mm/mmap.c
> index 919b912..7b86605 100644
> --- a/arch/x86/mm/mmap.c
> +++ b/arch/x86/mm/mmap.c
> @@ -122,3 +122,12 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
>                 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
>         }
>  }
> +unsigned long randomize_et_dyn(unsigned long base)
> +{
> +       unsigned long ret;
> +       if ((current->personality & ADDR_NO_RANDOMIZE) ||
> +               !(current->flags & PF_RANDOMIZE))
> +               return base;
> +       ret = base + mmap_rnd();
> +       return (ret > base) ? ret : base;
> +}
> diff --git a/fs/Kconfig.binfmt b/fs/Kconfig.binfmt
> index c055d56..1186190 100644
> --- a/fs/Kconfig.binfmt
> +++ b/fs/Kconfig.binfmt
> @@ -27,8 +27,6 @@ config COMPAT_BINFMT_ELF
>         bool
>         depends on COMPAT && BINFMT_ELF
>
> -config ARCH_BINFMT_ELF_RANDOMIZE_PIE
> -       bool
>
>  config ARCH_BINFMT_ELF_STATE
>         bool
> diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
> index 02b1691..72f7ff5 100644
> --- a/fs/binfmt_elf.c
> +++ b/fs/binfmt_elf.c
> @@ -908,21 +908,7 @@ static int load_elf_binary(struct linux_binprm *bprm)
>                          * 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.  */
> -#ifdef CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE
> -                       /* Memory randomization might have been switched off
> -                        * in runtime via sysctl or explicit setting of
> -                        * personality flags.
> -                        * If that is the case, retain the original non-zero
> -                        * load_bias value in order to establish proper
> -                        * non-randomized mappings.
> -                        */
> -                       if (current->flags & PF_RANDOMIZE)
> -                               load_bias = 0;
> -                       else
> -                               load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE -
> vaddr);
> -#else
>                         load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
> -#endif
>                 }
>
>                 error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt,

I think this is much cleaner now without
ARCH_BINFMT_ELF_RANDOMIZE_PIE. I imagine there could be some follow-up
cleanups to standardize (or at least clearly document) the intended
levels of entropy in the 4 ASLR regions on each architecture, as it
currently varies a bit.

Thanks!

-Kees

-- 
Kees Cook
Chrome OS Security

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

* Re: [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS
@ 2015-02-23 19:54     ` Hector Marco Gisbert
  0 siblings, 0 replies; 56+ messages in thread
From: Hector Marco Gisbert @ 2015-02-23 19:54 UTC (permalink / raw)
  To: Kees Cook
  Cc: Andrew Morton, LKML, ismael Ripoll, x86, linux-arm-kernel,
	Linux MIPS Mailing List, linuxppc-dev

[PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS

The issue appears on PIE linked executables when all memory areas of a
process are randomized. In this case, the attack "offset2lib" de-randomizes
all library areas on 64 bit Linux systems in less than one second.


Further details of the PoC attack at:
http://cybersecurity.upv.es/attacks/offset2lib/offset2lib.html


This patch loads the PIE linked executable in a different area than the
libraries. The successful fix can be tested with a simple pie compiled
application:


$ ./show_mmaps_pie
54859ccd6000-54859ccd7000 r-xp  ...  /tmp/show_mmaps_pie
54859ced6000-54859ced7000 r--p  ...  /tmp/show_mmaps_pie
54859ced7000-54859ced8000 rw-p  ...  /tmp/show_mmaps_pie
7f75be764000-7f75be91f000 r-xp  ...  /lib/x86_64-linux-gnu/libc.so.6
7f75be91f000-7f75beb1f000 ---p  ...  /lib/x86_64-linux-gnu/libc.so.6
7f75beb1f000-7f75beb23000 r--p  ...  /lib/x86_64-linux-gnu/libc.so.6
7f75beb23000-7f75beb25000 rw-p  ...  /lib/x86_64-linux-gnu/libc.so.6
7f75beb25000-7f75beb2a000 rw-p  ...
7f75beb2a000-7f75beb4d000 r-xp  ...  /lib64/ld-linux-x86-64.so.2
7f75bed45000-7f75bed46000 rw-p  ...
7f75bed46000-7f75bed47000 r-xp  ...
7f75bed47000-7f75bed4c000 rw-p  ...
7f75bed4c000-7f75bed4d000 r--p  ...  /lib64/ld-linux-x86-64.so.2
7f75bed4d000-7f75bed4e000 rw-p  ...  /lib64/ld-linux-x86-64.so.2
7f75bed4e000-7f75bed4f000 rw-p  ...
7fffb3741000-7fffb3762000 rw-p  ...  [stack]
7fffb377b000-7fffb377d000 r--p  ...  [vvar]
7fffb377d000-7fffb377f000 r-xp  ...  [vdso]


Once corrected, the PIE linked application is loaded in a different area.

We updated the "Fixing Offset2lib weakness" page:
http://cybersecurity.upv.es/solutions/aslrv2/aslrv2.html


Signed-off-by: Hector Marco-Gisbert <hecmargi@upv.es>
Signed-off-by: Ismael Ripoll <iripoll@upv.es>

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 97d07ed..ee7ea7e 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1,7 +1,6 @@
  config ARM
  	bool
  	default y
-	select ARCH_BINFMT_ELF_RANDOMIZE_PIE
  	select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
  	select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
  	select ARCH_HAVE_CUSTOM_GPIO_H
diff --git a/arch/arm/include/asm/elf.h b/arch/arm/include/asm/elf.h
index afb9caf..6755cd8 100644
--- a/arch/arm/include/asm/elf.h
+++ b/arch/arm/include/asm/elf.h
@@ -115,7 +115,8 @@ int dump_task_regs(struct task_struct *t,  
elf_gregset_t *elfregs);
     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	(2 * TASK_SIZE / 3)
+extern unsigned long randomize_et_dyn(unsigned long base);
+#define ELF_ET_DYN_BASE	(randomize_et_dyn(2 * TASK_SIZE / 3))

  /* 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
diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c
index 5e85ed3..9177100 100644
--- a/arch/arm/mm/mmap.c
+++ b/arch/arm/mm/mmap.c
@@ -30,6 +30,17 @@ static int mmap_is_legacy(void)
  	return sysctl_legacy_va_layout;
  }

+static unsigned long mmap_rnd(void)
+{
+	unsigned long rnd = 0;
+
+	/* 8 bits of randomness in 20 address space bits */
+	if (current->flags & PF_RANDOMIZE)
+		rnd = (long)get_random_int() % (1 << 8);
+
+	return rnd << PAGE_SHIFT;
+}
+
  static unsigned long mmap_base(unsigned long rnd)
  {
  	unsigned long gap = rlimit(RLIMIT_STACK);
@@ -230,3 +241,13 @@ int devmem_is_allowed(unsigned long pfn)
  }

  #endif
+
+unsigned long randomize_et_dyn(unsigned long base)
+{
+	unsigned long ret;
+	if ((current->personality & ADDR_NO_RANDOMIZE) ||
+		!(current->flags & PF_RANDOMIZE))
+		return base;
+	ret = base + mmap_rnd();
+	return (ret > base) ? ret : base;
+}
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index b1f9a20..5580d90 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -1,6 +1,5 @@
  config ARM64
  	def_bool y
-	select ARCH_BINFMT_ELF_RANDOMIZE_PIE
  	select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
  	select ARCH_HAS_GCOV_PROFILE_ALL
  	select ARCH_HAS_SG_CHAIN
diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
index 1f65be3..01d3aab 100644
--- a/arch/arm64/include/asm/elf.h
+++ b/arch/arm64/include/asm/elf.h
@@ -126,7 +126,7 @@ typedef struct user_fpsimd_state elf_fpregset_t;
   * that it will "exec", and that there is sufficient room for the brk.
   */
  extern unsigned long randomize_et_dyn(unsigned long base);
-#define ELF_ET_DYN_BASE	(2 * TASK_SIZE_64 / 3)
+#define ELF_ET_DYN_BASE	(randomize_et_dyn(2 * TASK_SIZE_64 / 3))

  /*
   * When the program starts, a1 contains a pointer to a function to be
@@ -169,7 +169,7 @@ extern unsigned long arch_randomize_brk(struct  
mm_struct *mm);
  #define COMPAT_ELF_PLATFORM		("v8l")
  #endif

-#define COMPAT_ELF_ET_DYN_BASE		(2 * TASK_SIZE_32 / 3)
+#define COMPAT_ELF_ET_DYN_BASE		(randomize_et_dyn(2 * TASK_SIZE_32 / 3))

  /* AArch32 registers. */
  #define COMPAT_ELF_NGREG		18
diff --git a/arch/arm64/mm/mmap.c b/arch/arm64/mm/mmap.c
index 54922d1..980110c50 100644
--- a/arch/arm64/mm/mmap.c
+++ b/arch/arm64/mm/mmap.c
@@ -89,6 +89,16 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
  }
  EXPORT_SYMBOL_GPL(arch_pick_mmap_layout);

+unsigned long randomize_et_dyn(unsigned long base)
+{
+	unsigned long ret;
+	if ((current->personality & ADDR_NO_RANDOMIZE) ||
+		!(current->flags & PF_RANDOMIZE))
+		return base;
+	ret = base + mmap_rnd();
+	return (ret > base) ? ret : base;
+}
+

  /*
   * You really shouldn't be using read() or write() on /dev/mem.   
This might go
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 3289969..31cc248 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -23,7 +23,6 @@ config MIPS
  	select HAVE_KRETPROBES
  	select HAVE_DEBUG_KMEMLEAK
  	select HAVE_SYSCALL_TRACEPOINTS
-	select ARCH_BINFMT_ELF_RANDOMIZE_PIE
  	select HAVE_ARCH_TRANSPARENT_HUGEPAGE if CPU_SUPPORTS_HUGEPAGES && 64BIT
  	select RTC_LIB if !MACH_LOONGSON
  	select GENERIC_ATOMIC64 if !64BIT
diff --git a/arch/mips/include/asm/elf.h b/arch/mips/include/asm/elf.h
index eb4d95d..fcac4c99 100644
--- a/arch/mips/include/asm/elf.h
+++ b/arch/mips/include/asm/elf.h
@@ -402,7 +402,8 @@ extern const char *__elf_platform;
     that it will "exec", and that there is sufficient room for the brk.	*/

  #ifndef ELF_ET_DYN_BASE
-#define ELF_ET_DYN_BASE		(TASK_SIZE / 3 * 2)
+extern unsigned long randomize_et_dyn(unsigned long base);
+#define ELF_ET_DYN_BASE		(randomize_et_dyn(TASK_SIZE / 3 * 2))
  #endif

  #define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
diff --git a/arch/mips/mm/mmap.c b/arch/mips/mm/mmap.c
index f1baadd..20ad644 100644
--- a/arch/mips/mm/mmap.c
+++ b/arch/mips/mm/mmap.c
@@ -196,3 +196,13 @@ int __virt_addr_valid(const volatile void *kaddr)
  	return pfn_valid(PFN_DOWN(virt_to_phys(kaddr)));
  }
  EXPORT_SYMBOL_GPL(__virt_addr_valid);
+
+unsigned long randomize_et_dyn(unsigned long base)
+{
+	unsigned long ret;
+	if ((current->personality & ADDR_NO_RANDOMIZE) ||
+		!(current->flags & PF_RANDOMIZE))
+		return base;
+	ret = base + brk_rnd();
+	return (ret > base) ? ret : base;
+}
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index a2a168e..fa4c877 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -88,7 +88,6 @@ config PPC
  	select ARCH_MIGHT_HAVE_PC_PARPORT
  	select ARCH_MIGHT_HAVE_PC_SERIO
  	select BINFMT_ELF
-	select ARCH_BINFMT_ELF_RANDOMIZE_PIE
  	select OF
  	select OF_EARLY_FLATTREE
  	select OF_RESERVED_MEM
diff --git a/arch/powerpc/include/asm/elf.h b/arch/powerpc/include/asm/elf.h
index 57d289a..4080425 100644
--- a/arch/powerpc/include/asm/elf.h
+++ b/arch/powerpc/include/asm/elf.h
@@ -28,7 +28,8 @@
     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
+extern unsigned long randomize_et_dyn(unsigned long base);
+#define ELF_ET_DYN_BASE	(randomize_et_dyn(0x20000000))

  #define ELF_CORE_EFLAGS (is_elf2_task() ? 2 : 0)

diff --git a/arch/powerpc/mm/mmap.c b/arch/powerpc/mm/mmap.c
index cb8bdbe..3e642e7 100644
--- a/arch/powerpc/mm/mmap.c
+++ b/arch/powerpc/mm/mmap.c
@@ -97,3 +97,13 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
  		mm->get_unmapped_area = arch_get_unmapped_area_topdown;
  	}
  }
+
+unsigned long randomize_et_dyn(unsigned long base)
+{
+	unsigned long ret;
+	if ((current->personality & ADDR_NO_RANDOMIZE) ||
+		!(current->flags & PF_RANDOMIZE))
+		return base;
+	ret = base + mmap_rnd();
+	return (ret > base) ? ret : base;
+}
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index ba397bd..dcfe16c 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -85,7 +85,6 @@ config X86
  	select HAVE_CMPXCHG_DOUBLE
  	select HAVE_ARCH_KMEMCHECK
  	select HAVE_USER_RETURN_NOTIFIER
-	select ARCH_BINFMT_ELF_RANDOMIZE_PIE
  	select HAVE_ARCH_JUMP_LABEL
  	select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
  	select SPARSE_IRQ
diff --git a/arch/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h
index ca3347a..92c6ac4 100644
--- a/arch/x86/include/asm/elf.h
+++ b/arch/x86/include/asm/elf.h
@@ -249,7 +249,8 @@ extern int force_personality32;
     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)
+extern unsigned long randomize_et_dyn(unsigned long base);
+#define ELF_ET_DYN_BASE		(randomize_et_dyn(TASK_SIZE / 3 * 2))

  /* 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/arch/x86/mm/mmap.c b/arch/x86/mm/mmap.c
index 919b912..7b86605 100644
--- a/arch/x86/mm/mmap.c
+++ b/arch/x86/mm/mmap.c
@@ -122,3 +122,12 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
  		mm->get_unmapped_area = arch_get_unmapped_area_topdown;
  	}
  }
+unsigned long randomize_et_dyn(unsigned long base)
+{
+	unsigned long ret;
+	if ((current->personality & ADDR_NO_RANDOMIZE) ||
+		!(current->flags & PF_RANDOMIZE))
+		return base;
+	ret = base + mmap_rnd();
+	return (ret > base) ? ret : base;
+}
diff --git a/fs/Kconfig.binfmt b/fs/Kconfig.binfmt
index c055d56..1186190 100644
--- a/fs/Kconfig.binfmt
+++ b/fs/Kconfig.binfmt
@@ -27,8 +27,6 @@ config COMPAT_BINFMT_ELF
  	bool
  	depends on COMPAT && BINFMT_ELF

-config ARCH_BINFMT_ELF_RANDOMIZE_PIE
-	bool

  config ARCH_BINFMT_ELF_STATE
  	bool
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 02b1691..72f7ff5 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -908,21 +908,7 @@ static int load_elf_binary(struct linux_binprm *bprm)
  			 * 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.  */
-#ifdef CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE
-			/* Memory randomization might have been switched off
-			 * in runtime via sysctl or explicit setting of
-			 * personality flags.
-			 * If that is the case, retain the original non-zero
-			 * load_bias value in order to establish proper
-			 * non-randomized mappings.
-			 */
-			if (current->flags & PF_RANDOMIZE)
-				load_bias = 0;
-			else
-				load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
-#else
  			load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
-#endif
  		}

  		error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt,



Kees Cook <keescook@chromium.org> escribió:

> (I've added some additional CCs to make sure the arch maintainers
> notice this patch.)
>
> This patch seems white-space damaged to me. I had to do a lot of
> manual editing to get it to apply. Please use "git format-patch", if
> you're not already. What version of the kernel was this based on?
>
> On Mon, Feb 23, 2015 at 10:37 AM, Hector Marco <hecmargi@upv.es> wrote:
>> [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS
>>
>> The issue appears on PIE linked executables when all memory areas of a
>> process are randomized. In this case, the attack "offset2lib" de-randomizes
>> all library areas on 64 bit Linux systems in less than one second.
>>
>>
>> Further details of the PoC attack at:
>> http://cybersecurity.upv.es/attacks/offset2lib/offset2lib.html
>>
>>
>> This patch loads the PIE linked executable in a different area than the
>> libraries. The successful fix can be tested with a simple pie compiled
>> application:
>>
>>
>> $ ./show_mmaps_pie
>> 54859ccd6000-54859ccd7000 r-xp  ...  /tmp/show_mmaps_pie
>> 54859ced6000-54859ced7000 r--p  ...  /tmp/show_mmaps_pie
>> 54859ced7000-54859ced8000 rw-p  ...  /tmp/show_mmaps_pie
>> 7f75be764000-7f75be91f000 r-xp  ...  /lib/x86_64-linux-gnu/libc.so.6
>> 7f75be91f000-7f75beb1f000 ---p  ...  /lib/x86_64-linux-gnu/libc.so.6
>> 7f75beb1f000-7f75beb23000 r--p  ...  /lib/x86_64-linux-gnu/libc.so.6
>> 7f75beb23000-7f75beb25000 rw-p  ...  /lib/x86_64-linux-gnu/libc.so.6
>> 7f75beb25000-7f75beb2a000 rw-p  ...
>> 7f75beb2a000-7f75beb4d000 r-xp  ...  /lib64/ld-linux-x86-64.so.2
>> 7f75bed45000-7f75bed46000 rw-p  ...
>> 7f75bed46000-7f75bed47000 r-xp  ...
>> 7f75bed47000-7f75bed4c000 rw-p  ...
>> 7f75bed4c000-7f75bed4d000 r--p  ...  /lib64/ld-linux-x86-64.so.2
>> 7f75bed4d000-7f75bed4e000 rw-p  ...  /lib64/ld-linux-x86-64.so.2
>> 7f75bed4e000-7f75bed4f000 rw-p  ...
>> 7fffb3741000-7fffb3762000 rw-p  ...  [stack]
>> 7fffb377b000-7fffb377d000 r--p  ...  [vvar]
>> 7fffb377d000-7fffb377f000 r-xp  ...  [vdso]
>>
>>
>> Once corrected, the PIE linked application is loaded in a different area.
>
> Thanks for working on this!
>
>>
>> We updated the "Fixing Offset2lib weakness" page:
>> http://cybersecurity.upv.es/solutions/aslrv2/aslrv2.html
>>
>>
>> Signed-off-by: Hector Marco-Gisbert <hecmargi@upv.es>
>> Signed-off-by: Ismael Ripoll <iripoll@upv.es>
>
> Acked-by: Kees Cook <keescook@chromium.org>
>
>>
>>
>> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
>> index 97d07ed..ee7ea7e 100644
>> --- a/arch/arm/Kconfig
>> +++ b/arch/arm/Kconfig
>> @@ -1,7 +1,6 @@
>>  config ARM
>>         bool
>>         default y
>> -       select ARCH_BINFMT_ELF_RANDOMIZE_PIE
>>         select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
>>         select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
>>         select ARCH_HAVE_CUSTOM_GPIO_H
>> diff --git a/arch/arm/include/asm/elf.h b/arch/arm/include/asm/elf.h
>> index afb9caf..6755cd8 100644
>> --- a/arch/arm/include/asm/elf.h
>> +++ b/arch/arm/include/asm/elf.h
>> @@ -115,7 +115,8 @@ int dump_task_regs(struct task_struct *t, elf_gregset_t
>> *elfregs);
>>     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        (2 * TASK_SIZE / 3)
>> +extern unsigned long randomize_et_dyn(unsigned long base);
>> +#define ELF_ET_DYN_BASE        (randomize_et_dyn(2 * TASK_SIZE / 3))
>>
>>  /* 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
>> diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c
>> index 5e85ed3..9177100 100644
>> --- a/arch/arm/mm/mmap.c
>> +++ b/arch/arm/mm/mmap.c
>> @@ -30,6 +30,17 @@ static int mmap_is_legacy(void)
>>         return sysctl_legacy_va_layout;
>>  }
>>
>> +static unsigned long mmap_rnd(void)
>> +{
>> +       unsigned long rnd = 0;
>> +
>> +       /* 8 bits of randomness in 20 address space bits */
>> +       if (current->flags & PF_RANDOMIZE)
>> +               rnd = (long)get_random_int() % (1 << 8);
>> +
>> +       return rnd << PAGE_SHIFT;
>> +}
>> +
>>  static unsigned long mmap_base(unsigned long rnd)
>>  {
>>         unsigned long gap = rlimit(RLIMIT_STACK);
>> @@ -230,3 +241,13 @@ int devmem_is_allowed(unsigned long pfn)
>>  }
>>
>>  #endif
>> +
>> +unsigned long randomize_et_dyn(unsigned long base)
>> +{
>> +       unsigned long ret;
>> +       if ((current->personality & ADDR_NO_RANDOMIZE) ||
>> +               !(current->flags & PF_RANDOMIZE))
>> +               return base;
>> +       ret = base + mmap_rnd();
>> +       return (ret > base) ? ret : base;
>> +}
>> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
>> index b1f9a20..5580d90 100644
>> --- a/arch/arm64/Kconfig
>> +++ b/arch/arm64/Kconfig
>> @@ -1,6 +1,5 @@
>>  config ARM64
>>         def_bool y
>> -       select ARCH_BINFMT_ELF_RANDOMIZE_PIE
>>         select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
>>         select ARCH_HAS_GCOV_PROFILE_ALL
>>         select ARCH_HAS_SG_CHAIN
>> diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
>> index 1f65be3..01d3aab 100644
>> --- a/arch/arm64/include/asm/elf.h
>> +++ b/arch/arm64/include/asm/elf.h
>> @@ -126,7 +126,7 @@ typedef struct user_fpsimd_state elf_fpregset_t;
>>   * that it will "exec", and that there is sufficient room for the brk.
>>   */
>>  extern unsigned long randomize_et_dyn(unsigned long base);
>> -#define ELF_ET_DYN_BASE        (2 * TASK_SIZE_64 / 3)
>> +#define ELF_ET_DYN_BASE        (randomize_et_dyn(2 * TASK_SIZE_64 / 3))
>>
>>  /*
>>   * When the program starts, a1 contains a pointer to a function to be
>> @@ -169,7 +169,7 @@ extern unsigned long arch_randomize_brk(struct mm_struct
>> *mm);
>>  #define COMPAT_ELF_PLATFORM            ("v8l")
>>  #endif
>>
>> -#define COMPAT_ELF_ET_DYN_BASE         (2 * TASK_SIZE_32 / 3)
>> +#define COMPAT_ELF_ET_DYN_BASE         (randomize_et_dyn(2 * TASK_SIZE_32 /
>> 3))
>>
>>  /* AArch32 registers. */
>>  #define COMPAT_ELF_NGREG               18
>> diff --git a/arch/arm64/mm/mmap.c b/arch/arm64/mm/mmap.c
>> index 54922d1..980110c50 100644
>> --- a/arch/arm64/mm/mmap.c
>> +++ b/arch/arm64/mm/mmap.c
>> @@ -89,6 +89,16 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
>>  }
>>  EXPORT_SYMBOL_GPL(arch_pick_mmap_layout);
>>
>> +unsigned long randomize_et_dyn(unsigned long base)
>> +{
>> +       unsigned long ret;
>> +       if ((current->personality & ADDR_NO_RANDOMIZE) ||
>> +               !(current->flags & PF_RANDOMIZE))
>> +               return base;
>> +       ret = base + mmap_rnd();
>> +       return (ret > base) ? ret : base;
>> +}
>> +
>>
>>  /*
>>   * You really shouldn't be using read() or write() on /dev/mem.  This might
>> go
>> diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
>> index 3289969..31cc248 100644
>> --- a/arch/mips/Kconfig
>> +++ b/arch/mips/Kconfig
>> @@ -23,7 +23,6 @@ config MIPS
>>         select HAVE_KRETPROBES
>>         select HAVE_DEBUG_KMEMLEAK
>>         select HAVE_SYSCALL_TRACEPOINTS
>> -       select ARCH_BINFMT_ELF_RANDOMIZE_PIE
>>         select HAVE_ARCH_TRANSPARENT_HUGEPAGE if CPU_SUPPORTS_HUGEPAGES &&
>> 64BIT
>>         select RTC_LIB if !MACH_LOONGSON
>>         select GENERIC_ATOMIC64 if !64BIT
>> diff --git a/arch/mips/include/asm/elf.h b/arch/mips/include/asm/elf.h
>> index eb4d95d..fcac4c99 100644
>> --- a/arch/mips/include/asm/elf.h
>> +++ b/arch/mips/include/asm/elf.h
>> @@ -402,7 +402,8 @@ extern const char *__elf_platform;
>>     that it will "exec", and that there is sufficient room for the brk. */
>>
>>  #ifndef ELF_ET_DYN_BASE
>> -#define ELF_ET_DYN_BASE                (TASK_SIZE / 3 * 2)
>> +extern unsigned long randomize_et_dyn(unsigned long base);
>> +#define ELF_ET_DYN_BASE                (randomize_et_dyn(TASK_SIZE / 3 *
>> 2))
>>  #endif
>>
>>  #define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
>> diff --git a/arch/mips/mm/mmap.c b/arch/mips/mm/mmap.c
>> index f1baadd..20ad644 100644
>> --- a/arch/mips/mm/mmap.c
>> +++ b/arch/mips/mm/mmap.c
>> @@ -196,3 +196,13 @@ int __virt_addr_valid(const volatile void *kaddr)
>>         return pfn_valid(PFN_DOWN(virt_to_phys(kaddr)));
>>  }
>>  EXPORT_SYMBOL_GPL(__virt_addr_valid);
>> +
>> +unsigned long randomize_et_dyn(unsigned long base)
>> +{
>> +       unsigned long ret;
>> +       if ((current->personality & ADDR_NO_RANDOMIZE) ||
>> +               !(current->flags & PF_RANDOMIZE))
>> +               return base;
>> +       ret = base + brk_rnd();
>> +       return (ret > base) ? ret : base;
>> +}
>> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
>> index a2a168e..fa4c877 100644
>> --- a/arch/powerpc/Kconfig
>> +++ b/arch/powerpc/Kconfig
>> @@ -88,7 +88,6 @@ config PPC
>>         select ARCH_MIGHT_HAVE_PC_PARPORT
>>         select ARCH_MIGHT_HAVE_PC_SERIO
>>         select BINFMT_ELF
>> -       select ARCH_BINFMT_ELF_RANDOMIZE_PIE
>>         select OF
>>         select OF_EARLY_FLATTREE
>>         select OF_RESERVED_MEM
>> diff --git a/arch/powerpc/include/asm/elf.h b/arch/powerpc/include/asm/elf.h
>> index 57d289a..4080425 100644
>> --- a/arch/powerpc/include/asm/elf.h
>> +++ b/arch/powerpc/include/asm/elf.h
>> @@ -28,7 +28,8 @@
>>     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
>> +extern unsigned long randomize_et_dyn(unsigned long base);
>> +#define ELF_ET_DYN_BASE        (randomize_et_dyn(0x20000000))
>>
>>  #define ELF_CORE_EFLAGS (is_elf2_task() ? 2 : 0)
>>
>> diff --git a/arch/powerpc/mm/mmap.c b/arch/powerpc/mm/mmap.c
>> index cb8bdbe..3e642e7 100644
>> --- a/arch/powerpc/mm/mmap.c
>> +++ b/arch/powerpc/mm/mmap.c
>> @@ -97,3 +97,13 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
>>                 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
>>         }
>>  }
>> +
>> +unsigned long randomize_et_dyn(unsigned long base)
>> +{
>> +       unsigned long ret;
>> +       if ((current->personality & ADDR_NO_RANDOMIZE) ||
>> +               !(current->flags & PF_RANDOMIZE))
>> +               return base;
>> +       ret = base + mmap_rnd();
>> +       return (ret > base) ? ret : base;
>> +}
>> diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
>> index ba397bd..dcfe16c 100644
>> --- a/arch/x86/Kconfig
>> +++ b/arch/x86/Kconfig
>> @@ -85,7 +85,6 @@ config X86
>>         select HAVE_CMPXCHG_DOUBLE
>>         select HAVE_ARCH_KMEMCHECK
>>         select HAVE_USER_RETURN_NOTIFIER
>> -       select ARCH_BINFMT_ELF_RANDOMIZE_PIE
>>         select HAVE_ARCH_JUMP_LABEL
>>         select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
>>         select SPARSE_IRQ
>> diff --git a/arch/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h
>> index ca3347a..92c6ac4 100644
>> --- a/arch/x86/include/asm/elf.h
>> +++ b/arch/x86/include/asm/elf.h
>> @@ -249,7 +249,8 @@ extern int force_personality32;
>>     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)
>> +extern unsigned long randomize_et_dyn(unsigned long base);
>> +#define ELF_ET_DYN_BASE                (randomize_et_dyn(TASK_SIZE / 3 *
>> 2))
>>
>>  /* 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/arch/x86/mm/mmap.c b/arch/x86/mm/mmap.c
>> index 919b912..7b86605 100644
>> --- a/arch/x86/mm/mmap.c
>> +++ b/arch/x86/mm/mmap.c
>> @@ -122,3 +122,12 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
>>                 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
>>         }
>>  }
>> +unsigned long randomize_et_dyn(unsigned long base)
>> +{
>> +       unsigned long ret;
>> +       if ((current->personality & ADDR_NO_RANDOMIZE) ||
>> +               !(current->flags & PF_RANDOMIZE))
>> +               return base;
>> +       ret = base + mmap_rnd();
>> +       return (ret > base) ? ret : base;
>> +}
>> diff --git a/fs/Kconfig.binfmt b/fs/Kconfig.binfmt
>> index c055d56..1186190 100644
>> --- a/fs/Kconfig.binfmt
>> +++ b/fs/Kconfig.binfmt
>> @@ -27,8 +27,6 @@ config COMPAT_BINFMT_ELF
>>         bool
>>         depends on COMPAT && BINFMT_ELF
>>
>> -config ARCH_BINFMT_ELF_RANDOMIZE_PIE
>> -       bool
>>
>>  config ARCH_BINFMT_ELF_STATE
>>         bool
>> diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
>> index 02b1691..72f7ff5 100644
>> --- a/fs/binfmt_elf.c
>> +++ b/fs/binfmt_elf.c
>> @@ -908,21 +908,7 @@ static int load_elf_binary(struct linux_binprm *bprm)
>>                          * 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.  */
>> -#ifdef CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE
>> -                       /* Memory randomization might have been switched off
>> -                        * in runtime via sysctl or explicit setting of
>> -                        * personality flags.
>> -                        * If that is the case, retain the original non-zero
>> -                        * load_bias value in order to establish proper
>> -                        * non-randomized mappings.
>> -                        */
>> -                       if (current->flags & PF_RANDOMIZE)
>> -                               load_bias = 0;
>> -                       else
>> -                               load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE -
>> vaddr);
>> -#else
>>                         load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
>> -#endif
>>                 }
>>
>>                 error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt,
>
> I think this is much cleaner now without
> ARCH_BINFMT_ELF_RANDOMIZE_PIE. I imagine there could be some follow-up
> cleanups to standardize (or at least clearly document) the intended
> levels of entropy in the 4 ASLR regions on each architecture, as it
> currently varies a bit.
>
> Thanks!
>
> -Kees
>
> --
> Kees Cook
> Chrome OS Security
>




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

* Re: [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS
@ 2015-02-23 19:54     ` Hector Marco Gisbert
  0 siblings, 0 replies; 56+ messages in thread
From: Hector Marco Gisbert @ 2015-02-23 19:54 UTC (permalink / raw)
  To: Kees Cook
  Cc: Andrew Morton, LKML, ismael Ripoll, x86, linux-arm-kernel,
	Linux MIPS Mailing List, linuxppc-dev

[PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS

The issue appears on PIE linked executables when all memory areas of a
process are randomized. In this case, the attack "offset2lib" de-randomizes
all library areas on 64 bit Linux systems in less than one second.


Further details of the PoC attack at:
http://cybersecurity.upv.es/attacks/offset2lib/offset2lib.html


This patch loads the PIE linked executable in a different area than the
libraries. The successful fix can be tested with a simple pie compiled
application:


$ ./show_mmaps_pie
54859ccd6000-54859ccd7000 r-xp  ...  /tmp/show_mmaps_pie
54859ced6000-54859ced7000 r--p  ...  /tmp/show_mmaps_pie
54859ced7000-54859ced8000 rw-p  ...  /tmp/show_mmaps_pie
7f75be764000-7f75be91f000 r-xp  ...  /lib/x86_64-linux-gnu/libc.so.6
7f75be91f000-7f75beb1f000 ---p  ...  /lib/x86_64-linux-gnu/libc.so.6
7f75beb1f000-7f75beb23000 r--p  ...  /lib/x86_64-linux-gnu/libc.so.6
7f75beb23000-7f75beb25000 rw-p  ...  /lib/x86_64-linux-gnu/libc.so.6
7f75beb25000-7f75beb2a000 rw-p  ...
7f75beb2a000-7f75beb4d000 r-xp  ...  /lib64/ld-linux-x86-64.so.2
7f75bed45000-7f75bed46000 rw-p  ...
7f75bed46000-7f75bed47000 r-xp  ...
7f75bed47000-7f75bed4c000 rw-p  ...
7f75bed4c000-7f75bed4d000 r--p  ...  /lib64/ld-linux-x86-64.so.2
7f75bed4d000-7f75bed4e000 rw-p  ...  /lib64/ld-linux-x86-64.so.2
7f75bed4e000-7f75bed4f000 rw-p  ...
7fffb3741000-7fffb3762000 rw-p  ...  [stack]
7fffb377b000-7fffb377d000 r--p  ...  [vvar]
7fffb377d000-7fffb377f000 r-xp  ...  [vdso]


Once corrected, the PIE linked application is loaded in a different area.

We updated the "Fixing Offset2lib weakness" page:
http://cybersecurity.upv.es/solutions/aslrv2/aslrv2.html


Signed-off-by: Hector Marco-Gisbert <hecmargi@upv.es>
Signed-off-by: Ismael Ripoll <iripoll@upv.es>

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 97d07ed..ee7ea7e 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1,7 +1,6 @@
  config ARM
  	bool
  	default y
-	select ARCH_BINFMT_ELF_RANDOMIZE_PIE
  	select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
  	select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
  	select ARCH_HAVE_CUSTOM_GPIO_H
diff --git a/arch/arm/include/asm/elf.h b/arch/arm/include/asm/elf.h
index afb9caf..6755cd8 100644
--- a/arch/arm/include/asm/elf.h
+++ b/arch/arm/include/asm/elf.h
@@ -115,7 +115,8 @@ int dump_task_regs(struct task_struct *t,  
elf_gregset_t *elfregs);
     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	(2 * TASK_SIZE / 3)
+extern unsigned long randomize_et_dyn(unsigned long base);
+#define ELF_ET_DYN_BASE	(randomize_et_dyn(2 * TASK_SIZE / 3))

  /* 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
diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c
index 5e85ed3..9177100 100644
--- a/arch/arm/mm/mmap.c
+++ b/arch/arm/mm/mmap.c
@@ -30,6 +30,17 @@ static int mmap_is_legacy(void)
  	return sysctl_legacy_va_layout;
  }

+static unsigned long mmap_rnd(void)
+{
+	unsigned long rnd = 0;
+
+	/* 8 bits of randomness in 20 address space bits */
+	if (current->flags & PF_RANDOMIZE)
+		rnd = (long)get_random_int() % (1 << 8);
+
+	return rnd << PAGE_SHIFT;
+}
+
  static unsigned long mmap_base(unsigned long rnd)
  {
  	unsigned long gap = rlimit(RLIMIT_STACK);
@@ -230,3 +241,13 @@ int devmem_is_allowed(unsigned long pfn)
  }

  #endif
+
+unsigned long randomize_et_dyn(unsigned long base)
+{
+	unsigned long ret;
+	if ((current->personality & ADDR_NO_RANDOMIZE) ||
+		!(current->flags & PF_RANDOMIZE))
+		return base;
+	ret = base + mmap_rnd();
+	return (ret > base) ? ret : base;
+}
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index b1f9a20..5580d90 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -1,6 +1,5 @@
  config ARM64
  	def_bool y
-	select ARCH_BINFMT_ELF_RANDOMIZE_PIE
  	select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
  	select ARCH_HAS_GCOV_PROFILE_ALL
  	select ARCH_HAS_SG_CHAIN
diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
index 1f65be3..01d3aab 100644
--- a/arch/arm64/include/asm/elf.h
+++ b/arch/arm64/include/asm/elf.h
@@ -126,7 +126,7 @@ typedef struct user_fpsimd_state elf_fpregset_t;
   * that it will "exec", and that there is sufficient room for the brk.
   */
  extern unsigned long randomize_et_dyn(unsigned long base);
-#define ELF_ET_DYN_BASE	(2 * TASK_SIZE_64 / 3)
+#define ELF_ET_DYN_BASE	(randomize_et_dyn(2 * TASK_SIZE_64 / 3))

  /*
   * When the program starts, a1 contains a pointer to a function to be
@@ -169,7 +169,7 @@ extern unsigned long arch_randomize_brk(struct  
mm_struct *mm);
  #define COMPAT_ELF_PLATFORM		("v8l")
  #endif

-#define COMPAT_ELF_ET_DYN_BASE		(2 * TASK_SIZE_32 / 3)
+#define COMPAT_ELF_ET_DYN_BASE		(randomize_et_dyn(2 * TASK_SIZE_32 / 3))

  /* AArch32 registers. */
  #define COMPAT_ELF_NGREG		18
diff --git a/arch/arm64/mm/mmap.c b/arch/arm64/mm/mmap.c
index 54922d1..980110c50 100644
--- a/arch/arm64/mm/mmap.c
+++ b/arch/arm64/mm/mmap.c
@@ -89,6 +89,16 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
  }
  EXPORT_SYMBOL_GPL(arch_pick_mmap_layout);

+unsigned long randomize_et_dyn(unsigned long base)
+{
+	unsigned long ret;
+	if ((current->personality & ADDR_NO_RANDOMIZE) ||
+		!(current->flags & PF_RANDOMIZE))
+		return base;
+	ret = base + mmap_rnd();
+	return (ret > base) ? ret : base;
+}
+

  /*
   * You really shouldn't be using read() or write() on /dev/mem.   
This might go
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 3289969..31cc248 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -23,7 +23,6 @@ config MIPS
  	select HAVE_KRETPROBES
  	select HAVE_DEBUG_KMEMLEAK
  	select HAVE_SYSCALL_TRACEPOINTS
-	select ARCH_BINFMT_ELF_RANDOMIZE_PIE
  	select HAVE_ARCH_TRANSPARENT_HUGEPAGE if CPU_SUPPORTS_HUGEPAGES && 64BIT
  	select RTC_LIB if !MACH_LOONGSON
  	select GENERIC_ATOMIC64 if !64BIT
diff --git a/arch/mips/include/asm/elf.h b/arch/mips/include/asm/elf.h
index eb4d95d..fcac4c99 100644
--- a/arch/mips/include/asm/elf.h
+++ b/arch/mips/include/asm/elf.h
@@ -402,7 +402,8 @@ extern const char *__elf_platform;
     that it will "exec", and that there is sufficient room for the brk.	*/

  #ifndef ELF_ET_DYN_BASE
-#define ELF_ET_DYN_BASE		(TASK_SIZE / 3 * 2)
+extern unsigned long randomize_et_dyn(unsigned long base);
+#define ELF_ET_DYN_BASE		(randomize_et_dyn(TASK_SIZE / 3 * 2))
  #endif

  #define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
diff --git a/arch/mips/mm/mmap.c b/arch/mips/mm/mmap.c
index f1baadd..20ad644 100644
--- a/arch/mips/mm/mmap.c
+++ b/arch/mips/mm/mmap.c
@@ -196,3 +196,13 @@ int __virt_addr_valid(const volatile void *kaddr)
  	return pfn_valid(PFN_DOWN(virt_to_phys(kaddr)));
  }
  EXPORT_SYMBOL_GPL(__virt_addr_valid);
+
+unsigned long randomize_et_dyn(unsigned long base)
+{
+	unsigned long ret;
+	if ((current->personality & ADDR_NO_RANDOMIZE) ||
+		!(current->flags & PF_RANDOMIZE))
+		return base;
+	ret = base + brk_rnd();
+	return (ret > base) ? ret : base;
+}
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index a2a168e..fa4c877 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -88,7 +88,6 @@ config PPC
  	select ARCH_MIGHT_HAVE_PC_PARPORT
  	select ARCH_MIGHT_HAVE_PC_SERIO
  	select BINFMT_ELF
-	select ARCH_BINFMT_ELF_RANDOMIZE_PIE
  	select OF
  	select OF_EARLY_FLATTREE
  	select OF_RESERVED_MEM
diff --git a/arch/powerpc/include/asm/elf.h b/arch/powerpc/include/asm/elf.h
index 57d289a..4080425 100644
--- a/arch/powerpc/include/asm/elf.h
+++ b/arch/powerpc/include/asm/elf.h
@@ -28,7 +28,8 @@
     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
+extern unsigned long randomize_et_dyn(unsigned long base);
+#define ELF_ET_DYN_BASE	(randomize_et_dyn(0x20000000))

  #define ELF_CORE_EFLAGS (is_elf2_task() ? 2 : 0)

diff --git a/arch/powerpc/mm/mmap.c b/arch/powerpc/mm/mmap.c
index cb8bdbe..3e642e7 100644
--- a/arch/powerpc/mm/mmap.c
+++ b/arch/powerpc/mm/mmap.c
@@ -97,3 +97,13 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
  		mm->get_unmapped_area = arch_get_unmapped_area_topdown;
  	}
  }
+
+unsigned long randomize_et_dyn(unsigned long base)
+{
+	unsigned long ret;
+	if ((current->personality & ADDR_NO_RANDOMIZE) ||
+		!(current->flags & PF_RANDOMIZE))
+		return base;
+	ret = base + mmap_rnd();
+	return (ret > base) ? ret : base;
+}
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index ba397bd..dcfe16c 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -85,7 +85,6 @@ config X86
  	select HAVE_CMPXCHG_DOUBLE
  	select HAVE_ARCH_KMEMCHECK
  	select HAVE_USER_RETURN_NOTIFIER
-	select ARCH_BINFMT_ELF_RANDOMIZE_PIE
  	select HAVE_ARCH_JUMP_LABEL
  	select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
  	select SPARSE_IRQ
diff --git a/arch/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h
index ca3347a..92c6ac4 100644
--- a/arch/x86/include/asm/elf.h
+++ b/arch/x86/include/asm/elf.h
@@ -249,7 +249,8 @@ extern int force_personality32;
     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)
+extern unsigned long randomize_et_dyn(unsigned long base);
+#define ELF_ET_DYN_BASE		(randomize_et_dyn(TASK_SIZE / 3 * 2))

  /* 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/arch/x86/mm/mmap.c b/arch/x86/mm/mmap.c
index 919b912..7b86605 100644
--- a/arch/x86/mm/mmap.c
+++ b/arch/x86/mm/mmap.c
@@ -122,3 +122,12 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
  		mm->get_unmapped_area = arch_get_unmapped_area_topdown;
  	}
  }
+unsigned long randomize_et_dyn(unsigned long base)
+{
+	unsigned long ret;
+	if ((current->personality & ADDR_NO_RANDOMIZE) ||
+		!(current->flags & PF_RANDOMIZE))
+		return base;
+	ret = base + mmap_rnd();
+	return (ret > base) ? ret : base;
+}
diff --git a/fs/Kconfig.binfmt b/fs/Kconfig.binfmt
index c055d56..1186190 100644
--- a/fs/Kconfig.binfmt
+++ b/fs/Kconfig.binfmt
@@ -27,8 +27,6 @@ config COMPAT_BINFMT_ELF
  	bool
  	depends on COMPAT && BINFMT_ELF

-config ARCH_BINFMT_ELF_RANDOMIZE_PIE
-	bool

  config ARCH_BINFMT_ELF_STATE
  	bool
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 02b1691..72f7ff5 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -908,21 +908,7 @@ static int load_elf_binary(struct linux_binprm *bprm)
  			 * 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.  */
-#ifdef CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE
-			/* Memory randomization might have been switched off
-			 * in runtime via sysctl or explicit setting of
-			 * personality flags.
-			 * If that is the case, retain the original non-zero
-			 * load_bias value in order to establish proper
-			 * non-randomized mappings.
-			 */
-			if (current->flags & PF_RANDOMIZE)
-				load_bias = 0;
-			else
-				load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
-#else
  			load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
-#endif
  		}

  		error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt,



Kees Cook <keescook@chromium.org> escribió:

> (I've added some additional CCs to make sure the arch maintainers
> notice this patch.)
>
> This patch seems white-space damaged to me. I had to do a lot of
> manual editing to get it to apply. Please use "git format-patch", if
> you're not already. What version of the kernel was this based on?
>
> On Mon, Feb 23, 2015 at 10:37 AM, Hector Marco <hecmargi@upv.es> wrote:
>> [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS
>>
>> The issue appears on PIE linked executables when all memory areas of a
>> process are randomized. In this case, the attack "offset2lib" de-randomizes
>> all library areas on 64 bit Linux systems in less than one second.
>>
>>
>> Further details of the PoC attack at:
>> http://cybersecurity.upv.es/attacks/offset2lib/offset2lib.html
>>
>>
>> This patch loads the PIE linked executable in a different area than the
>> libraries. The successful fix can be tested with a simple pie compiled
>> application:
>>
>>
>> $ ./show_mmaps_pie
>> 54859ccd6000-54859ccd7000 r-xp  ...  /tmp/show_mmaps_pie
>> 54859ced6000-54859ced7000 r--p  ...  /tmp/show_mmaps_pie
>> 54859ced7000-54859ced8000 rw-p  ...  /tmp/show_mmaps_pie
>> 7f75be764000-7f75be91f000 r-xp  ...  /lib/x86_64-linux-gnu/libc.so.6
>> 7f75be91f000-7f75beb1f000 ---p  ...  /lib/x86_64-linux-gnu/libc.so.6
>> 7f75beb1f000-7f75beb23000 r--p  ...  /lib/x86_64-linux-gnu/libc.so.6
>> 7f75beb23000-7f75beb25000 rw-p  ...  /lib/x86_64-linux-gnu/libc.so.6
>> 7f75beb25000-7f75beb2a000 rw-p  ...
>> 7f75beb2a000-7f75beb4d000 r-xp  ...  /lib64/ld-linux-x86-64.so.2
>> 7f75bed45000-7f75bed46000 rw-p  ...
>> 7f75bed46000-7f75bed47000 r-xp  ...
>> 7f75bed47000-7f75bed4c000 rw-p  ...
>> 7f75bed4c000-7f75bed4d000 r--p  ...  /lib64/ld-linux-x86-64.so.2
>> 7f75bed4d000-7f75bed4e000 rw-p  ...  /lib64/ld-linux-x86-64.so.2
>> 7f75bed4e000-7f75bed4f000 rw-p  ...
>> 7fffb3741000-7fffb3762000 rw-p  ...  [stack]
>> 7fffb377b000-7fffb377d000 r--p  ...  [vvar]
>> 7fffb377d000-7fffb377f000 r-xp  ...  [vdso]
>>
>>
>> Once corrected, the PIE linked application is loaded in a different area.
>
> Thanks for working on this!
>
>>
>> We updated the "Fixing Offset2lib weakness" page:
>> http://cybersecurity.upv.es/solutions/aslrv2/aslrv2.html
>>
>>
>> Signed-off-by: Hector Marco-Gisbert <hecmargi@upv.es>
>> Signed-off-by: Ismael Ripoll <iripoll@upv.es>
>
> Acked-by: Kees Cook <keescook@chromium.org>
>
>>
>>
>> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
>> index 97d07ed..ee7ea7e 100644
>> --- a/arch/arm/Kconfig
>> +++ b/arch/arm/Kconfig
>> @@ -1,7 +1,6 @@
>>  config ARM
>>         bool
>>         default y
>> -       select ARCH_BINFMT_ELF_RANDOMIZE_PIE
>>         select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
>>         select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
>>         select ARCH_HAVE_CUSTOM_GPIO_H
>> diff --git a/arch/arm/include/asm/elf.h b/arch/arm/include/asm/elf.h
>> index afb9caf..6755cd8 100644
>> --- a/arch/arm/include/asm/elf.h
>> +++ b/arch/arm/include/asm/elf.h
>> @@ -115,7 +115,8 @@ int dump_task_regs(struct task_struct *t, elf_gregset_t
>> *elfregs);
>>     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        (2 * TASK_SIZE / 3)
>> +extern unsigned long randomize_et_dyn(unsigned long base);
>> +#define ELF_ET_DYN_BASE        (randomize_et_dyn(2 * TASK_SIZE / 3))
>>
>>  /* 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
>> diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c
>> index 5e85ed3..9177100 100644
>> --- a/arch/arm/mm/mmap.c
>> +++ b/arch/arm/mm/mmap.c
>> @@ -30,6 +30,17 @@ static int mmap_is_legacy(void)
>>         return sysctl_legacy_va_layout;
>>  }
>>
>> +static unsigned long mmap_rnd(void)
>> +{
>> +       unsigned long rnd = 0;
>> +
>> +       /* 8 bits of randomness in 20 address space bits */
>> +       if (current->flags & PF_RANDOMIZE)
>> +               rnd = (long)get_random_int() % (1 << 8);
>> +
>> +       return rnd << PAGE_SHIFT;
>> +}
>> +
>>  static unsigned long mmap_base(unsigned long rnd)
>>  {
>>         unsigned long gap = rlimit(RLIMIT_STACK);
>> @@ -230,3 +241,13 @@ int devmem_is_allowed(unsigned long pfn)
>>  }
>>
>>  #endif
>> +
>> +unsigned long randomize_et_dyn(unsigned long base)
>> +{
>> +       unsigned long ret;
>> +       if ((current->personality & ADDR_NO_RANDOMIZE) ||
>> +               !(current->flags & PF_RANDOMIZE))
>> +               return base;
>> +       ret = base + mmap_rnd();
>> +       return (ret > base) ? ret : base;
>> +}
>> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
>> index b1f9a20..5580d90 100644
>> --- a/arch/arm64/Kconfig
>> +++ b/arch/arm64/Kconfig
>> @@ -1,6 +1,5 @@
>>  config ARM64
>>         def_bool y
>> -       select ARCH_BINFMT_ELF_RANDOMIZE_PIE
>>         select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
>>         select ARCH_HAS_GCOV_PROFILE_ALL
>>         select ARCH_HAS_SG_CHAIN
>> diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
>> index 1f65be3..01d3aab 100644
>> --- a/arch/arm64/include/asm/elf.h
>> +++ b/arch/arm64/include/asm/elf.h
>> @@ -126,7 +126,7 @@ typedef struct user_fpsimd_state elf_fpregset_t;
>>   * that it will "exec", and that there is sufficient room for the brk.
>>   */
>>  extern unsigned long randomize_et_dyn(unsigned long base);
>> -#define ELF_ET_DYN_BASE        (2 * TASK_SIZE_64 / 3)
>> +#define ELF_ET_DYN_BASE        (randomize_et_dyn(2 * TASK_SIZE_64 / 3))
>>
>>  /*
>>   * When the program starts, a1 contains a pointer to a function to be
>> @@ -169,7 +169,7 @@ extern unsigned long arch_randomize_brk(struct mm_struct
>> *mm);
>>  #define COMPAT_ELF_PLATFORM            ("v8l")
>>  #endif
>>
>> -#define COMPAT_ELF_ET_DYN_BASE         (2 * TASK_SIZE_32 / 3)
>> +#define COMPAT_ELF_ET_DYN_BASE         (randomize_et_dyn(2 * TASK_SIZE_32 /
>> 3))
>>
>>  /* AArch32 registers. */
>>  #define COMPAT_ELF_NGREG               18
>> diff --git a/arch/arm64/mm/mmap.c b/arch/arm64/mm/mmap.c
>> index 54922d1..980110c50 100644
>> --- a/arch/arm64/mm/mmap.c
>> +++ b/arch/arm64/mm/mmap.c
>> @@ -89,6 +89,16 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
>>  }
>>  EXPORT_SYMBOL_GPL(arch_pick_mmap_layout);
>>
>> +unsigned long randomize_et_dyn(unsigned long base)
>> +{
>> +       unsigned long ret;
>> +       if ((current->personality & ADDR_NO_RANDOMIZE) ||
>> +               !(current->flags & PF_RANDOMIZE))
>> +               return base;
>> +       ret = base + mmap_rnd();
>> +       return (ret > base) ? ret : base;
>> +}
>> +
>>
>>  /*
>>   * You really shouldn't be using read() or write() on /dev/mem.  This might
>> go
>> diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
>> index 3289969..31cc248 100644
>> --- a/arch/mips/Kconfig
>> +++ b/arch/mips/Kconfig
>> @@ -23,7 +23,6 @@ config MIPS
>>         select HAVE_KRETPROBES
>>         select HAVE_DEBUG_KMEMLEAK
>>         select HAVE_SYSCALL_TRACEPOINTS
>> -       select ARCH_BINFMT_ELF_RANDOMIZE_PIE
>>         select HAVE_ARCH_TRANSPARENT_HUGEPAGE if CPU_SUPPORTS_HUGEPAGES &&
>> 64BIT
>>         select RTC_LIB if !MACH_LOONGSON
>>         select GENERIC_ATOMIC64 if !64BIT
>> diff --git a/arch/mips/include/asm/elf.h b/arch/mips/include/asm/elf.h
>> index eb4d95d..fcac4c99 100644
>> --- a/arch/mips/include/asm/elf.h
>> +++ b/arch/mips/include/asm/elf.h
>> @@ -402,7 +402,8 @@ extern const char *__elf_platform;
>>     that it will "exec", and that there is sufficient room for the brk. */
>>
>>  #ifndef ELF_ET_DYN_BASE
>> -#define ELF_ET_DYN_BASE                (TASK_SIZE / 3 * 2)
>> +extern unsigned long randomize_et_dyn(unsigned long base);
>> +#define ELF_ET_DYN_BASE                (randomize_et_dyn(TASK_SIZE / 3 *
>> 2))
>>  #endif
>>
>>  #define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
>> diff --git a/arch/mips/mm/mmap.c b/arch/mips/mm/mmap.c
>> index f1baadd..20ad644 100644
>> --- a/arch/mips/mm/mmap.c
>> +++ b/arch/mips/mm/mmap.c
>> @@ -196,3 +196,13 @@ int __virt_addr_valid(const volatile void *kaddr)
>>         return pfn_valid(PFN_DOWN(virt_to_phys(kaddr)));
>>  }
>>  EXPORT_SYMBOL_GPL(__virt_addr_valid);
>> +
>> +unsigned long randomize_et_dyn(unsigned long base)
>> +{
>> +       unsigned long ret;
>> +       if ((current->personality & ADDR_NO_RANDOMIZE) ||
>> +               !(current->flags & PF_RANDOMIZE))
>> +               return base;
>> +       ret = base + brk_rnd();
>> +       return (ret > base) ? ret : base;
>> +}
>> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
>> index a2a168e..fa4c877 100644
>> --- a/arch/powerpc/Kconfig
>> +++ b/arch/powerpc/Kconfig
>> @@ -88,7 +88,6 @@ config PPC
>>         select ARCH_MIGHT_HAVE_PC_PARPORT
>>         select ARCH_MIGHT_HAVE_PC_SERIO
>>         select BINFMT_ELF
>> -       select ARCH_BINFMT_ELF_RANDOMIZE_PIE
>>         select OF
>>         select OF_EARLY_FLATTREE
>>         select OF_RESERVED_MEM
>> diff --git a/arch/powerpc/include/asm/elf.h b/arch/powerpc/include/asm/elf.h
>> index 57d289a..4080425 100644
>> --- a/arch/powerpc/include/asm/elf.h
>> +++ b/arch/powerpc/include/asm/elf.h
>> @@ -28,7 +28,8 @@
>>     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
>> +extern unsigned long randomize_et_dyn(unsigned long base);
>> +#define ELF_ET_DYN_BASE        (randomize_et_dyn(0x20000000))
>>
>>  #define ELF_CORE_EFLAGS (is_elf2_task() ? 2 : 0)
>>
>> diff --git a/arch/powerpc/mm/mmap.c b/arch/powerpc/mm/mmap.c
>> index cb8bdbe..3e642e7 100644
>> --- a/arch/powerpc/mm/mmap.c
>> +++ b/arch/powerpc/mm/mmap.c
>> @@ -97,3 +97,13 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
>>                 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
>>         }
>>  }
>> +
>> +unsigned long randomize_et_dyn(unsigned long base)
>> +{
>> +       unsigned long ret;
>> +       if ((current->personality & ADDR_NO_RANDOMIZE) ||
>> +               !(current->flags & PF_RANDOMIZE))
>> +               return base;
>> +       ret = base + mmap_rnd();
>> +       return (ret > base) ? ret : base;
>> +}
>> diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
>> index ba397bd..dcfe16c 100644
>> --- a/arch/x86/Kconfig
>> +++ b/arch/x86/Kconfig
>> @@ -85,7 +85,6 @@ config X86
>>         select HAVE_CMPXCHG_DOUBLE
>>         select HAVE_ARCH_KMEMCHECK
>>         select HAVE_USER_RETURN_NOTIFIER
>> -       select ARCH_BINFMT_ELF_RANDOMIZE_PIE
>>         select HAVE_ARCH_JUMP_LABEL
>>         select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
>>         select SPARSE_IRQ
>> diff --git a/arch/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h
>> index ca3347a..92c6ac4 100644
>> --- a/arch/x86/include/asm/elf.h
>> +++ b/arch/x86/include/asm/elf.h
>> @@ -249,7 +249,8 @@ extern int force_personality32;
>>     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)
>> +extern unsigned long randomize_et_dyn(unsigned long base);
>> +#define ELF_ET_DYN_BASE                (randomize_et_dyn(TASK_SIZE / 3 *
>> 2))
>>
>>  /* 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/arch/x86/mm/mmap.c b/arch/x86/mm/mmap.c
>> index 919b912..7b86605 100644
>> --- a/arch/x86/mm/mmap.c
>> +++ b/arch/x86/mm/mmap.c
>> @@ -122,3 +122,12 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
>>                 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
>>         }
>>  }
>> +unsigned long randomize_et_dyn(unsigned long base)
>> +{
>> +       unsigned long ret;
>> +       if ((current->personality & ADDR_NO_RANDOMIZE) ||
>> +               !(current->flags & PF_RANDOMIZE))
>> +               return base;
>> +       ret = base + mmap_rnd();
>> +       return (ret > base) ? ret : base;
>> +}
>> diff --git a/fs/Kconfig.binfmt b/fs/Kconfig.binfmt
>> index c055d56..1186190 100644
>> --- a/fs/Kconfig.binfmt
>> +++ b/fs/Kconfig.binfmt
>> @@ -27,8 +27,6 @@ config COMPAT_BINFMT_ELF
>>         bool
>>         depends on COMPAT && BINFMT_ELF
>>
>> -config ARCH_BINFMT_ELF_RANDOMIZE_PIE
>> -       bool
>>
>>  config ARCH_BINFMT_ELF_STATE
>>         bool
>> diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
>> index 02b1691..72f7ff5 100644
>> --- a/fs/binfmt_elf.c
>> +++ b/fs/binfmt_elf.c
>> @@ -908,21 +908,7 @@ static int load_elf_binary(struct linux_binprm *bprm)
>>                          * 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.  */
>> -#ifdef CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE
>> -                       /* Memory randomization might have been switched off
>> -                        * in runtime via sysctl or explicit setting of
>> -                        * personality flags.
>> -                        * If that is the case, retain the original non-zero
>> -                        * load_bias value in order to establish proper
>> -                        * non-randomized mappings.
>> -                        */
>> -                       if (current->flags & PF_RANDOMIZE)
>> -                               load_bias = 0;
>> -                       else
>> -                               load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE -
>> vaddr);
>> -#else
>>                         load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
>> -#endif
>>                 }
>>
>>                 error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt,
>
> I think this is much cleaner now without
> ARCH_BINFMT_ELF_RANDOMIZE_PIE. I imagine there could be some follow-up
> cleanups to standardize (or at least clearly document) the intended
> levels of entropy in the 4 ASLR regions on each architecture, as it
> currently varies a bit.
>
> Thanks!
>
> -Kees
>
> --
> Kees Cook
> Chrome OS Security
>

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

* Re: [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS
@ 2015-02-23 19:54     ` Hector Marco Gisbert
  0 siblings, 0 replies; 56+ messages in thread
From: Hector Marco Gisbert @ 2015-02-23 19:54 UTC (permalink / raw)
  To: Kees Cook
  Cc: Linux MIPS Mailing List, x86, LKML, ismael Ripoll, Andrew Morton,
	linuxppc-dev, linux-arm-kernel

[PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS

The issue appears on PIE linked executables when all memory areas of a
process are randomized. In this case, the attack "offset2lib" de-randomizes
all library areas on 64 bit Linux systems in less than one second.


Further details of the PoC attack at:
http://cybersecurity.upv.es/attacks/offset2lib/offset2lib.html


This patch loads the PIE linked executable in a different area than the
libraries. The successful fix can be tested with a simple pie compiled
application:


$ ./show_mmaps_pie
54859ccd6000-54859ccd7000 r-xp  ...  /tmp/show_mmaps_pie
54859ced6000-54859ced7000 r--p  ...  /tmp/show_mmaps_pie
54859ced7000-54859ced8000 rw-p  ...  /tmp/show_mmaps_pie
7f75be764000-7f75be91f000 r-xp  ...  /lib/x86_64-linux-gnu/libc.so.6
7f75be91f000-7f75beb1f000 ---p  ...  /lib/x86_64-linux-gnu/libc.so.6
7f75beb1f000-7f75beb23000 r--p  ...  /lib/x86_64-linux-gnu/libc.so.6
7f75beb23000-7f75beb25000 rw-p  ...  /lib/x86_64-linux-gnu/libc.so.6
7f75beb25000-7f75beb2a000 rw-p  ...
7f75beb2a000-7f75beb4d000 r-xp  ...  /lib64/ld-linux-x86-64.so.2
7f75bed45000-7f75bed46000 rw-p  ...
7f75bed46000-7f75bed47000 r-xp  ...
7f75bed47000-7f75bed4c000 rw-p  ...
7f75bed4c000-7f75bed4d000 r--p  ...  /lib64/ld-linux-x86-64.so.2
7f75bed4d000-7f75bed4e000 rw-p  ...  /lib64/ld-linux-x86-64.so.2
7f75bed4e000-7f75bed4f000 rw-p  ...
7fffb3741000-7fffb3762000 rw-p  ...  [stack]
7fffb377b000-7fffb377d000 r--p  ...  [vvar]
7fffb377d000-7fffb377f000 r-xp  ...  [vdso]


Once corrected, the PIE linked application is loaded in a different area.

We updated the "Fixing Offset2lib weakness" page:
http://cybersecurity.upv.es/solutions/aslrv2/aslrv2.html


Signed-off-by: Hector Marco-Gisbert <hecmargi@upv.es>
Signed-off-by: Ismael Ripoll <iripoll@upv.es>

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 97d07ed..ee7ea7e 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1,7 +1,6 @@
  config ARM
  	bool
  	default y
-	select ARCH_BINFMT_ELF_RANDOMIZE_PIE
  	select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
  	select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
  	select ARCH_HAVE_CUSTOM_GPIO_H
diff --git a/arch/arm/include/asm/elf.h b/arch/arm/include/asm/elf.h
index afb9caf..6755cd8 100644
--- a/arch/arm/include/asm/elf.h
+++ b/arch/arm/include/asm/elf.h
@@ -115,7 +115,8 @@ int dump_task_regs(struct task_struct *t,  
elf_gregset_t *elfregs);
     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	(2 * TASK_SIZE / 3)
+extern unsigned long randomize_et_dyn(unsigned long base);
+#define ELF_ET_DYN_BASE	(randomize_et_dyn(2 * TASK_SIZE / 3))

  /* 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
diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c
index 5e85ed3..9177100 100644
--- a/arch/arm/mm/mmap.c
+++ b/arch/arm/mm/mmap.c
@@ -30,6 +30,17 @@ static int mmap_is_legacy(void)
  	return sysctl_legacy_va_layout;
  }

+static unsigned long mmap_rnd(void)
+{
+	unsigned long rnd = 0;
+
+	/* 8 bits of randomness in 20 address space bits */
+	if (current->flags & PF_RANDOMIZE)
+		rnd = (long)get_random_int() % (1 << 8);
+
+	return rnd << PAGE_SHIFT;
+}
+
  static unsigned long mmap_base(unsigned long rnd)
  {
  	unsigned long gap = rlimit(RLIMIT_STACK);
@@ -230,3 +241,13 @@ int devmem_is_allowed(unsigned long pfn)
  }

  #endif
+
+unsigned long randomize_et_dyn(unsigned long base)
+{
+	unsigned long ret;
+	if ((current->personality & ADDR_NO_RANDOMIZE) ||
+		!(current->flags & PF_RANDOMIZE))
+		return base;
+	ret = base + mmap_rnd();
+	return (ret > base) ? ret : base;
+}
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index b1f9a20..5580d90 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -1,6 +1,5 @@
  config ARM64
  	def_bool y
-	select ARCH_BINFMT_ELF_RANDOMIZE_PIE
  	select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
  	select ARCH_HAS_GCOV_PROFILE_ALL
  	select ARCH_HAS_SG_CHAIN
diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
index 1f65be3..01d3aab 100644
--- a/arch/arm64/include/asm/elf.h
+++ b/arch/arm64/include/asm/elf.h
@@ -126,7 +126,7 @@ typedef struct user_fpsimd_state elf_fpregset_t;
   * that it will "exec", and that there is sufficient room for the brk.
   */
  extern unsigned long randomize_et_dyn(unsigned long base);
-#define ELF_ET_DYN_BASE	(2 * TASK_SIZE_64 / 3)
+#define ELF_ET_DYN_BASE	(randomize_et_dyn(2 * TASK_SIZE_64 / 3))

  /*
   * When the program starts, a1 contains a pointer to a function to be
@@ -169,7 +169,7 @@ extern unsigned long arch_randomize_brk(struct  
mm_struct *mm);
  #define COMPAT_ELF_PLATFORM		("v8l")
  #endif

-#define COMPAT_ELF_ET_DYN_BASE		(2 * TASK_SIZE_32 / 3)
+#define COMPAT_ELF_ET_DYN_BASE		(randomize_et_dyn(2 * TASK_SIZE_32 / 3))

  /* AArch32 registers. */
  #define COMPAT_ELF_NGREG		18
diff --git a/arch/arm64/mm/mmap.c b/arch/arm64/mm/mmap.c
index 54922d1..980110c50 100644
--- a/arch/arm64/mm/mmap.c
+++ b/arch/arm64/mm/mmap.c
@@ -89,6 +89,16 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
  }
  EXPORT_SYMBOL_GPL(arch_pick_mmap_layout);

+unsigned long randomize_et_dyn(unsigned long base)
+{
+	unsigned long ret;
+	if ((current->personality & ADDR_NO_RANDOMIZE) ||
+		!(current->flags & PF_RANDOMIZE))
+		return base;
+	ret = base + mmap_rnd();
+	return (ret > base) ? ret : base;
+}
+

  /*
   * You really shouldn't be using read() or write() on /dev/mem.   
This might go
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 3289969..31cc248 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -23,7 +23,6 @@ config MIPS
  	select HAVE_KRETPROBES
  	select HAVE_DEBUG_KMEMLEAK
  	select HAVE_SYSCALL_TRACEPOINTS
-	select ARCH_BINFMT_ELF_RANDOMIZE_PIE
  	select HAVE_ARCH_TRANSPARENT_HUGEPAGE if CPU_SUPPORTS_HUGEPAGES && 64BIT
  	select RTC_LIB if !MACH_LOONGSON
  	select GENERIC_ATOMIC64 if !64BIT
diff --git a/arch/mips/include/asm/elf.h b/arch/mips/include/asm/elf.h
index eb4d95d..fcac4c99 100644
--- a/arch/mips/include/asm/elf.h
+++ b/arch/mips/include/asm/elf.h
@@ -402,7 +402,8 @@ extern const char *__elf_platform;
     that it will "exec", and that there is sufficient room for the brk.	*/

  #ifndef ELF_ET_DYN_BASE
-#define ELF_ET_DYN_BASE		(TASK_SIZE / 3 * 2)
+extern unsigned long randomize_et_dyn(unsigned long base);
+#define ELF_ET_DYN_BASE		(randomize_et_dyn(TASK_SIZE / 3 * 2))
  #endif

  #define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
diff --git a/arch/mips/mm/mmap.c b/arch/mips/mm/mmap.c
index f1baadd..20ad644 100644
--- a/arch/mips/mm/mmap.c
+++ b/arch/mips/mm/mmap.c
@@ -196,3 +196,13 @@ int __virt_addr_valid(const volatile void *kaddr)
  	return pfn_valid(PFN_DOWN(virt_to_phys(kaddr)));
  }
  EXPORT_SYMBOL_GPL(__virt_addr_valid);
+
+unsigned long randomize_et_dyn(unsigned long base)
+{
+	unsigned long ret;
+	if ((current->personality & ADDR_NO_RANDOMIZE) ||
+		!(current->flags & PF_RANDOMIZE))
+		return base;
+	ret = base + brk_rnd();
+	return (ret > base) ? ret : base;
+}
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index a2a168e..fa4c877 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -88,7 +88,6 @@ config PPC
  	select ARCH_MIGHT_HAVE_PC_PARPORT
  	select ARCH_MIGHT_HAVE_PC_SERIO
  	select BINFMT_ELF
-	select ARCH_BINFMT_ELF_RANDOMIZE_PIE
  	select OF
  	select OF_EARLY_FLATTREE
  	select OF_RESERVED_MEM
diff --git a/arch/powerpc/include/asm/elf.h b/arch/powerpc/include/asm/elf.h
index 57d289a..4080425 100644
--- a/arch/powerpc/include/asm/elf.h
+++ b/arch/powerpc/include/asm/elf.h
@@ -28,7 +28,8 @@
     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
+extern unsigned long randomize_et_dyn(unsigned long base);
+#define ELF_ET_DYN_BASE	(randomize_et_dyn(0x20000000))

  #define ELF_CORE_EFLAGS (is_elf2_task() ? 2 : 0)

diff --git a/arch/powerpc/mm/mmap.c b/arch/powerpc/mm/mmap.c
index cb8bdbe..3e642e7 100644
--- a/arch/powerpc/mm/mmap.c
+++ b/arch/powerpc/mm/mmap.c
@@ -97,3 +97,13 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
  		mm->get_unmapped_area = arch_get_unmapped_area_topdown;
  	}
  }
+
+unsigned long randomize_et_dyn(unsigned long base)
+{
+	unsigned long ret;
+	if ((current->personality & ADDR_NO_RANDOMIZE) ||
+		!(current->flags & PF_RANDOMIZE))
+		return base;
+	ret = base + mmap_rnd();
+	return (ret > base) ? ret : base;
+}
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index ba397bd..dcfe16c 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -85,7 +85,6 @@ config X86
  	select HAVE_CMPXCHG_DOUBLE
  	select HAVE_ARCH_KMEMCHECK
  	select HAVE_USER_RETURN_NOTIFIER
-	select ARCH_BINFMT_ELF_RANDOMIZE_PIE
  	select HAVE_ARCH_JUMP_LABEL
  	select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
  	select SPARSE_IRQ
diff --git a/arch/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h
index ca3347a..92c6ac4 100644
--- a/arch/x86/include/asm/elf.h
+++ b/arch/x86/include/asm/elf.h
@@ -249,7 +249,8 @@ extern int force_personality32;
     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)
+extern unsigned long randomize_et_dyn(unsigned long base);
+#define ELF_ET_DYN_BASE		(randomize_et_dyn(TASK_SIZE / 3 * 2))

  /* 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/arch/x86/mm/mmap.c b/arch/x86/mm/mmap.c
index 919b912..7b86605 100644
--- a/arch/x86/mm/mmap.c
+++ b/arch/x86/mm/mmap.c
@@ -122,3 +122,12 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
  		mm->get_unmapped_area = arch_get_unmapped_area_topdown;
  	}
  }
+unsigned long randomize_et_dyn(unsigned long base)
+{
+	unsigned long ret;
+	if ((current->personality & ADDR_NO_RANDOMIZE) ||
+		!(current->flags & PF_RANDOMIZE))
+		return base;
+	ret = base + mmap_rnd();
+	return (ret > base) ? ret : base;
+}
diff --git a/fs/Kconfig.binfmt b/fs/Kconfig.binfmt
index c055d56..1186190 100644
--- a/fs/Kconfig.binfmt
+++ b/fs/Kconfig.binfmt
@@ -27,8 +27,6 @@ config COMPAT_BINFMT_ELF
  	bool
  	depends on COMPAT && BINFMT_ELF

-config ARCH_BINFMT_ELF_RANDOMIZE_PIE
-	bool

  config ARCH_BINFMT_ELF_STATE
  	bool
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 02b1691..72f7ff5 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -908,21 +908,7 @@ static int load_elf_binary(struct linux_binprm *bprm)
  			 * 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.  */
-#ifdef CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE
-			/* Memory randomization might have been switched off
-			 * in runtime via sysctl or explicit setting of
-			 * personality flags.
-			 * If that is the case, retain the original non-zero
-			 * load_bias value in order to establish proper
-			 * non-randomized mappings.
-			 */
-			if (current->flags & PF_RANDOMIZE)
-				load_bias = 0;
-			else
-				load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
-#else
  			load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
-#endif
  		}

  		error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt,



Kees Cook <keescook@chromium.org> escribió:

> (I've added some additional CCs to make sure the arch maintainers
> notice this patch.)
>
> This patch seems white-space damaged to me. I had to do a lot of
> manual editing to get it to apply. Please use "git format-patch", if
> you're not already. What version of the kernel was this based on?
>
> On Mon, Feb 23, 2015 at 10:37 AM, Hector Marco <hecmargi@upv.es> wrote:
>> [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS
>>
>> The issue appears on PIE linked executables when all memory areas of a
>> process are randomized. In this case, the attack "offset2lib" de-randomizes
>> all library areas on 64 bit Linux systems in less than one second.
>>
>>
>> Further details of the PoC attack at:
>> http://cybersecurity.upv.es/attacks/offset2lib/offset2lib.html
>>
>>
>> This patch loads the PIE linked executable in a different area than the
>> libraries. The successful fix can be tested with a simple pie compiled
>> application:
>>
>>
>> $ ./show_mmaps_pie
>> 54859ccd6000-54859ccd7000 r-xp  ...  /tmp/show_mmaps_pie
>> 54859ced6000-54859ced7000 r--p  ...  /tmp/show_mmaps_pie
>> 54859ced7000-54859ced8000 rw-p  ...  /tmp/show_mmaps_pie
>> 7f75be764000-7f75be91f000 r-xp  ...  /lib/x86_64-linux-gnu/libc.so.6
>> 7f75be91f000-7f75beb1f000 ---p  ...  /lib/x86_64-linux-gnu/libc.so.6
>> 7f75beb1f000-7f75beb23000 r--p  ...  /lib/x86_64-linux-gnu/libc.so.6
>> 7f75beb23000-7f75beb25000 rw-p  ...  /lib/x86_64-linux-gnu/libc.so.6
>> 7f75beb25000-7f75beb2a000 rw-p  ...
>> 7f75beb2a000-7f75beb4d000 r-xp  ...  /lib64/ld-linux-x86-64.so.2
>> 7f75bed45000-7f75bed46000 rw-p  ...
>> 7f75bed46000-7f75bed47000 r-xp  ...
>> 7f75bed47000-7f75bed4c000 rw-p  ...
>> 7f75bed4c000-7f75bed4d000 r--p  ...  /lib64/ld-linux-x86-64.so.2
>> 7f75bed4d000-7f75bed4e000 rw-p  ...  /lib64/ld-linux-x86-64.so.2
>> 7f75bed4e000-7f75bed4f000 rw-p  ...
>> 7fffb3741000-7fffb3762000 rw-p  ...  [stack]
>> 7fffb377b000-7fffb377d000 r--p  ...  [vvar]
>> 7fffb377d000-7fffb377f000 r-xp  ...  [vdso]
>>
>>
>> Once corrected, the PIE linked application is loaded in a different area.
>
> Thanks for working on this!
>
>>
>> We updated the "Fixing Offset2lib weakness" page:
>> http://cybersecurity.upv.es/solutions/aslrv2/aslrv2.html
>>
>>
>> Signed-off-by: Hector Marco-Gisbert <hecmargi@upv.es>
>> Signed-off-by: Ismael Ripoll <iripoll@upv.es>
>
> Acked-by: Kees Cook <keescook@chromium.org>
>
>>
>>
>> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
>> index 97d07ed..ee7ea7e 100644
>> --- a/arch/arm/Kconfig
>> +++ b/arch/arm/Kconfig
>> @@ -1,7 +1,6 @@
>>  config ARM
>>         bool
>>         default y
>> -       select ARCH_BINFMT_ELF_RANDOMIZE_PIE
>>         select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
>>         select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
>>         select ARCH_HAVE_CUSTOM_GPIO_H
>> diff --git a/arch/arm/include/asm/elf.h b/arch/arm/include/asm/elf.h
>> index afb9caf..6755cd8 100644
>> --- a/arch/arm/include/asm/elf.h
>> +++ b/arch/arm/include/asm/elf.h
>> @@ -115,7 +115,8 @@ int dump_task_regs(struct task_struct *t, elf_gregset_t
>> *elfregs);
>>     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        (2 * TASK_SIZE / 3)
>> +extern unsigned long randomize_et_dyn(unsigned long base);
>> +#define ELF_ET_DYN_BASE        (randomize_et_dyn(2 * TASK_SIZE / 3))
>>
>>  /* 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
>> diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c
>> index 5e85ed3..9177100 100644
>> --- a/arch/arm/mm/mmap.c
>> +++ b/arch/arm/mm/mmap.c
>> @@ -30,6 +30,17 @@ static int mmap_is_legacy(void)
>>         return sysctl_legacy_va_layout;
>>  }
>>
>> +static unsigned long mmap_rnd(void)
>> +{
>> +       unsigned long rnd = 0;
>> +
>> +       /* 8 bits of randomness in 20 address space bits */
>> +       if (current->flags & PF_RANDOMIZE)
>> +               rnd = (long)get_random_int() % (1 << 8);
>> +
>> +       return rnd << PAGE_SHIFT;
>> +}
>> +
>>  static unsigned long mmap_base(unsigned long rnd)
>>  {
>>         unsigned long gap = rlimit(RLIMIT_STACK);
>> @@ -230,3 +241,13 @@ int devmem_is_allowed(unsigned long pfn)
>>  }
>>
>>  #endif
>> +
>> +unsigned long randomize_et_dyn(unsigned long base)
>> +{
>> +       unsigned long ret;
>> +       if ((current->personality & ADDR_NO_RANDOMIZE) ||
>> +               !(current->flags & PF_RANDOMIZE))
>> +               return base;
>> +       ret = base + mmap_rnd();
>> +       return (ret > base) ? ret : base;
>> +}
>> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
>> index b1f9a20..5580d90 100644
>> --- a/arch/arm64/Kconfig
>> +++ b/arch/arm64/Kconfig
>> @@ -1,6 +1,5 @@
>>  config ARM64
>>         def_bool y
>> -       select ARCH_BINFMT_ELF_RANDOMIZE_PIE
>>         select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
>>         select ARCH_HAS_GCOV_PROFILE_ALL
>>         select ARCH_HAS_SG_CHAIN
>> diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
>> index 1f65be3..01d3aab 100644
>> --- a/arch/arm64/include/asm/elf.h
>> +++ b/arch/arm64/include/asm/elf.h
>> @@ -126,7 +126,7 @@ typedef struct user_fpsimd_state elf_fpregset_t;
>>   * that it will "exec", and that there is sufficient room for the brk.
>>   */
>>  extern unsigned long randomize_et_dyn(unsigned long base);
>> -#define ELF_ET_DYN_BASE        (2 * TASK_SIZE_64 / 3)
>> +#define ELF_ET_DYN_BASE        (randomize_et_dyn(2 * TASK_SIZE_64 / 3))
>>
>>  /*
>>   * When the program starts, a1 contains a pointer to a function to be
>> @@ -169,7 +169,7 @@ extern unsigned long arch_randomize_brk(struct mm_struct
>> *mm);
>>  #define COMPAT_ELF_PLATFORM            ("v8l")
>>  #endif
>>
>> -#define COMPAT_ELF_ET_DYN_BASE         (2 * TASK_SIZE_32 / 3)
>> +#define COMPAT_ELF_ET_DYN_BASE         (randomize_et_dyn(2 * TASK_SIZE_32 /
>> 3))
>>
>>  /* AArch32 registers. */
>>  #define COMPAT_ELF_NGREG               18
>> diff --git a/arch/arm64/mm/mmap.c b/arch/arm64/mm/mmap.c
>> index 54922d1..980110c50 100644
>> --- a/arch/arm64/mm/mmap.c
>> +++ b/arch/arm64/mm/mmap.c
>> @@ -89,6 +89,16 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
>>  }
>>  EXPORT_SYMBOL_GPL(arch_pick_mmap_layout);
>>
>> +unsigned long randomize_et_dyn(unsigned long base)
>> +{
>> +       unsigned long ret;
>> +       if ((current->personality & ADDR_NO_RANDOMIZE) ||
>> +               !(current->flags & PF_RANDOMIZE))
>> +               return base;
>> +       ret = base + mmap_rnd();
>> +       return (ret > base) ? ret : base;
>> +}
>> +
>>
>>  /*
>>   * You really shouldn't be using read() or write() on /dev/mem.  This might
>> go
>> diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
>> index 3289969..31cc248 100644
>> --- a/arch/mips/Kconfig
>> +++ b/arch/mips/Kconfig
>> @@ -23,7 +23,6 @@ config MIPS
>>         select HAVE_KRETPROBES
>>         select HAVE_DEBUG_KMEMLEAK
>>         select HAVE_SYSCALL_TRACEPOINTS
>> -       select ARCH_BINFMT_ELF_RANDOMIZE_PIE
>>         select HAVE_ARCH_TRANSPARENT_HUGEPAGE if CPU_SUPPORTS_HUGEPAGES &&
>> 64BIT
>>         select RTC_LIB if !MACH_LOONGSON
>>         select GENERIC_ATOMIC64 if !64BIT
>> diff --git a/arch/mips/include/asm/elf.h b/arch/mips/include/asm/elf.h
>> index eb4d95d..fcac4c99 100644
>> --- a/arch/mips/include/asm/elf.h
>> +++ b/arch/mips/include/asm/elf.h
>> @@ -402,7 +402,8 @@ extern const char *__elf_platform;
>>     that it will "exec", and that there is sufficient room for the brk. */
>>
>>  #ifndef ELF_ET_DYN_BASE
>> -#define ELF_ET_DYN_BASE                (TASK_SIZE / 3 * 2)
>> +extern unsigned long randomize_et_dyn(unsigned long base);
>> +#define ELF_ET_DYN_BASE                (randomize_et_dyn(TASK_SIZE / 3 *
>> 2))
>>  #endif
>>
>>  #define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
>> diff --git a/arch/mips/mm/mmap.c b/arch/mips/mm/mmap.c
>> index f1baadd..20ad644 100644
>> --- a/arch/mips/mm/mmap.c
>> +++ b/arch/mips/mm/mmap.c
>> @@ -196,3 +196,13 @@ int __virt_addr_valid(const volatile void *kaddr)
>>         return pfn_valid(PFN_DOWN(virt_to_phys(kaddr)));
>>  }
>>  EXPORT_SYMBOL_GPL(__virt_addr_valid);
>> +
>> +unsigned long randomize_et_dyn(unsigned long base)
>> +{
>> +       unsigned long ret;
>> +       if ((current->personality & ADDR_NO_RANDOMIZE) ||
>> +               !(current->flags & PF_RANDOMIZE))
>> +               return base;
>> +       ret = base + brk_rnd();
>> +       return (ret > base) ? ret : base;
>> +}
>> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
>> index a2a168e..fa4c877 100644
>> --- a/arch/powerpc/Kconfig
>> +++ b/arch/powerpc/Kconfig
>> @@ -88,7 +88,6 @@ config PPC
>>         select ARCH_MIGHT_HAVE_PC_PARPORT
>>         select ARCH_MIGHT_HAVE_PC_SERIO
>>         select BINFMT_ELF
>> -       select ARCH_BINFMT_ELF_RANDOMIZE_PIE
>>         select OF
>>         select OF_EARLY_FLATTREE
>>         select OF_RESERVED_MEM
>> diff --git a/arch/powerpc/include/asm/elf.h b/arch/powerpc/include/asm/elf.h
>> index 57d289a..4080425 100644
>> --- a/arch/powerpc/include/asm/elf.h
>> +++ b/arch/powerpc/include/asm/elf.h
>> @@ -28,7 +28,8 @@
>>     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
>> +extern unsigned long randomize_et_dyn(unsigned long base);
>> +#define ELF_ET_DYN_BASE        (randomize_et_dyn(0x20000000))
>>
>>  #define ELF_CORE_EFLAGS (is_elf2_task() ? 2 : 0)
>>
>> diff --git a/arch/powerpc/mm/mmap.c b/arch/powerpc/mm/mmap.c
>> index cb8bdbe..3e642e7 100644
>> --- a/arch/powerpc/mm/mmap.c
>> +++ b/arch/powerpc/mm/mmap.c
>> @@ -97,3 +97,13 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
>>                 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
>>         }
>>  }
>> +
>> +unsigned long randomize_et_dyn(unsigned long base)
>> +{
>> +       unsigned long ret;
>> +       if ((current->personality & ADDR_NO_RANDOMIZE) ||
>> +               !(current->flags & PF_RANDOMIZE))
>> +               return base;
>> +       ret = base + mmap_rnd();
>> +       return (ret > base) ? ret : base;
>> +}
>> diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
>> index ba397bd..dcfe16c 100644
>> --- a/arch/x86/Kconfig
>> +++ b/arch/x86/Kconfig
>> @@ -85,7 +85,6 @@ config X86
>>         select HAVE_CMPXCHG_DOUBLE
>>         select HAVE_ARCH_KMEMCHECK
>>         select HAVE_USER_RETURN_NOTIFIER
>> -       select ARCH_BINFMT_ELF_RANDOMIZE_PIE
>>         select HAVE_ARCH_JUMP_LABEL
>>         select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
>>         select SPARSE_IRQ
>> diff --git a/arch/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h
>> index ca3347a..92c6ac4 100644
>> --- a/arch/x86/include/asm/elf.h
>> +++ b/arch/x86/include/asm/elf.h
>> @@ -249,7 +249,8 @@ extern int force_personality32;
>>     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)
>> +extern unsigned long randomize_et_dyn(unsigned long base);
>> +#define ELF_ET_DYN_BASE                (randomize_et_dyn(TASK_SIZE / 3 *
>> 2))
>>
>>  /* 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/arch/x86/mm/mmap.c b/arch/x86/mm/mmap.c
>> index 919b912..7b86605 100644
>> --- a/arch/x86/mm/mmap.c
>> +++ b/arch/x86/mm/mmap.c
>> @@ -122,3 +122,12 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
>>                 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
>>         }
>>  }
>> +unsigned long randomize_et_dyn(unsigned long base)
>> +{
>> +       unsigned long ret;
>> +       if ((current->personality & ADDR_NO_RANDOMIZE) ||
>> +               !(current->flags & PF_RANDOMIZE))
>> +               return base;
>> +       ret = base + mmap_rnd();
>> +       return (ret > base) ? ret : base;
>> +}
>> diff --git a/fs/Kconfig.binfmt b/fs/Kconfig.binfmt
>> index c055d56..1186190 100644
>> --- a/fs/Kconfig.binfmt
>> +++ b/fs/Kconfig.binfmt
>> @@ -27,8 +27,6 @@ config COMPAT_BINFMT_ELF
>>         bool
>>         depends on COMPAT && BINFMT_ELF
>>
>> -config ARCH_BINFMT_ELF_RANDOMIZE_PIE
>> -       bool
>>
>>  config ARCH_BINFMT_ELF_STATE
>>         bool
>> diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
>> index 02b1691..72f7ff5 100644
>> --- a/fs/binfmt_elf.c
>> +++ b/fs/binfmt_elf.c
>> @@ -908,21 +908,7 @@ static int load_elf_binary(struct linux_binprm *bprm)
>>                          * 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.  */
>> -#ifdef CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE
>> -                       /* Memory randomization might have been switched off
>> -                        * in runtime via sysctl or explicit setting of
>> -                        * personality flags.
>> -                        * If that is the case, retain the original non-zero
>> -                        * load_bias value in order to establish proper
>> -                        * non-randomized mappings.
>> -                        */
>> -                       if (current->flags & PF_RANDOMIZE)
>> -                               load_bias = 0;
>> -                       else
>> -                               load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE -
>> vaddr);
>> -#else
>>                         load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
>> -#endif
>>                 }
>>
>>                 error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt,
>
> I think this is much cleaner now without
> ARCH_BINFMT_ELF_RANDOMIZE_PIE. I imagine there could be some follow-up
> cleanups to standardize (or at least clearly document) the intended
> levels of entropy in the 4 ASLR regions on each architecture, as it
> currently varies a bit.
>
> Thanks!
>
> -Kees
>
> --
> Kees Cook
> Chrome OS Security
>

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

* [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS
@ 2015-02-23 19:54     ` Hector Marco Gisbert
  0 siblings, 0 replies; 56+ messages in thread
From: Hector Marco Gisbert @ 2015-02-23 19:54 UTC (permalink / raw)
  To: linux-arm-kernel

[PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS

The issue appears on PIE linked executables when all memory areas of a
process are randomized. In this case, the attack "offset2lib" de-randomizes
all library areas on 64 bit Linux systems in less than one second.


Further details of the PoC attack at:
http://cybersecurity.upv.es/attacks/offset2lib/offset2lib.html


This patch loads the PIE linked executable in a different area than the
libraries. The successful fix can be tested with a simple pie compiled
application:


$ ./show_mmaps_pie
54859ccd6000-54859ccd7000 r-xp  ...  /tmp/show_mmaps_pie
54859ced6000-54859ced7000 r--p  ...  /tmp/show_mmaps_pie
54859ced7000-54859ced8000 rw-p  ...  /tmp/show_mmaps_pie
7f75be764000-7f75be91f000 r-xp  ...  /lib/x86_64-linux-gnu/libc.so.6
7f75be91f000-7f75beb1f000 ---p  ...  /lib/x86_64-linux-gnu/libc.so.6
7f75beb1f000-7f75beb23000 r--p  ...  /lib/x86_64-linux-gnu/libc.so.6
7f75beb23000-7f75beb25000 rw-p  ...  /lib/x86_64-linux-gnu/libc.so.6
7f75beb25000-7f75beb2a000 rw-p  ...
7f75beb2a000-7f75beb4d000 r-xp  ...  /lib64/ld-linux-x86-64.so.2
7f75bed45000-7f75bed46000 rw-p  ...
7f75bed46000-7f75bed47000 r-xp  ...
7f75bed47000-7f75bed4c000 rw-p  ...
7f75bed4c000-7f75bed4d000 r--p  ...  /lib64/ld-linux-x86-64.so.2
7f75bed4d000-7f75bed4e000 rw-p  ...  /lib64/ld-linux-x86-64.so.2
7f75bed4e000-7f75bed4f000 rw-p  ...
7fffb3741000-7fffb3762000 rw-p  ...  [stack]
7fffb377b000-7fffb377d000 r--p  ...  [vvar]
7fffb377d000-7fffb377f000 r-xp  ...  [vdso]


Once corrected, the PIE linked application is loaded in a different area.

We updated the "Fixing Offset2lib weakness" page:
http://cybersecurity.upv.es/solutions/aslrv2/aslrv2.html


Signed-off-by: Hector Marco-Gisbert <hecmargi@upv.es>
Signed-off-by: Ismael Ripoll <iripoll@upv.es>

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 97d07ed..ee7ea7e 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1,7 +1,6 @@
  config ARM
  	bool
  	default y
-	select ARCH_BINFMT_ELF_RANDOMIZE_PIE
  	select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
  	select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
  	select ARCH_HAVE_CUSTOM_GPIO_H
diff --git a/arch/arm/include/asm/elf.h b/arch/arm/include/asm/elf.h
index afb9caf..6755cd8 100644
--- a/arch/arm/include/asm/elf.h
+++ b/arch/arm/include/asm/elf.h
@@ -115,7 +115,8 @@ int dump_task_regs(struct task_struct *t,  
elf_gregset_t *elfregs);
     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	(2 * TASK_SIZE / 3)
+extern unsigned long randomize_et_dyn(unsigned long base);
+#define ELF_ET_DYN_BASE	(randomize_et_dyn(2 * TASK_SIZE / 3))

  /* 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
diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c
index 5e85ed3..9177100 100644
--- a/arch/arm/mm/mmap.c
+++ b/arch/arm/mm/mmap.c
@@ -30,6 +30,17 @@ static int mmap_is_legacy(void)
  	return sysctl_legacy_va_layout;
  }

+static unsigned long mmap_rnd(void)
+{
+	unsigned long rnd = 0;
+
+	/* 8 bits of randomness in 20 address space bits */
+	if (current->flags & PF_RANDOMIZE)
+		rnd = (long)get_random_int() % (1 << 8);
+
+	return rnd << PAGE_SHIFT;
+}
+
  static unsigned long mmap_base(unsigned long rnd)
  {
  	unsigned long gap = rlimit(RLIMIT_STACK);
@@ -230,3 +241,13 @@ int devmem_is_allowed(unsigned long pfn)
  }

  #endif
+
+unsigned long randomize_et_dyn(unsigned long base)
+{
+	unsigned long ret;
+	if ((current->personality & ADDR_NO_RANDOMIZE) ||
+		!(current->flags & PF_RANDOMIZE))
+		return base;
+	ret = base + mmap_rnd();
+	return (ret > base) ? ret : base;
+}
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index b1f9a20..5580d90 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -1,6 +1,5 @@
  config ARM64
  	def_bool y
-	select ARCH_BINFMT_ELF_RANDOMIZE_PIE
  	select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
  	select ARCH_HAS_GCOV_PROFILE_ALL
  	select ARCH_HAS_SG_CHAIN
diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
index 1f65be3..01d3aab 100644
--- a/arch/arm64/include/asm/elf.h
+++ b/arch/arm64/include/asm/elf.h
@@ -126,7 +126,7 @@ typedef struct user_fpsimd_state elf_fpregset_t;
   * that it will "exec", and that there is sufficient room for the brk.
   */
  extern unsigned long randomize_et_dyn(unsigned long base);
-#define ELF_ET_DYN_BASE	(2 * TASK_SIZE_64 / 3)
+#define ELF_ET_DYN_BASE	(randomize_et_dyn(2 * TASK_SIZE_64 / 3))

  /*
   * When the program starts, a1 contains a pointer to a function to be
@@ -169,7 +169,7 @@ extern unsigned long arch_randomize_brk(struct  
mm_struct *mm);
  #define COMPAT_ELF_PLATFORM		("v8l")
  #endif

-#define COMPAT_ELF_ET_DYN_BASE		(2 * TASK_SIZE_32 / 3)
+#define COMPAT_ELF_ET_DYN_BASE		(randomize_et_dyn(2 * TASK_SIZE_32 / 3))

  /* AArch32 registers. */
  #define COMPAT_ELF_NGREG		18
diff --git a/arch/arm64/mm/mmap.c b/arch/arm64/mm/mmap.c
index 54922d1..980110c50 100644
--- a/arch/arm64/mm/mmap.c
+++ b/arch/arm64/mm/mmap.c
@@ -89,6 +89,16 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
  }
  EXPORT_SYMBOL_GPL(arch_pick_mmap_layout);

+unsigned long randomize_et_dyn(unsigned long base)
+{
+	unsigned long ret;
+	if ((current->personality & ADDR_NO_RANDOMIZE) ||
+		!(current->flags & PF_RANDOMIZE))
+		return base;
+	ret = base + mmap_rnd();
+	return (ret > base) ? ret : base;
+}
+

  /*
   * You really shouldn't be using read() or write() on /dev/mem.   
This might go
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 3289969..31cc248 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -23,7 +23,6 @@ config MIPS
  	select HAVE_KRETPROBES
  	select HAVE_DEBUG_KMEMLEAK
  	select HAVE_SYSCALL_TRACEPOINTS
-	select ARCH_BINFMT_ELF_RANDOMIZE_PIE
  	select HAVE_ARCH_TRANSPARENT_HUGEPAGE if CPU_SUPPORTS_HUGEPAGES && 64BIT
  	select RTC_LIB if !MACH_LOONGSON
  	select GENERIC_ATOMIC64 if !64BIT
diff --git a/arch/mips/include/asm/elf.h b/arch/mips/include/asm/elf.h
index eb4d95d..fcac4c99 100644
--- a/arch/mips/include/asm/elf.h
+++ b/arch/mips/include/asm/elf.h
@@ -402,7 +402,8 @@ extern const char *__elf_platform;
     that it will "exec", and that there is sufficient room for the brk.	*/

  #ifndef ELF_ET_DYN_BASE
-#define ELF_ET_DYN_BASE		(TASK_SIZE / 3 * 2)
+extern unsigned long randomize_et_dyn(unsigned long base);
+#define ELF_ET_DYN_BASE		(randomize_et_dyn(TASK_SIZE / 3 * 2))
  #endif

  #define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
diff --git a/arch/mips/mm/mmap.c b/arch/mips/mm/mmap.c
index f1baadd..20ad644 100644
--- a/arch/mips/mm/mmap.c
+++ b/arch/mips/mm/mmap.c
@@ -196,3 +196,13 @@ int __virt_addr_valid(const volatile void *kaddr)
  	return pfn_valid(PFN_DOWN(virt_to_phys(kaddr)));
  }
  EXPORT_SYMBOL_GPL(__virt_addr_valid);
+
+unsigned long randomize_et_dyn(unsigned long base)
+{
+	unsigned long ret;
+	if ((current->personality & ADDR_NO_RANDOMIZE) ||
+		!(current->flags & PF_RANDOMIZE))
+		return base;
+	ret = base + brk_rnd();
+	return (ret > base) ? ret : base;
+}
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index a2a168e..fa4c877 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -88,7 +88,6 @@ config PPC
  	select ARCH_MIGHT_HAVE_PC_PARPORT
  	select ARCH_MIGHT_HAVE_PC_SERIO
  	select BINFMT_ELF
-	select ARCH_BINFMT_ELF_RANDOMIZE_PIE
  	select OF
  	select OF_EARLY_FLATTREE
  	select OF_RESERVED_MEM
diff --git a/arch/powerpc/include/asm/elf.h b/arch/powerpc/include/asm/elf.h
index 57d289a..4080425 100644
--- a/arch/powerpc/include/asm/elf.h
+++ b/arch/powerpc/include/asm/elf.h
@@ -28,7 +28,8 @@
     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
+extern unsigned long randomize_et_dyn(unsigned long base);
+#define ELF_ET_DYN_BASE	(randomize_et_dyn(0x20000000))

  #define ELF_CORE_EFLAGS (is_elf2_task() ? 2 : 0)

diff --git a/arch/powerpc/mm/mmap.c b/arch/powerpc/mm/mmap.c
index cb8bdbe..3e642e7 100644
--- a/arch/powerpc/mm/mmap.c
+++ b/arch/powerpc/mm/mmap.c
@@ -97,3 +97,13 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
  		mm->get_unmapped_area = arch_get_unmapped_area_topdown;
  	}
  }
+
+unsigned long randomize_et_dyn(unsigned long base)
+{
+	unsigned long ret;
+	if ((current->personality & ADDR_NO_RANDOMIZE) ||
+		!(current->flags & PF_RANDOMIZE))
+		return base;
+	ret = base + mmap_rnd();
+	return (ret > base) ? ret : base;
+}
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index ba397bd..dcfe16c 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -85,7 +85,6 @@ config X86
  	select HAVE_CMPXCHG_DOUBLE
  	select HAVE_ARCH_KMEMCHECK
  	select HAVE_USER_RETURN_NOTIFIER
-	select ARCH_BINFMT_ELF_RANDOMIZE_PIE
  	select HAVE_ARCH_JUMP_LABEL
  	select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
  	select SPARSE_IRQ
diff --git a/arch/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h
index ca3347a..92c6ac4 100644
--- a/arch/x86/include/asm/elf.h
+++ b/arch/x86/include/asm/elf.h
@@ -249,7 +249,8 @@ extern int force_personality32;
     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)
+extern unsigned long randomize_et_dyn(unsigned long base);
+#define ELF_ET_DYN_BASE		(randomize_et_dyn(TASK_SIZE / 3 * 2))

  /* 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/arch/x86/mm/mmap.c b/arch/x86/mm/mmap.c
index 919b912..7b86605 100644
--- a/arch/x86/mm/mmap.c
+++ b/arch/x86/mm/mmap.c
@@ -122,3 +122,12 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
  		mm->get_unmapped_area = arch_get_unmapped_area_topdown;
  	}
  }
+unsigned long randomize_et_dyn(unsigned long base)
+{
+	unsigned long ret;
+	if ((current->personality & ADDR_NO_RANDOMIZE) ||
+		!(current->flags & PF_RANDOMIZE))
+		return base;
+	ret = base + mmap_rnd();
+	return (ret > base) ? ret : base;
+}
diff --git a/fs/Kconfig.binfmt b/fs/Kconfig.binfmt
index c055d56..1186190 100644
--- a/fs/Kconfig.binfmt
+++ b/fs/Kconfig.binfmt
@@ -27,8 +27,6 @@ config COMPAT_BINFMT_ELF
  	bool
  	depends on COMPAT && BINFMT_ELF

-config ARCH_BINFMT_ELF_RANDOMIZE_PIE
-	bool

  config ARCH_BINFMT_ELF_STATE
  	bool
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 02b1691..72f7ff5 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -908,21 +908,7 @@ static int load_elf_binary(struct linux_binprm *bprm)
  			 * 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.  */
-#ifdef CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE
-			/* Memory randomization might have been switched off
-			 * in runtime via sysctl or explicit setting of
-			 * personality flags.
-			 * If that is the case, retain the original non-zero
-			 * load_bias value in order to establish proper
-			 * non-randomized mappings.
-			 */
-			if (current->flags & PF_RANDOMIZE)
-				load_bias = 0;
-			else
-				load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
-#else
  			load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
-#endif
  		}

  		error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt,



Kees Cook <keescook@chromium.org> escribi?:

> (I've added some additional CCs to make sure the arch maintainers
> notice this patch.)
>
> This patch seems white-space damaged to me. I had to do a lot of
> manual editing to get it to apply. Please use "git format-patch", if
> you're not already. What version of the kernel was this based on?
>
> On Mon, Feb 23, 2015 at 10:37 AM, Hector Marco <hecmargi@upv.es> wrote:
>> [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS
>>
>> The issue appears on PIE linked executables when all memory areas of a
>> process are randomized. In this case, the attack "offset2lib" de-randomizes
>> all library areas on 64 bit Linux systems in less than one second.
>>
>>
>> Further details of the PoC attack at:
>> http://cybersecurity.upv.es/attacks/offset2lib/offset2lib.html
>>
>>
>> This patch loads the PIE linked executable in a different area than the
>> libraries. The successful fix can be tested with a simple pie compiled
>> application:
>>
>>
>> $ ./show_mmaps_pie
>> 54859ccd6000-54859ccd7000 r-xp  ...  /tmp/show_mmaps_pie
>> 54859ced6000-54859ced7000 r--p  ...  /tmp/show_mmaps_pie
>> 54859ced7000-54859ced8000 rw-p  ...  /tmp/show_mmaps_pie
>> 7f75be764000-7f75be91f000 r-xp  ...  /lib/x86_64-linux-gnu/libc.so.6
>> 7f75be91f000-7f75beb1f000 ---p  ...  /lib/x86_64-linux-gnu/libc.so.6
>> 7f75beb1f000-7f75beb23000 r--p  ...  /lib/x86_64-linux-gnu/libc.so.6
>> 7f75beb23000-7f75beb25000 rw-p  ...  /lib/x86_64-linux-gnu/libc.so.6
>> 7f75beb25000-7f75beb2a000 rw-p  ...
>> 7f75beb2a000-7f75beb4d000 r-xp  ...  /lib64/ld-linux-x86-64.so.2
>> 7f75bed45000-7f75bed46000 rw-p  ...
>> 7f75bed46000-7f75bed47000 r-xp  ...
>> 7f75bed47000-7f75bed4c000 rw-p  ...
>> 7f75bed4c000-7f75bed4d000 r--p  ...  /lib64/ld-linux-x86-64.so.2
>> 7f75bed4d000-7f75bed4e000 rw-p  ...  /lib64/ld-linux-x86-64.so.2
>> 7f75bed4e000-7f75bed4f000 rw-p  ...
>> 7fffb3741000-7fffb3762000 rw-p  ...  [stack]
>> 7fffb377b000-7fffb377d000 r--p  ...  [vvar]
>> 7fffb377d000-7fffb377f000 r-xp  ...  [vdso]
>>
>>
>> Once corrected, the PIE linked application is loaded in a different area.
>
> Thanks for working on this!
>
>>
>> We updated the "Fixing Offset2lib weakness" page:
>> http://cybersecurity.upv.es/solutions/aslrv2/aslrv2.html
>>
>>
>> Signed-off-by: Hector Marco-Gisbert <hecmargi@upv.es>
>> Signed-off-by: Ismael Ripoll <iripoll@upv.es>
>
> Acked-by: Kees Cook <keescook@chromium.org>
>
>>
>>
>> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
>> index 97d07ed..ee7ea7e 100644
>> --- a/arch/arm/Kconfig
>> +++ b/arch/arm/Kconfig
>> @@ -1,7 +1,6 @@
>>  config ARM
>>         bool
>>         default y
>> -       select ARCH_BINFMT_ELF_RANDOMIZE_PIE
>>         select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
>>         select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
>>         select ARCH_HAVE_CUSTOM_GPIO_H
>> diff --git a/arch/arm/include/asm/elf.h b/arch/arm/include/asm/elf.h
>> index afb9caf..6755cd8 100644
>> --- a/arch/arm/include/asm/elf.h
>> +++ b/arch/arm/include/asm/elf.h
>> @@ -115,7 +115,8 @@ int dump_task_regs(struct task_struct *t, elf_gregset_t
>> *elfregs);
>>     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        (2 * TASK_SIZE / 3)
>> +extern unsigned long randomize_et_dyn(unsigned long base);
>> +#define ELF_ET_DYN_BASE        (randomize_et_dyn(2 * TASK_SIZE / 3))
>>
>>  /* 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
>> diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c
>> index 5e85ed3..9177100 100644
>> --- a/arch/arm/mm/mmap.c
>> +++ b/arch/arm/mm/mmap.c
>> @@ -30,6 +30,17 @@ static int mmap_is_legacy(void)
>>         return sysctl_legacy_va_layout;
>>  }
>>
>> +static unsigned long mmap_rnd(void)
>> +{
>> +       unsigned long rnd = 0;
>> +
>> +       /* 8 bits of randomness in 20 address space bits */
>> +       if (current->flags & PF_RANDOMIZE)
>> +               rnd = (long)get_random_int() % (1 << 8);
>> +
>> +       return rnd << PAGE_SHIFT;
>> +}
>> +
>>  static unsigned long mmap_base(unsigned long rnd)
>>  {
>>         unsigned long gap = rlimit(RLIMIT_STACK);
>> @@ -230,3 +241,13 @@ int devmem_is_allowed(unsigned long pfn)
>>  }
>>
>>  #endif
>> +
>> +unsigned long randomize_et_dyn(unsigned long base)
>> +{
>> +       unsigned long ret;
>> +       if ((current->personality & ADDR_NO_RANDOMIZE) ||
>> +               !(current->flags & PF_RANDOMIZE))
>> +               return base;
>> +       ret = base + mmap_rnd();
>> +       return (ret > base) ? ret : base;
>> +}
>> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
>> index b1f9a20..5580d90 100644
>> --- a/arch/arm64/Kconfig
>> +++ b/arch/arm64/Kconfig
>> @@ -1,6 +1,5 @@
>>  config ARM64
>>         def_bool y
>> -       select ARCH_BINFMT_ELF_RANDOMIZE_PIE
>>         select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
>>         select ARCH_HAS_GCOV_PROFILE_ALL
>>         select ARCH_HAS_SG_CHAIN
>> diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
>> index 1f65be3..01d3aab 100644
>> --- a/arch/arm64/include/asm/elf.h
>> +++ b/arch/arm64/include/asm/elf.h
>> @@ -126,7 +126,7 @@ typedef struct user_fpsimd_state elf_fpregset_t;
>>   * that it will "exec", and that there is sufficient room for the brk.
>>   */
>>  extern unsigned long randomize_et_dyn(unsigned long base);
>> -#define ELF_ET_DYN_BASE        (2 * TASK_SIZE_64 / 3)
>> +#define ELF_ET_DYN_BASE        (randomize_et_dyn(2 * TASK_SIZE_64 / 3))
>>
>>  /*
>>   * When the program starts, a1 contains a pointer to a function to be
>> @@ -169,7 +169,7 @@ extern unsigned long arch_randomize_brk(struct mm_struct
>> *mm);
>>  #define COMPAT_ELF_PLATFORM            ("v8l")
>>  #endif
>>
>> -#define COMPAT_ELF_ET_DYN_BASE         (2 * TASK_SIZE_32 / 3)
>> +#define COMPAT_ELF_ET_DYN_BASE         (randomize_et_dyn(2 * TASK_SIZE_32 /
>> 3))
>>
>>  /* AArch32 registers. */
>>  #define COMPAT_ELF_NGREG               18
>> diff --git a/arch/arm64/mm/mmap.c b/arch/arm64/mm/mmap.c
>> index 54922d1..980110c50 100644
>> --- a/arch/arm64/mm/mmap.c
>> +++ b/arch/arm64/mm/mmap.c
>> @@ -89,6 +89,16 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
>>  }
>>  EXPORT_SYMBOL_GPL(arch_pick_mmap_layout);
>>
>> +unsigned long randomize_et_dyn(unsigned long base)
>> +{
>> +       unsigned long ret;
>> +       if ((current->personality & ADDR_NO_RANDOMIZE) ||
>> +               !(current->flags & PF_RANDOMIZE))
>> +               return base;
>> +       ret = base + mmap_rnd();
>> +       return (ret > base) ? ret : base;
>> +}
>> +
>>
>>  /*
>>   * You really shouldn't be using read() or write() on /dev/mem.  This might
>> go
>> diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
>> index 3289969..31cc248 100644
>> --- a/arch/mips/Kconfig
>> +++ b/arch/mips/Kconfig
>> @@ -23,7 +23,6 @@ config MIPS
>>         select HAVE_KRETPROBES
>>         select HAVE_DEBUG_KMEMLEAK
>>         select HAVE_SYSCALL_TRACEPOINTS
>> -       select ARCH_BINFMT_ELF_RANDOMIZE_PIE
>>         select HAVE_ARCH_TRANSPARENT_HUGEPAGE if CPU_SUPPORTS_HUGEPAGES &&
>> 64BIT
>>         select RTC_LIB if !MACH_LOONGSON
>>         select GENERIC_ATOMIC64 if !64BIT
>> diff --git a/arch/mips/include/asm/elf.h b/arch/mips/include/asm/elf.h
>> index eb4d95d..fcac4c99 100644
>> --- a/arch/mips/include/asm/elf.h
>> +++ b/arch/mips/include/asm/elf.h
>> @@ -402,7 +402,8 @@ extern const char *__elf_platform;
>>     that it will "exec", and that there is sufficient room for the brk. */
>>
>>  #ifndef ELF_ET_DYN_BASE
>> -#define ELF_ET_DYN_BASE                (TASK_SIZE / 3 * 2)
>> +extern unsigned long randomize_et_dyn(unsigned long base);
>> +#define ELF_ET_DYN_BASE                (randomize_et_dyn(TASK_SIZE / 3 *
>> 2))
>>  #endif
>>
>>  #define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
>> diff --git a/arch/mips/mm/mmap.c b/arch/mips/mm/mmap.c
>> index f1baadd..20ad644 100644
>> --- a/arch/mips/mm/mmap.c
>> +++ b/arch/mips/mm/mmap.c
>> @@ -196,3 +196,13 @@ int __virt_addr_valid(const volatile void *kaddr)
>>         return pfn_valid(PFN_DOWN(virt_to_phys(kaddr)));
>>  }
>>  EXPORT_SYMBOL_GPL(__virt_addr_valid);
>> +
>> +unsigned long randomize_et_dyn(unsigned long base)
>> +{
>> +       unsigned long ret;
>> +       if ((current->personality & ADDR_NO_RANDOMIZE) ||
>> +               !(current->flags & PF_RANDOMIZE))
>> +               return base;
>> +       ret = base + brk_rnd();
>> +       return (ret > base) ? ret : base;
>> +}
>> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
>> index a2a168e..fa4c877 100644
>> --- a/arch/powerpc/Kconfig
>> +++ b/arch/powerpc/Kconfig
>> @@ -88,7 +88,6 @@ config PPC
>>         select ARCH_MIGHT_HAVE_PC_PARPORT
>>         select ARCH_MIGHT_HAVE_PC_SERIO
>>         select BINFMT_ELF
>> -       select ARCH_BINFMT_ELF_RANDOMIZE_PIE
>>         select OF
>>         select OF_EARLY_FLATTREE
>>         select OF_RESERVED_MEM
>> diff --git a/arch/powerpc/include/asm/elf.h b/arch/powerpc/include/asm/elf.h
>> index 57d289a..4080425 100644
>> --- a/arch/powerpc/include/asm/elf.h
>> +++ b/arch/powerpc/include/asm/elf.h
>> @@ -28,7 +28,8 @@
>>     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
>> +extern unsigned long randomize_et_dyn(unsigned long base);
>> +#define ELF_ET_DYN_BASE        (randomize_et_dyn(0x20000000))
>>
>>  #define ELF_CORE_EFLAGS (is_elf2_task() ? 2 : 0)
>>
>> diff --git a/arch/powerpc/mm/mmap.c b/arch/powerpc/mm/mmap.c
>> index cb8bdbe..3e642e7 100644
>> --- a/arch/powerpc/mm/mmap.c
>> +++ b/arch/powerpc/mm/mmap.c
>> @@ -97,3 +97,13 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
>>                 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
>>         }
>>  }
>> +
>> +unsigned long randomize_et_dyn(unsigned long base)
>> +{
>> +       unsigned long ret;
>> +       if ((current->personality & ADDR_NO_RANDOMIZE) ||
>> +               !(current->flags & PF_RANDOMIZE))
>> +               return base;
>> +       ret = base + mmap_rnd();
>> +       return (ret > base) ? ret : base;
>> +}
>> diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
>> index ba397bd..dcfe16c 100644
>> --- a/arch/x86/Kconfig
>> +++ b/arch/x86/Kconfig
>> @@ -85,7 +85,6 @@ config X86
>>         select HAVE_CMPXCHG_DOUBLE
>>         select HAVE_ARCH_KMEMCHECK
>>         select HAVE_USER_RETURN_NOTIFIER
>> -       select ARCH_BINFMT_ELF_RANDOMIZE_PIE
>>         select HAVE_ARCH_JUMP_LABEL
>>         select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
>>         select SPARSE_IRQ
>> diff --git a/arch/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h
>> index ca3347a..92c6ac4 100644
>> --- a/arch/x86/include/asm/elf.h
>> +++ b/arch/x86/include/asm/elf.h
>> @@ -249,7 +249,8 @@ extern int force_personality32;
>>     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)
>> +extern unsigned long randomize_et_dyn(unsigned long base);
>> +#define ELF_ET_DYN_BASE                (randomize_et_dyn(TASK_SIZE / 3 *
>> 2))
>>
>>  /* 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/arch/x86/mm/mmap.c b/arch/x86/mm/mmap.c
>> index 919b912..7b86605 100644
>> --- a/arch/x86/mm/mmap.c
>> +++ b/arch/x86/mm/mmap.c
>> @@ -122,3 +122,12 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
>>                 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
>>         }
>>  }
>> +unsigned long randomize_et_dyn(unsigned long base)
>> +{
>> +       unsigned long ret;
>> +       if ((current->personality & ADDR_NO_RANDOMIZE) ||
>> +               !(current->flags & PF_RANDOMIZE))
>> +               return base;
>> +       ret = base + mmap_rnd();
>> +       return (ret > base) ? ret : base;
>> +}
>> diff --git a/fs/Kconfig.binfmt b/fs/Kconfig.binfmt
>> index c055d56..1186190 100644
>> --- a/fs/Kconfig.binfmt
>> +++ b/fs/Kconfig.binfmt
>> @@ -27,8 +27,6 @@ config COMPAT_BINFMT_ELF
>>         bool
>>         depends on COMPAT && BINFMT_ELF
>>
>> -config ARCH_BINFMT_ELF_RANDOMIZE_PIE
>> -       bool
>>
>>  config ARCH_BINFMT_ELF_STATE
>>         bool
>> diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
>> index 02b1691..72f7ff5 100644
>> --- a/fs/binfmt_elf.c
>> +++ b/fs/binfmt_elf.c
>> @@ -908,21 +908,7 @@ static int load_elf_binary(struct linux_binprm *bprm)
>>                          * 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.  */
>> -#ifdef CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE
>> -                       /* Memory randomization might have been switched off
>> -                        * in runtime via sysctl or explicit setting of
>> -                        * personality flags.
>> -                        * If that is the case, retain the original non-zero
>> -                        * load_bias value in order to establish proper
>> -                        * non-randomized mappings.
>> -                        */
>> -                       if (current->flags & PF_RANDOMIZE)
>> -                               load_bias = 0;
>> -                       else
>> -                               load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE -
>> vaddr);
>> -#else
>>                         load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
>> -#endif
>>                 }
>>
>>                 error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt,
>
> I think this is much cleaner now without
> ARCH_BINFMT_ELF_RANDOMIZE_PIE. I imagine there could be some follow-up
> cleanups to standardize (or at least clearly document) the intended
> levels of entropy in the 4 ASLR regions on each architecture, as it
> currently varies a bit.
>
> Thanks!
>
> -Kees
>
> --
> Kees Cook
> Chrome OS Security
>

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

* Re: [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS
@ 2015-02-24  7:39       ` Ingo Molnar
  0 siblings, 0 replies; 56+ messages in thread
From: Ingo Molnar @ 2015-02-24  7:39 UTC (permalink / raw)
  To: Hector Marco Gisbert
  Cc: Kees Cook, Andrew Morton, LKML, ismael Ripoll, x86,
	linux-arm-kernel, Linux MIPS Mailing List, linuxppc-dev


* Hector Marco Gisbert <hecmargi@upv.es> wrote:

> +unsigned long randomize_et_dyn(unsigned long base)
> +{
> +	unsigned long ret;
> +	if ((current->personality & ADDR_NO_RANDOMIZE) ||
> +		!(current->flags & PF_RANDOMIZE))
> +		return base;
> +	ret = base + mmap_rnd();
> +	return (ret > base) ? ret : base;
> +}

> +unsigned long randomize_et_dyn(unsigned long base)
> +{
> +	unsigned long ret;
> +	if ((current->personality & ADDR_NO_RANDOMIZE) ||
> +		!(current->flags & PF_RANDOMIZE))
> +		return base;
> +	ret = base + mmap_rnd();
> +	return (ret > base) ? ret : base;
> +}

> +unsigned long randomize_et_dyn(unsigned long base)
> +{
> +	unsigned long ret;
> +	if ((current->personality & ADDR_NO_RANDOMIZE) ||
> +		!(current->flags & PF_RANDOMIZE))
> +		return base;
> +	ret = base + brk_rnd();
> +	return (ret > base) ? ret : base;
> +}

> +unsigned long randomize_et_dyn(unsigned long base)
> +{
> +	unsigned long ret;
> +	if ((current->personality & ADDR_NO_RANDOMIZE) ||
> +		!(current->flags & PF_RANDOMIZE))
> +		return base;
> +	ret = base + mmap_rnd();
> +	return (ret > base) ? ret : base;
> +}

> +unsigned long randomize_et_dyn(unsigned long base)
> +{
> +	unsigned long ret;
> +	if ((current->personality & ADDR_NO_RANDOMIZE) ||
> +		!(current->flags & PF_RANDOMIZE))
> +		return base;
> +	ret = base + mmap_rnd();
> +	return (ret > base) ? ret : base;
> +}

That pointless repetition should be avoided.

Thanks,

	Ingo

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

* Re: [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS
@ 2015-02-24  7:39       ` Ingo Molnar
  0 siblings, 0 replies; 56+ messages in thread
From: Ingo Molnar @ 2015-02-24  7:39 UTC (permalink / raw)
  To: Hector Marco Gisbert
  Cc: Kees Cook, Andrew Morton, LKML, ismael Ripoll, x86,
	linux-arm-kernel, Linux MIPS Mailing List, linuxppc-dev


* Hector Marco Gisbert <hecmargi@upv.es> wrote:

> +unsigned long randomize_et_dyn(unsigned long base)
> +{
> +	unsigned long ret;
> +	if ((current->personality & ADDR_NO_RANDOMIZE) ||
> +		!(current->flags & PF_RANDOMIZE))
> +		return base;
> +	ret = base + mmap_rnd();
> +	return (ret > base) ? ret : base;
> +}

> +unsigned long randomize_et_dyn(unsigned long base)
> +{
> +	unsigned long ret;
> +	if ((current->personality & ADDR_NO_RANDOMIZE) ||
> +		!(current->flags & PF_RANDOMIZE))
> +		return base;
> +	ret = base + mmap_rnd();
> +	return (ret > base) ? ret : base;
> +}

> +unsigned long randomize_et_dyn(unsigned long base)
> +{
> +	unsigned long ret;
> +	if ((current->personality & ADDR_NO_RANDOMIZE) ||
> +		!(current->flags & PF_RANDOMIZE))
> +		return base;
> +	ret = base + brk_rnd();
> +	return (ret > base) ? ret : base;
> +}

> +unsigned long randomize_et_dyn(unsigned long base)
> +{
> +	unsigned long ret;
> +	if ((current->personality & ADDR_NO_RANDOMIZE) ||
> +		!(current->flags & PF_RANDOMIZE))
> +		return base;
> +	ret = base + mmap_rnd();
> +	return (ret > base) ? ret : base;
> +}

> +unsigned long randomize_et_dyn(unsigned long base)
> +{
> +	unsigned long ret;
> +	if ((current->personality & ADDR_NO_RANDOMIZE) ||
> +		!(current->flags & PF_RANDOMIZE))
> +		return base;
> +	ret = base + mmap_rnd();
> +	return (ret > base) ? ret : base;
> +}

That pointless repetition should be avoided.

Thanks,

	Ingo

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

* Re: [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS
@ 2015-02-24  7:39       ` Ingo Molnar
  0 siblings, 0 replies; 56+ messages in thread
From: Ingo Molnar @ 2015-02-24  7:39 UTC (permalink / raw)
  To: Hector Marco Gisbert
  Cc: Linux MIPS Mailing List, Kees Cook, x86, LKML, ismael Ripoll,
	Andrew Morton, linuxppc-dev, linux-arm-kernel


* Hector Marco Gisbert <hecmargi@upv.es> wrote:

> +unsigned long randomize_et_dyn(unsigned long base)
> +{
> +	unsigned long ret;
> +	if ((current->personality & ADDR_NO_RANDOMIZE) ||
> +		!(current->flags & PF_RANDOMIZE))
> +		return base;
> +	ret = base + mmap_rnd();
> +	return (ret > base) ? ret : base;
> +}

> +unsigned long randomize_et_dyn(unsigned long base)
> +{
> +	unsigned long ret;
> +	if ((current->personality & ADDR_NO_RANDOMIZE) ||
> +		!(current->flags & PF_RANDOMIZE))
> +		return base;
> +	ret = base + mmap_rnd();
> +	return (ret > base) ? ret : base;
> +}

> +unsigned long randomize_et_dyn(unsigned long base)
> +{
> +	unsigned long ret;
> +	if ((current->personality & ADDR_NO_RANDOMIZE) ||
> +		!(current->flags & PF_RANDOMIZE))
> +		return base;
> +	ret = base + brk_rnd();
> +	return (ret > base) ? ret : base;
> +}

> +unsigned long randomize_et_dyn(unsigned long base)
> +{
> +	unsigned long ret;
> +	if ((current->personality & ADDR_NO_RANDOMIZE) ||
> +		!(current->flags & PF_RANDOMIZE))
> +		return base;
> +	ret = base + mmap_rnd();
> +	return (ret > base) ? ret : base;
> +}

> +unsigned long randomize_et_dyn(unsigned long base)
> +{
> +	unsigned long ret;
> +	if ((current->personality & ADDR_NO_RANDOMIZE) ||
> +		!(current->flags & PF_RANDOMIZE))
> +		return base;
> +	ret = base + mmap_rnd();
> +	return (ret > base) ? ret : base;
> +}

That pointless repetition should be avoided.

Thanks,

	Ingo

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

* [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS
@ 2015-02-24  7:39       ` Ingo Molnar
  0 siblings, 0 replies; 56+ messages in thread
From: Ingo Molnar @ 2015-02-24  7:39 UTC (permalink / raw)
  To: linux-arm-kernel


* Hector Marco Gisbert <hecmargi@upv.es> wrote:

> +unsigned long randomize_et_dyn(unsigned long base)
> +{
> +	unsigned long ret;
> +	if ((current->personality & ADDR_NO_RANDOMIZE) ||
> +		!(current->flags & PF_RANDOMIZE))
> +		return base;
> +	ret = base + mmap_rnd();
> +	return (ret > base) ? ret : base;
> +}

> +unsigned long randomize_et_dyn(unsigned long base)
> +{
> +	unsigned long ret;
> +	if ((current->personality & ADDR_NO_RANDOMIZE) ||
> +		!(current->flags & PF_RANDOMIZE))
> +		return base;
> +	ret = base + mmap_rnd();
> +	return (ret > base) ? ret : base;
> +}

> +unsigned long randomize_et_dyn(unsigned long base)
> +{
> +	unsigned long ret;
> +	if ((current->personality & ADDR_NO_RANDOMIZE) ||
> +		!(current->flags & PF_RANDOMIZE))
> +		return base;
> +	ret = base + brk_rnd();
> +	return (ret > base) ? ret : base;
> +}

> +unsigned long randomize_et_dyn(unsigned long base)
> +{
> +	unsigned long ret;
> +	if ((current->personality & ADDR_NO_RANDOMIZE) ||
> +		!(current->flags & PF_RANDOMIZE))
> +		return base;
> +	ret = base + mmap_rnd();
> +	return (ret > base) ? ret : base;
> +}

> +unsigned long randomize_et_dyn(unsigned long base)
> +{
> +	unsigned long ret;
> +	if ((current->personality & ADDR_NO_RANDOMIZE) ||
> +		!(current->flags & PF_RANDOMIZE))
> +		return base;
> +	ret = base + mmap_rnd();
> +	return (ret > base) ? ret : base;
> +}

That pointless repetition should be avoided.

Thanks,

	Ingo

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

* Re: [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS
@ 2015-02-26 22:38         ` Andrew Morton
  0 siblings, 0 replies; 56+ messages in thread
From: Andrew Morton @ 2015-02-26 22:38 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Hector Marco Gisbert, Kees Cook, LKML, ismael Ripoll, x86,
	linux-arm-kernel, Linux MIPS Mailing List, linuxppc-dev

On Tue, 24 Feb 2015 08:39:06 +0100 Ingo Molnar <mingo@kernel.org> wrote:

> 
> * Hector Marco Gisbert <hecmargi@upv.es> wrote:
> 
> > +unsigned long randomize_et_dyn(unsigned long base)
> > +{
> > +	unsigned long ret;
> > +	if ((current->personality & ADDR_NO_RANDOMIZE) ||
> > +		!(current->flags & PF_RANDOMIZE))
> > +		return base;
> > +	ret = base + mmap_rnd();
> > +	return (ret > base) ? ret : base;
> > +}
> 
> > +unsigned long randomize_et_dyn(unsigned long base)
> > +{
> > +	unsigned long ret;
> > +	if ((current->personality & ADDR_NO_RANDOMIZE) ||
> > +		!(current->flags & PF_RANDOMIZE))
> > +		return base;
> > +	ret = base + mmap_rnd();
> > +	return (ret > base) ? ret : base;
> > +}
> 
> > +unsigned long randomize_et_dyn(unsigned long base)
> > +{
> > +	unsigned long ret;
> > +	if ((current->personality & ADDR_NO_RANDOMIZE) ||
> > +		!(current->flags & PF_RANDOMIZE))
> > +		return base;
> > +	ret = base + brk_rnd();
> > +	return (ret > base) ? ret : base;
> > +}
> 
> > +unsigned long randomize_et_dyn(unsigned long base)
> > +{
> > +	unsigned long ret;
> > +	if ((current->personality & ADDR_NO_RANDOMIZE) ||
> > +		!(current->flags & PF_RANDOMIZE))
> > +		return base;
> > +	ret = base + mmap_rnd();
> > +	return (ret > base) ? ret : base;
> > +}
> 
> > +unsigned long randomize_et_dyn(unsigned long base)
> > +{
> > +	unsigned long ret;
> > +	if ((current->personality & ADDR_NO_RANDOMIZE) ||
> > +		!(current->flags & PF_RANDOMIZE))
> > +		return base;
> > +	ret = base + mmap_rnd();
> > +	return (ret > base) ? ret : base;
> > +}
> 
> That pointless repetition should be avoided.

That's surprisingly hard!

After renaming mips brk_rnd() to mmap_rnd() I had a shot.  I'm not very
confident in the result.  Does that __weak trick even work?

Someone tell me how important Hector's patch is?


From: Andrew Morton <akpm@linux-foundation.org>
Subject: fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix

Consolidate randomize_et_dyn() implementations into fs/binfmt_elf.c.

There doesn't seem to be a compile-time way of making randomize_et_dyn()
go away on architectures which don't need it, so mark it __weak to cause
it to be discarded at link time.

Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Hector Marco Gisbert <hecmargi@upv.es>
Cc: Hector Marco-Gisbert <hecmargi@upv.es>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Ismael Ripoll <iripoll@upv.es>
Cc: Kees Cook <keescook@chromium.org>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Russell King <rmk@arm.linux.org.uk>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Will Deacon <will.deacon@arm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---

 arch/arm/include/asm/elf.h        |    3 +--
 arch/arm/mm/mmap.c                |   13 ++-----------
 arch/arm64/Kconfig                |    2 +-
 arch/arm64/include/asm/elf.h      |    3 +--
 arch/arm64/mm/mmap.c              |   14 ++------------
 arch/mips/include/asm/elf.h       |    1 -
 arch/mips/mm/mmap.c               |   13 ++-----------
 arch/powerpc/include/asm/elf.h    |    2 --
 arch/powerpc/mm/mmap.c            |   13 ++-----------
 arch/x86/include/asm/elf.h        |    2 --
 arch/x86/mm/mmap.c                |   12 ++----------
 fs/binfmt_elf.c                   |   21 +++++++++++++++++++++
 include/linux/elf-randomization.h |    7 +++++++
 13 files changed, 41 insertions(+), 65 deletions(-)

diff -puN arch/arm/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/arm/Kconfig
diff -puN arch/arm/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/arm/include/asm/elf.h
--- a/arch/arm/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
+++ a/arch/arm/include/asm/elf.h
@@ -2,7 +2,7 @@
 #define __ASMARM_ELF_H
 
 #include <asm/hwcap.h>
-
+#include <linux/elf-randomization.h>
 /*
  * ELF register definitions..
  */
@@ -115,7 +115,6 @@ int dump_task_regs(struct task_struct *t
    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.  */
 
-extern unsigned long randomize_et_dyn(unsigned long base);
 #define ELF_ET_DYN_BASE	(randomize_et_dyn(2 * TASK_SIZE / 3))
 
 /* When the program starts, a1 contains a pointer to a function to be 
diff -puN arch/arm/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/arm/mm/mmap.c
--- a/arch/arm/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
+++ a/arch/arm/mm/mmap.c
@@ -7,6 +7,7 @@
 #include <linux/shm.h>
 #include <linux/sched.h>
 #include <linux/io.h>
+#include <linux/elf-randomization.h>
 #include <linux/personality.h>
 #include <linux/random.h>
 #include <asm/cachetype.h>
@@ -30,7 +31,7 @@ static int mmap_is_legacy(void)
 	return sysctl_legacy_va_layout;
 }
 
-static unsigned long mmap_rnd(void)
+unsigned long mmap_rnd(void)
 {
 	unsigned long rnd = 0;
 
@@ -241,13 +242,3 @@ int devmem_is_allowed(unsigned long pfn)
 }
 
 #endif
-
-unsigned long randomize_et_dyn(unsigned long base)
-{
-	unsigned long ret;
-	if ((current->personality & ADDR_NO_RANDOMIZE) ||
-		!(current->flags & PF_RANDOMIZE))
-		return base;
-	ret = base + mmap_rnd();
-	return (ret > base) ? ret : base;
-}
diff -puN arch/arm64/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/arm64/Kconfig
--- a/arch/arm64/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
+++ a/arch/arm64/Kconfig
@@ -1,4 +1,4 @@
-config ARM64
+qconfig ARM64
 	def_bool y
 	select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
 	select ARCH_HAS_GCOV_PROFILE_ALL
diff -puN arch/arm64/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/arm64/include/asm/elf.h
--- a/arch/arm64/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
+++ a/arch/arm64/include/asm/elf.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 ARM Ltd.
+ * Copyright (C) 20q12 ARM Ltd.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -125,7 +125,6 @@ typedef struct user_fpsimd_state elf_fpr
  * 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.
  */
-extern unsigned long randomize_et_dyn(unsigned long base);
 #define ELF_ET_DYN_BASE	(randomize_et_dyn(2 * TASK_SIZE_64 / 3))
 
 /*
diff -puN arch/arm64/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/arm64/mm/mmap.c
--- a/arch/arm64/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
+++ a/arch/arm64/mm/mmap.c
@@ -17,6 +17,7 @@
  */
 
 #include <linux/elf.h>
+#include <linux/elf-randomization.h>
 #include <linux/fs.h>
 #include <linux/mm.h>
 #include <linux/mman.h>
@@ -47,7 +48,7 @@ static int mmap_is_legacy(void)
 	return sysctl_legacy_va_layout;
 }
 
-static unsigned long mmap_rnd(void)
+unsigned long mmap_rnd(void)
 {
 	unsigned long rnd = 0;
 
@@ -89,17 +90,6 @@ void arch_pick_mmap_layout(struct mm_str
 }
 EXPORT_SYMBOL_GPL(arch_pick_mmap_layout);
 
-unsigned long randomize_et_dyn(unsigned long base)
-{
-	unsigned long ret;
-	if ((current->personality & ADDR_NO_RANDOMIZE) ||
-		!(current->flags & PF_RANDOMIZE))
-		return base;
-	ret = base + mmap_rnd();
-	return (ret > base) ? ret : base;
-}
-
-
 /*
  * You really shouldn't be using read() or write() on /dev/mem.  This might go
  * away in the future.
diff -puN arch/mips/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/mips/Kconfig
diff -puN arch/mips/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/mips/include/asm/elf.h
--- a/arch/mips/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
+++ a/arch/mips/include/asm/elf.h
@@ -402,7 +402,6 @@ extern const char *__elf_platform;
    that it will "exec", and that there is sufficient room for the brk.	*/
 
 #ifndef ELF_ET_DYN_BASE
-extern unsigned long randomize_et_dyn(unsigned long base);
 #define ELF_ET_DYN_BASE		(randomize_et_dyn(TASK_SIZE / 3 * 2))
 #endif
 
diff -puN arch/mips/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/mips/mm/mmap.c
--- a/arch/mips/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
+++ a/arch/mips/mm/mmap.c
@@ -9,6 +9,7 @@
 #include <linux/compiler.h>
 #include <linux/errno.h>
 #include <linux/mm.h>
+#include <linux/elf-randomization.h>
 #include <linux/mman.h>
 #include <linux/module.h>
 #include <linux/personality.h>
@@ -164,7 +165,7 @@ void arch_pick_mmap_layout(struct mm_str
 	}
 }
 
-static inline unsigned long mmap_rnd(void)
+unsigned long mmap_rnd(void)
 {
 	unsigned long rnd = get_random_int();
 
@@ -196,13 +197,3 @@ int __virt_addr_valid(const volatile voi
 	return pfn_valid(PFN_DOWN(virt_to_phys(kaddr)));
 }
 EXPORT_SYMBOL_GPL(__virt_addr_valid);
-
-unsigned long randomize_et_dyn(unsigned long base)
-{
-	unsigned long ret;
-	if ((current->personality & ADDR_NO_RANDOMIZE) ||
-		!(current->flags & PF_RANDOMIZE))
-		return base;
-	ret = base + brk_rnd();
-	return (ret > base) ? ret : base;
-}
diff -puN arch/powerpc/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/powerpc/Kconfig
diff -puN arch/powerpc/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/powerpc/include/asm/elf.h
--- a/arch/powerpc/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
+++ a/arch/powerpc/include/asm/elf.h
@@ -27,8 +27,6 @@
    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.  */
-
-extern unsigned long randomize_et_dyn(unsigned long base);
 #define ELF_ET_DYN_BASE	(randomize_et_dyn(0x20000000))
 
 #define ELF_CORE_EFLAGS (is_elf2_task() ? 2 : 0)
diff -puN arch/powerpc/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/powerpc/mm/mmap.c
--- a/arch/powerpc/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
+++ a/arch/powerpc/mm/mmap.c
@@ -24,6 +24,7 @@
 
 #include <linux/personality.h>
 #include <linux/mm.h>
+#include <linux/elf-randomization.h>
 #include <linux/random.h>
 #include <linux/sched.h>
 
@@ -53,7 +54,7 @@ static inline int mmap_is_legacy(void)
 	return sysctl_legacy_va_layout;
 }
 
-static unsigned long mmap_rnd(void)
+unsigned long mmap_rnd(void)
 {
 	unsigned long rnd = 0;
 
@@ -97,13 +98,3 @@ void arch_pick_mmap_layout(struct mm_str
 		mm->get_unmapped_area = arch_get_unmapped_area_topdown;
 	}
 }
-
-unsigned long randomize_et_dyn(unsigned long base)
-{
-	unsigned long ret;
-	if ((current->personality & ADDR_NO_RANDOMIZE) ||
-		!(current->flags & PF_RANDOMIZE))
-		return base;
-	ret = base + mmap_rnd();
-	return (ret > base) ? ret : base;
-}
diff -puN arch/x86/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/x86/Kconfig
diff -puN arch/x86/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/x86/include/asm/elf.h
--- a/arch/x86/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
+++ a/arch/x86/include/asm/elf.h
@@ -248,8 +248,6 @@ extern int force_personality32;
    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.  */
-
-extern unsigned long randomize_et_dyn(unsigned long base);
 #define ELF_ET_DYN_BASE		(randomize_et_dyn(TASK_SIZE / 3 * 2))
 
 /* This yields a mask that user programs can use to figure out what
diff -puN arch/x86/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/x86/mm/mmap.c
--- a/arch/x86/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
+++ a/arch/x86/mm/mmap.c
@@ -29,6 +29,7 @@
 #include <linux/random.h>
 #include <linux/limits.h>
 #include <linux/sched.h>
+#include <linux/elf-randomization.h>
 #include <asm/elf.h>
 
 struct va_alignment __read_mostly va_align = {
@@ -65,7 +66,7 @@ static int mmap_is_legacy(void)
 	return sysctl_legacy_va_layout;
 }
 
-static unsigned long mmap_rnd(void)
+unsigned long mmap_rnd(void)
 {
 	unsigned long rnd = 0;
 
@@ -122,12 +123,3 @@ void arch_pick_mmap_layout(struct mm_str
 		mm->get_unmapped_area = arch_get_unmapped_area_topdown;
 	}
 }
-unsigned long randomize_et_dyn(unsigned long base)
-{
-	unsigned long ret;
-	if ((current->personality & ADDR_NO_RANDOMIZE) ||
-		!(current->flags & PF_RANDOMIZE))
-		return base;
-	ret = base + mmap_rnd();
-	return (ret > base) ? ret : base;
-}
diff -puN fs/Kconfig.binfmt~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix fs/Kconfig.binfmt
diff -puN fs/binfmt_elf.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix fs/binfmt_elf.c
--- a/fs/binfmt_elf.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
+++ a/fs/binfmt_elf.c
@@ -22,6 +22,7 @@
 #include <linux/slab.h>
 #include <linux/personality.h>
 #include <linux/elfcore.h>
+#include <linux/elf-randomization.h>
 #include <linux/init.h>
 #include <linux/highuid.h>
 #include <linux/compiler.h>
@@ -2300,6 +2301,26 @@ out:
 
 #endif		/* CONFIG_ELF_CORE */
 
+/* Not all architectures implement mmap_rnd() */
+unsigned long __weak mmap_rnd(void)
+{
+}
+
+/*
+ * Not all architectures use randomize_et_dyn(), so use __weak to let the
+ * linker omit it from vmlinux
+ */
+unsigned long __weak randomize_et_dyn(unsigned long base)
+{
+	unsigned long ret;
+
+	if ((current->personality & ADDR_NO_RANDOMIZE) ||
+		!(current->flags & PF_RANDOMIZE))
+		return base;
+	ret = base + mmap_rnd();
+	return max(ret, base);
+}
+
 static int __init init_elf_binfmt(void)
 {
 	register_binfmt(&elf_format);
diff -puN include/linux/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix include/linux/elf.h
diff -puN /dev/null include/linux/elf-randomization.h
--- /dev/null
+++ a/include/linux/elf-randomization.h
@@ -0,0 +1,7 @@
+#ifndef __ELF_RANDOMIZATION_H
+#define __ELF_RANDOMIZATION_H
+
+unsigned long randomize_et_dyn(unsigned long base);
+unsigned long mmap_rnd(void);
+
+#endif	/* __ELF_RANDOMIZATION_H */
_


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

* Re: [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS
@ 2015-02-26 22:38         ` Andrew Morton
  0 siblings, 0 replies; 56+ messages in thread
From: Andrew Morton @ 2015-02-26 22:38 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Hector Marco Gisbert, Kees Cook, LKML, ismael Ripoll, x86,
	linux-arm-kernel, Linux MIPS Mailing List, linuxppc-dev

On Tue, 24 Feb 2015 08:39:06 +0100 Ingo Molnar <mingo@kernel.org> wrote:

> 
> * Hector Marco Gisbert <hecmargi@upv.es> wrote:
> 
> > +unsigned long randomize_et_dyn(unsigned long base)
> > +{
> > +	unsigned long ret;
> > +	if ((current->personality & ADDR_NO_RANDOMIZE) ||
> > +		!(current->flags & PF_RANDOMIZE))
> > +		return base;
> > +	ret = base + mmap_rnd();
> > +	return (ret > base) ? ret : base;
> > +}
> 
> > +unsigned long randomize_et_dyn(unsigned long base)
> > +{
> > +	unsigned long ret;
> > +	if ((current->personality & ADDR_NO_RANDOMIZE) ||
> > +		!(current->flags & PF_RANDOMIZE))
> > +		return base;
> > +	ret = base + mmap_rnd();
> > +	return (ret > base) ? ret : base;
> > +}
> 
> > +unsigned long randomize_et_dyn(unsigned long base)
> > +{
> > +	unsigned long ret;
> > +	if ((current->personality & ADDR_NO_RANDOMIZE) ||
> > +		!(current->flags & PF_RANDOMIZE))
> > +		return base;
> > +	ret = base + brk_rnd();
> > +	return (ret > base) ? ret : base;
> > +}
> 
> > +unsigned long randomize_et_dyn(unsigned long base)
> > +{
> > +	unsigned long ret;
> > +	if ((current->personality & ADDR_NO_RANDOMIZE) ||
> > +		!(current->flags & PF_RANDOMIZE))
> > +		return base;
> > +	ret = base + mmap_rnd();
> > +	return (ret > base) ? ret : base;
> > +}
> 
> > +unsigned long randomize_et_dyn(unsigned long base)
> > +{
> > +	unsigned long ret;
> > +	if ((current->personality & ADDR_NO_RANDOMIZE) ||
> > +		!(current->flags & PF_RANDOMIZE))
> > +		return base;
> > +	ret = base + mmap_rnd();
> > +	return (ret > base) ? ret : base;
> > +}
> 
> That pointless repetition should be avoided.

That's surprisingly hard!

After renaming mips brk_rnd() to mmap_rnd() I had a shot.  I'm not very
confident in the result.  Does that __weak trick even work?

Someone tell me how important Hector's patch is?


From: Andrew Morton <akpm@linux-foundation.org>
Subject: fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix

Consolidate randomize_et_dyn() implementations into fs/binfmt_elf.c.

There doesn't seem to be a compile-time way of making randomize_et_dyn()
go away on architectures which don't need it, so mark it __weak to cause
it to be discarded at link time.

Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Hector Marco Gisbert <hecmargi@upv.es>
Cc: Hector Marco-Gisbert <hecmargi@upv.es>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Ismael Ripoll <iripoll@upv.es>
Cc: Kees Cook <keescook@chromium.org>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Russell King <rmk@arm.linux.org.uk>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Will Deacon <will.deacon@arm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---

 arch/arm/include/asm/elf.h        |    3 +--
 arch/arm/mm/mmap.c                |   13 ++-----------
 arch/arm64/Kconfig                |    2 +-
 arch/arm64/include/asm/elf.h      |    3 +--
 arch/arm64/mm/mmap.c              |   14 ++------------
 arch/mips/include/asm/elf.h       |    1 -
 arch/mips/mm/mmap.c               |   13 ++-----------
 arch/powerpc/include/asm/elf.h    |    2 --
 arch/powerpc/mm/mmap.c            |   13 ++-----------
 arch/x86/include/asm/elf.h        |    2 --
 arch/x86/mm/mmap.c                |   12 ++----------
 fs/binfmt_elf.c                   |   21 +++++++++++++++++++++
 include/linux/elf-randomization.h |    7 +++++++
 13 files changed, 41 insertions(+), 65 deletions(-)

diff -puN arch/arm/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/arm/Kconfig
diff -puN arch/arm/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/arm/include/asm/elf.h
--- a/arch/arm/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
+++ a/arch/arm/include/asm/elf.h
@@ -2,7 +2,7 @@
 #define __ASMARM_ELF_H
 
 #include <asm/hwcap.h>
-
+#include <linux/elf-randomization.h>
 /*
  * ELF register definitions..
  */
@@ -115,7 +115,6 @@ int dump_task_regs(struct task_struct *t
    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.  */
 
-extern unsigned long randomize_et_dyn(unsigned long base);
 #define ELF_ET_DYN_BASE	(randomize_et_dyn(2 * TASK_SIZE / 3))
 
 /* When the program starts, a1 contains a pointer to a function to be 
diff -puN arch/arm/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/arm/mm/mmap.c
--- a/arch/arm/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
+++ a/arch/arm/mm/mmap.c
@@ -7,6 +7,7 @@
 #include <linux/shm.h>
 #include <linux/sched.h>
 #include <linux/io.h>
+#include <linux/elf-randomization.h>
 #include <linux/personality.h>
 #include <linux/random.h>
 #include <asm/cachetype.h>
@@ -30,7 +31,7 @@ static int mmap_is_legacy(void)
 	return sysctl_legacy_va_layout;
 }
 
-static unsigned long mmap_rnd(void)
+unsigned long mmap_rnd(void)
 {
 	unsigned long rnd = 0;
 
@@ -241,13 +242,3 @@ int devmem_is_allowed(unsigned long pfn)
 }
 
 #endif
-
-unsigned long randomize_et_dyn(unsigned long base)
-{
-	unsigned long ret;
-	if ((current->personality & ADDR_NO_RANDOMIZE) ||
-		!(current->flags & PF_RANDOMIZE))
-		return base;
-	ret = base + mmap_rnd();
-	return (ret > base) ? ret : base;
-}
diff -puN arch/arm64/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/arm64/Kconfig
--- a/arch/arm64/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
+++ a/arch/arm64/Kconfig
@@ -1,4 +1,4 @@
-config ARM64
+qconfig ARM64
 	def_bool y
 	select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
 	select ARCH_HAS_GCOV_PROFILE_ALL
diff -puN arch/arm64/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/arm64/include/asm/elf.h
--- a/arch/arm64/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
+++ a/arch/arm64/include/asm/elf.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 ARM Ltd.
+ * Copyright (C) 20q12 ARM Ltd.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -125,7 +125,6 @@ typedef struct user_fpsimd_state elf_fpr
  * 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.
  */
-extern unsigned long randomize_et_dyn(unsigned long base);
 #define ELF_ET_DYN_BASE	(randomize_et_dyn(2 * TASK_SIZE_64 / 3))
 
 /*
diff -puN arch/arm64/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/arm64/mm/mmap.c
--- a/arch/arm64/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
+++ a/arch/arm64/mm/mmap.c
@@ -17,6 +17,7 @@
  */
 
 #include <linux/elf.h>
+#include <linux/elf-randomization.h>
 #include <linux/fs.h>
 #include <linux/mm.h>
 #include <linux/mman.h>
@@ -47,7 +48,7 @@ static int mmap_is_legacy(void)
 	return sysctl_legacy_va_layout;
 }
 
-static unsigned long mmap_rnd(void)
+unsigned long mmap_rnd(void)
 {
 	unsigned long rnd = 0;
 
@@ -89,17 +90,6 @@ void arch_pick_mmap_layout(struct mm_str
 }
 EXPORT_SYMBOL_GPL(arch_pick_mmap_layout);
 
-unsigned long randomize_et_dyn(unsigned long base)
-{
-	unsigned long ret;
-	if ((current->personality & ADDR_NO_RANDOMIZE) ||
-		!(current->flags & PF_RANDOMIZE))
-		return base;
-	ret = base + mmap_rnd();
-	return (ret > base) ? ret : base;
-}
-
-
 /*
  * You really shouldn't be using read() or write() on /dev/mem.  This might go
  * away in the future.
diff -puN arch/mips/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/mips/Kconfig
diff -puN arch/mips/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/mips/include/asm/elf.h
--- a/arch/mips/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
+++ a/arch/mips/include/asm/elf.h
@@ -402,7 +402,6 @@ extern const char *__elf_platform;
    that it will "exec", and that there is sufficient room for the brk.	*/
 
 #ifndef ELF_ET_DYN_BASE
-extern unsigned long randomize_et_dyn(unsigned long base);
 #define ELF_ET_DYN_BASE		(randomize_et_dyn(TASK_SIZE / 3 * 2))
 #endif
 
diff -puN arch/mips/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/mips/mm/mmap.c
--- a/arch/mips/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
+++ a/arch/mips/mm/mmap.c
@@ -9,6 +9,7 @@
 #include <linux/compiler.h>
 #include <linux/errno.h>
 #include <linux/mm.h>
+#include <linux/elf-randomization.h>
 #include <linux/mman.h>
 #include <linux/module.h>
 #include <linux/personality.h>
@@ -164,7 +165,7 @@ void arch_pick_mmap_layout(struct mm_str
 	}
 }
 
-static inline unsigned long mmap_rnd(void)
+unsigned long mmap_rnd(void)
 {
 	unsigned long rnd = get_random_int();
 
@@ -196,13 +197,3 @@ int __virt_addr_valid(const volatile voi
 	return pfn_valid(PFN_DOWN(virt_to_phys(kaddr)));
 }
 EXPORT_SYMBOL_GPL(__virt_addr_valid);
-
-unsigned long randomize_et_dyn(unsigned long base)
-{
-	unsigned long ret;
-	if ((current->personality & ADDR_NO_RANDOMIZE) ||
-		!(current->flags & PF_RANDOMIZE))
-		return base;
-	ret = base + brk_rnd();
-	return (ret > base) ? ret : base;
-}
diff -puN arch/powerpc/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/powerpc/Kconfig
diff -puN arch/powerpc/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/powerpc/include/asm/elf.h
--- a/arch/powerpc/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
+++ a/arch/powerpc/include/asm/elf.h
@@ -27,8 +27,6 @@
    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.  */
-
-extern unsigned long randomize_et_dyn(unsigned long base);
 #define ELF_ET_DYN_BASE	(randomize_et_dyn(0x20000000))
 
 #define ELF_CORE_EFLAGS (is_elf2_task() ? 2 : 0)
diff -puN arch/powerpc/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/powerpc/mm/mmap.c
--- a/arch/powerpc/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
+++ a/arch/powerpc/mm/mmap.c
@@ -24,6 +24,7 @@
 
 #include <linux/personality.h>
 #include <linux/mm.h>
+#include <linux/elf-randomization.h>
 #include <linux/random.h>
 #include <linux/sched.h>
 
@@ -53,7 +54,7 @@ static inline int mmap_is_legacy(void)
 	return sysctl_legacy_va_layout;
 }
 
-static unsigned long mmap_rnd(void)
+unsigned long mmap_rnd(void)
 {
 	unsigned long rnd = 0;
 
@@ -97,13 +98,3 @@ void arch_pick_mmap_layout(struct mm_str
 		mm->get_unmapped_area = arch_get_unmapped_area_topdown;
 	}
 }
-
-unsigned long randomize_et_dyn(unsigned long base)
-{
-	unsigned long ret;
-	if ((current->personality & ADDR_NO_RANDOMIZE) ||
-		!(current->flags & PF_RANDOMIZE))
-		return base;
-	ret = base + mmap_rnd();
-	return (ret > base) ? ret : base;
-}
diff -puN arch/x86/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/x86/Kconfig
diff -puN arch/x86/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/x86/include/asm/elf.h
--- a/arch/x86/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
+++ a/arch/x86/include/asm/elf.h
@@ -248,8 +248,6 @@ extern int force_personality32;
    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.  */
-
-extern unsigned long randomize_et_dyn(unsigned long base);
 #define ELF_ET_DYN_BASE		(randomize_et_dyn(TASK_SIZE / 3 * 2))
 
 /* This yields a mask that user programs can use to figure out what
diff -puN arch/x86/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/x86/mm/mmap.c
--- a/arch/x86/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
+++ a/arch/x86/mm/mmap.c
@@ -29,6 +29,7 @@
 #include <linux/random.h>
 #include <linux/limits.h>
 #include <linux/sched.h>
+#include <linux/elf-randomization.h>
 #include <asm/elf.h>
 
 struct va_alignment __read_mostly va_align = {
@@ -65,7 +66,7 @@ static int mmap_is_legacy(void)
 	return sysctl_legacy_va_layout;
 }
 
-static unsigned long mmap_rnd(void)
+unsigned long mmap_rnd(void)
 {
 	unsigned long rnd = 0;
 
@@ -122,12 +123,3 @@ void arch_pick_mmap_layout(struct mm_str
 		mm->get_unmapped_area = arch_get_unmapped_area_topdown;
 	}
 }
-unsigned long randomize_et_dyn(unsigned long base)
-{
-	unsigned long ret;
-	if ((current->personality & ADDR_NO_RANDOMIZE) ||
-		!(current->flags & PF_RANDOMIZE))
-		return base;
-	ret = base + mmap_rnd();
-	return (ret > base) ? ret : base;
-}
diff -puN fs/Kconfig.binfmt~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix fs/Kconfig.binfmt
diff -puN fs/binfmt_elf.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix fs/binfmt_elf.c
--- a/fs/binfmt_elf.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
+++ a/fs/binfmt_elf.c
@@ -22,6 +22,7 @@
 #include <linux/slab.h>
 #include <linux/personality.h>
 #include <linux/elfcore.h>
+#include <linux/elf-randomization.h>
 #include <linux/init.h>
 #include <linux/highuid.h>
 #include <linux/compiler.h>
@@ -2300,6 +2301,26 @@ out:
 
 #endif		/* CONFIG_ELF_CORE */
 
+/* Not all architectures implement mmap_rnd() */
+unsigned long __weak mmap_rnd(void)
+{
+}
+
+/*
+ * Not all architectures use randomize_et_dyn(), so use __weak to let the
+ * linker omit it from vmlinux
+ */
+unsigned long __weak randomize_et_dyn(unsigned long base)
+{
+	unsigned long ret;
+
+	if ((current->personality & ADDR_NO_RANDOMIZE) ||
+		!(current->flags & PF_RANDOMIZE))
+		return base;
+	ret = base + mmap_rnd();
+	return max(ret, base);
+}
+
 static int __init init_elf_binfmt(void)
 {
 	register_binfmt(&elf_format);
diff -puN include/linux/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix include/linux/elf.h
diff -puN /dev/null include/linux/elf-randomization.h
--- /dev/null
+++ a/include/linux/elf-randomization.h
@@ -0,0 +1,7 @@
+#ifndef __ELF_RANDOMIZATION_H
+#define __ELF_RANDOMIZATION_H
+
+unsigned long randomize_et_dyn(unsigned long base);
+unsigned long mmap_rnd(void);
+
+#endif	/* __ELF_RANDOMIZATION_H */
_

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

* Re: [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS
@ 2015-02-26 22:38         ` Andrew Morton
  0 siblings, 0 replies; 56+ messages in thread
From: Andrew Morton @ 2015-02-26 22:38 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Linux MIPS Mailing List, Kees Cook, x86, Hector Marco Gisbert,
	LKML, ismael Ripoll, linuxppc-dev, linux-arm-kernel

On Tue, 24 Feb 2015 08:39:06 +0100 Ingo Molnar <mingo@kernel.org> wrote:

> 
> * Hector Marco Gisbert <hecmargi@upv.es> wrote:
> 
> > +unsigned long randomize_et_dyn(unsigned long base)
> > +{
> > +	unsigned long ret;
> > +	if ((current->personality & ADDR_NO_RANDOMIZE) ||
> > +		!(current->flags & PF_RANDOMIZE))
> > +		return base;
> > +	ret = base + mmap_rnd();
> > +	return (ret > base) ? ret : base;
> > +}
> 
> > +unsigned long randomize_et_dyn(unsigned long base)
> > +{
> > +	unsigned long ret;
> > +	if ((current->personality & ADDR_NO_RANDOMIZE) ||
> > +		!(current->flags & PF_RANDOMIZE))
> > +		return base;
> > +	ret = base + mmap_rnd();
> > +	return (ret > base) ? ret : base;
> > +}
> 
> > +unsigned long randomize_et_dyn(unsigned long base)
> > +{
> > +	unsigned long ret;
> > +	if ((current->personality & ADDR_NO_RANDOMIZE) ||
> > +		!(current->flags & PF_RANDOMIZE))
> > +		return base;
> > +	ret = base + brk_rnd();
> > +	return (ret > base) ? ret : base;
> > +}
> 
> > +unsigned long randomize_et_dyn(unsigned long base)
> > +{
> > +	unsigned long ret;
> > +	if ((current->personality & ADDR_NO_RANDOMIZE) ||
> > +		!(current->flags & PF_RANDOMIZE))
> > +		return base;
> > +	ret = base + mmap_rnd();
> > +	return (ret > base) ? ret : base;
> > +}
> 
> > +unsigned long randomize_et_dyn(unsigned long base)
> > +{
> > +	unsigned long ret;
> > +	if ((current->personality & ADDR_NO_RANDOMIZE) ||
> > +		!(current->flags & PF_RANDOMIZE))
> > +		return base;
> > +	ret = base + mmap_rnd();
> > +	return (ret > base) ? ret : base;
> > +}
> 
> That pointless repetition should be avoided.

That's surprisingly hard!

After renaming mips brk_rnd() to mmap_rnd() I had a shot.  I'm not very
confident in the result.  Does that __weak trick even work?

Someone tell me how important Hector's patch is?


From: Andrew Morton <akpm@linux-foundation.org>
Subject: fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix

Consolidate randomize_et_dyn() implementations into fs/binfmt_elf.c.

There doesn't seem to be a compile-time way of making randomize_et_dyn()
go away on architectures which don't need it, so mark it __weak to cause
it to be discarded at link time.

Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Hector Marco Gisbert <hecmargi@upv.es>
Cc: Hector Marco-Gisbert <hecmargi@upv.es>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Ismael Ripoll <iripoll@upv.es>
Cc: Kees Cook <keescook@chromium.org>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Russell King <rmk@arm.linux.org.uk>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Will Deacon <will.deacon@arm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---

 arch/arm/include/asm/elf.h        |    3 +--
 arch/arm/mm/mmap.c                |   13 ++-----------
 arch/arm64/Kconfig                |    2 +-
 arch/arm64/include/asm/elf.h      |    3 +--
 arch/arm64/mm/mmap.c              |   14 ++------------
 arch/mips/include/asm/elf.h       |    1 -
 arch/mips/mm/mmap.c               |   13 ++-----------
 arch/powerpc/include/asm/elf.h    |    2 --
 arch/powerpc/mm/mmap.c            |   13 ++-----------
 arch/x86/include/asm/elf.h        |    2 --
 arch/x86/mm/mmap.c                |   12 ++----------
 fs/binfmt_elf.c                   |   21 +++++++++++++++++++++
 include/linux/elf-randomization.h |    7 +++++++
 13 files changed, 41 insertions(+), 65 deletions(-)

diff -puN arch/arm/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/arm/Kconfig
diff -puN arch/arm/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/arm/include/asm/elf.h
--- a/arch/arm/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
+++ a/arch/arm/include/asm/elf.h
@@ -2,7 +2,7 @@
 #define __ASMARM_ELF_H
 
 #include <asm/hwcap.h>
-
+#include <linux/elf-randomization.h>
 /*
  * ELF register definitions..
  */
@@ -115,7 +115,6 @@ int dump_task_regs(struct task_struct *t
    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.  */
 
-extern unsigned long randomize_et_dyn(unsigned long base);
 #define ELF_ET_DYN_BASE	(randomize_et_dyn(2 * TASK_SIZE / 3))
 
 /* When the program starts, a1 contains a pointer to a function to be 
diff -puN arch/arm/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/arm/mm/mmap.c
--- a/arch/arm/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
+++ a/arch/arm/mm/mmap.c
@@ -7,6 +7,7 @@
 #include <linux/shm.h>
 #include <linux/sched.h>
 #include <linux/io.h>
+#include <linux/elf-randomization.h>
 #include <linux/personality.h>
 #include <linux/random.h>
 #include <asm/cachetype.h>
@@ -30,7 +31,7 @@ static int mmap_is_legacy(void)
 	return sysctl_legacy_va_layout;
 }
 
-static unsigned long mmap_rnd(void)
+unsigned long mmap_rnd(void)
 {
 	unsigned long rnd = 0;
 
@@ -241,13 +242,3 @@ int devmem_is_allowed(unsigned long pfn)
 }
 
 #endif
-
-unsigned long randomize_et_dyn(unsigned long base)
-{
-	unsigned long ret;
-	if ((current->personality & ADDR_NO_RANDOMIZE) ||
-		!(current->flags & PF_RANDOMIZE))
-		return base;
-	ret = base + mmap_rnd();
-	return (ret > base) ? ret : base;
-}
diff -puN arch/arm64/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/arm64/Kconfig
--- a/arch/arm64/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
+++ a/arch/arm64/Kconfig
@@ -1,4 +1,4 @@
-config ARM64
+qconfig ARM64
 	def_bool y
 	select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
 	select ARCH_HAS_GCOV_PROFILE_ALL
diff -puN arch/arm64/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/arm64/include/asm/elf.h
--- a/arch/arm64/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
+++ a/arch/arm64/include/asm/elf.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 ARM Ltd.
+ * Copyright (C) 20q12 ARM Ltd.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -125,7 +125,6 @@ typedef struct user_fpsimd_state elf_fpr
  * 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.
  */
-extern unsigned long randomize_et_dyn(unsigned long base);
 #define ELF_ET_DYN_BASE	(randomize_et_dyn(2 * TASK_SIZE_64 / 3))
 
 /*
diff -puN arch/arm64/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/arm64/mm/mmap.c
--- a/arch/arm64/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
+++ a/arch/arm64/mm/mmap.c
@@ -17,6 +17,7 @@
  */
 
 #include <linux/elf.h>
+#include <linux/elf-randomization.h>
 #include <linux/fs.h>
 #include <linux/mm.h>
 #include <linux/mman.h>
@@ -47,7 +48,7 @@ static int mmap_is_legacy(void)
 	return sysctl_legacy_va_layout;
 }
 
-static unsigned long mmap_rnd(void)
+unsigned long mmap_rnd(void)
 {
 	unsigned long rnd = 0;
 
@@ -89,17 +90,6 @@ void arch_pick_mmap_layout(struct mm_str
 }
 EXPORT_SYMBOL_GPL(arch_pick_mmap_layout);
 
-unsigned long randomize_et_dyn(unsigned long base)
-{
-	unsigned long ret;
-	if ((current->personality & ADDR_NO_RANDOMIZE) ||
-		!(current->flags & PF_RANDOMIZE))
-		return base;
-	ret = base + mmap_rnd();
-	return (ret > base) ? ret : base;
-}
-
-
 /*
  * You really shouldn't be using read() or write() on /dev/mem.  This might go
  * away in the future.
diff -puN arch/mips/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/mips/Kconfig
diff -puN arch/mips/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/mips/include/asm/elf.h
--- a/arch/mips/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
+++ a/arch/mips/include/asm/elf.h
@@ -402,7 +402,6 @@ extern const char *__elf_platform;
    that it will "exec", and that there is sufficient room for the brk.	*/
 
 #ifndef ELF_ET_DYN_BASE
-extern unsigned long randomize_et_dyn(unsigned long base);
 #define ELF_ET_DYN_BASE		(randomize_et_dyn(TASK_SIZE / 3 * 2))
 #endif
 
diff -puN arch/mips/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/mips/mm/mmap.c
--- a/arch/mips/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
+++ a/arch/mips/mm/mmap.c
@@ -9,6 +9,7 @@
 #include <linux/compiler.h>
 #include <linux/errno.h>
 #include <linux/mm.h>
+#include <linux/elf-randomization.h>
 #include <linux/mman.h>
 #include <linux/module.h>
 #include <linux/personality.h>
@@ -164,7 +165,7 @@ void arch_pick_mmap_layout(struct mm_str
 	}
 }
 
-static inline unsigned long mmap_rnd(void)
+unsigned long mmap_rnd(void)
 {
 	unsigned long rnd = get_random_int();
 
@@ -196,13 +197,3 @@ int __virt_addr_valid(const volatile voi
 	return pfn_valid(PFN_DOWN(virt_to_phys(kaddr)));
 }
 EXPORT_SYMBOL_GPL(__virt_addr_valid);
-
-unsigned long randomize_et_dyn(unsigned long base)
-{
-	unsigned long ret;
-	if ((current->personality & ADDR_NO_RANDOMIZE) ||
-		!(current->flags & PF_RANDOMIZE))
-		return base;
-	ret = base + brk_rnd();
-	return (ret > base) ? ret : base;
-}
diff -puN arch/powerpc/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/powerpc/Kconfig
diff -puN arch/powerpc/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/powerpc/include/asm/elf.h
--- a/arch/powerpc/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
+++ a/arch/powerpc/include/asm/elf.h
@@ -27,8 +27,6 @@
    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.  */
-
-extern unsigned long randomize_et_dyn(unsigned long base);
 #define ELF_ET_DYN_BASE	(randomize_et_dyn(0x20000000))
 
 #define ELF_CORE_EFLAGS (is_elf2_task() ? 2 : 0)
diff -puN arch/powerpc/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/powerpc/mm/mmap.c
--- a/arch/powerpc/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
+++ a/arch/powerpc/mm/mmap.c
@@ -24,6 +24,7 @@
 
 #include <linux/personality.h>
 #include <linux/mm.h>
+#include <linux/elf-randomization.h>
 #include <linux/random.h>
 #include <linux/sched.h>
 
@@ -53,7 +54,7 @@ static inline int mmap_is_legacy(void)
 	return sysctl_legacy_va_layout;
 }
 
-static unsigned long mmap_rnd(void)
+unsigned long mmap_rnd(void)
 {
 	unsigned long rnd = 0;
 
@@ -97,13 +98,3 @@ void arch_pick_mmap_layout(struct mm_str
 		mm->get_unmapped_area = arch_get_unmapped_area_topdown;
 	}
 }
-
-unsigned long randomize_et_dyn(unsigned long base)
-{
-	unsigned long ret;
-	if ((current->personality & ADDR_NO_RANDOMIZE) ||
-		!(current->flags & PF_RANDOMIZE))
-		return base;
-	ret = base + mmap_rnd();
-	return (ret > base) ? ret : base;
-}
diff -puN arch/x86/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/x86/Kconfig
diff -puN arch/x86/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/x86/include/asm/elf.h
--- a/arch/x86/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
+++ a/arch/x86/include/asm/elf.h
@@ -248,8 +248,6 @@ extern int force_personality32;
    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.  */
-
-extern unsigned long randomize_et_dyn(unsigned long base);
 #define ELF_ET_DYN_BASE		(randomize_et_dyn(TASK_SIZE / 3 * 2))
 
 /* This yields a mask that user programs can use to figure out what
diff -puN arch/x86/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/x86/mm/mmap.c
--- a/arch/x86/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
+++ a/arch/x86/mm/mmap.c
@@ -29,6 +29,7 @@
 #include <linux/random.h>
 #include <linux/limits.h>
 #include <linux/sched.h>
+#include <linux/elf-randomization.h>
 #include <asm/elf.h>
 
 struct va_alignment __read_mostly va_align = {
@@ -65,7 +66,7 @@ static int mmap_is_legacy(void)
 	return sysctl_legacy_va_layout;
 }
 
-static unsigned long mmap_rnd(void)
+unsigned long mmap_rnd(void)
 {
 	unsigned long rnd = 0;
 
@@ -122,12 +123,3 @@ void arch_pick_mmap_layout(struct mm_str
 		mm->get_unmapped_area = arch_get_unmapped_area_topdown;
 	}
 }
-unsigned long randomize_et_dyn(unsigned long base)
-{
-	unsigned long ret;
-	if ((current->personality & ADDR_NO_RANDOMIZE) ||
-		!(current->flags & PF_RANDOMIZE))
-		return base;
-	ret = base + mmap_rnd();
-	return (ret > base) ? ret : base;
-}
diff -puN fs/Kconfig.binfmt~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix fs/Kconfig.binfmt
diff -puN fs/binfmt_elf.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix fs/binfmt_elf.c
--- a/fs/binfmt_elf.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
+++ a/fs/binfmt_elf.c
@@ -22,6 +22,7 @@
 #include <linux/slab.h>
 #include <linux/personality.h>
 #include <linux/elfcore.h>
+#include <linux/elf-randomization.h>
 #include <linux/init.h>
 #include <linux/highuid.h>
 #include <linux/compiler.h>
@@ -2300,6 +2301,26 @@ out:
 
 #endif		/* CONFIG_ELF_CORE */
 
+/* Not all architectures implement mmap_rnd() */
+unsigned long __weak mmap_rnd(void)
+{
+}
+
+/*
+ * Not all architectures use randomize_et_dyn(), so use __weak to let the
+ * linker omit it from vmlinux
+ */
+unsigned long __weak randomize_et_dyn(unsigned long base)
+{
+	unsigned long ret;
+
+	if ((current->personality & ADDR_NO_RANDOMIZE) ||
+		!(current->flags & PF_RANDOMIZE))
+		return base;
+	ret = base + mmap_rnd();
+	return max(ret, base);
+}
+
 static int __init init_elf_binfmt(void)
 {
 	register_binfmt(&elf_format);
diff -puN include/linux/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix include/linux/elf.h
diff -puN /dev/null include/linux/elf-randomization.h
--- /dev/null
+++ a/include/linux/elf-randomization.h
@@ -0,0 +1,7 @@
+#ifndef __ELF_RANDOMIZATION_H
+#define __ELF_RANDOMIZATION_H
+
+unsigned long randomize_et_dyn(unsigned long base);
+unsigned long mmap_rnd(void);
+
+#endif	/* __ELF_RANDOMIZATION_H */
_

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

* [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS
@ 2015-02-26 22:38         ` Andrew Morton
  0 siblings, 0 replies; 56+ messages in thread
From: Andrew Morton @ 2015-02-26 22:38 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, 24 Feb 2015 08:39:06 +0100 Ingo Molnar <mingo@kernel.org> wrote:

> 
> * Hector Marco Gisbert <hecmargi@upv.es> wrote:
> 
> > +unsigned long randomize_et_dyn(unsigned long base)
> > +{
> > +	unsigned long ret;
> > +	if ((current->personality & ADDR_NO_RANDOMIZE) ||
> > +		!(current->flags & PF_RANDOMIZE))
> > +		return base;
> > +	ret = base + mmap_rnd();
> > +	return (ret > base) ? ret : base;
> > +}
> 
> > +unsigned long randomize_et_dyn(unsigned long base)
> > +{
> > +	unsigned long ret;
> > +	if ((current->personality & ADDR_NO_RANDOMIZE) ||
> > +		!(current->flags & PF_RANDOMIZE))
> > +		return base;
> > +	ret = base + mmap_rnd();
> > +	return (ret > base) ? ret : base;
> > +}
> 
> > +unsigned long randomize_et_dyn(unsigned long base)
> > +{
> > +	unsigned long ret;
> > +	if ((current->personality & ADDR_NO_RANDOMIZE) ||
> > +		!(current->flags & PF_RANDOMIZE))
> > +		return base;
> > +	ret = base + brk_rnd();
> > +	return (ret > base) ? ret : base;
> > +}
> 
> > +unsigned long randomize_et_dyn(unsigned long base)
> > +{
> > +	unsigned long ret;
> > +	if ((current->personality & ADDR_NO_RANDOMIZE) ||
> > +		!(current->flags & PF_RANDOMIZE))
> > +		return base;
> > +	ret = base + mmap_rnd();
> > +	return (ret > base) ? ret : base;
> > +}
> 
> > +unsigned long randomize_et_dyn(unsigned long base)
> > +{
> > +	unsigned long ret;
> > +	if ((current->personality & ADDR_NO_RANDOMIZE) ||
> > +		!(current->flags & PF_RANDOMIZE))
> > +		return base;
> > +	ret = base + mmap_rnd();
> > +	return (ret > base) ? ret : base;
> > +}
> 
> That pointless repetition should be avoided.

That's surprisingly hard!

After renaming mips brk_rnd() to mmap_rnd() I had a shot.  I'm not very
confident in the result.  Does that __weak trick even work?

Someone tell me how important Hector's patch is?


From: Andrew Morton <akpm@linux-foundation.org>
Subject: fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix

Consolidate randomize_et_dyn() implementations into fs/binfmt_elf.c.

There doesn't seem to be a compile-time way of making randomize_et_dyn()
go away on architectures which don't need it, so mark it __weak to cause
it to be discarded at link time.

Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Hector Marco Gisbert <hecmargi@upv.es>
Cc: Hector Marco-Gisbert <hecmargi@upv.es>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Ismael Ripoll <iripoll@upv.es>
Cc: Kees Cook <keescook@chromium.org>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Russell King <rmk@arm.linux.org.uk>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Will Deacon <will.deacon@arm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---

 arch/arm/include/asm/elf.h        |    3 +--
 arch/arm/mm/mmap.c                |   13 ++-----------
 arch/arm64/Kconfig                |    2 +-
 arch/arm64/include/asm/elf.h      |    3 +--
 arch/arm64/mm/mmap.c              |   14 ++------------
 arch/mips/include/asm/elf.h       |    1 -
 arch/mips/mm/mmap.c               |   13 ++-----------
 arch/powerpc/include/asm/elf.h    |    2 --
 arch/powerpc/mm/mmap.c            |   13 ++-----------
 arch/x86/include/asm/elf.h        |    2 --
 arch/x86/mm/mmap.c                |   12 ++----------
 fs/binfmt_elf.c                   |   21 +++++++++++++++++++++
 include/linux/elf-randomization.h |    7 +++++++
 13 files changed, 41 insertions(+), 65 deletions(-)

diff -puN arch/arm/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/arm/Kconfig
diff -puN arch/arm/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/arm/include/asm/elf.h
--- a/arch/arm/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
+++ a/arch/arm/include/asm/elf.h
@@ -2,7 +2,7 @@
 #define __ASMARM_ELF_H
 
 #include <asm/hwcap.h>
-
+#include <linux/elf-randomization.h>
 /*
  * ELF register definitions..
  */
@@ -115,7 +115,6 @@ int dump_task_regs(struct task_struct *t
    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.  */
 
-extern unsigned long randomize_et_dyn(unsigned long base);
 #define ELF_ET_DYN_BASE	(randomize_et_dyn(2 * TASK_SIZE / 3))
 
 /* When the program starts, a1 contains a pointer to a function to be 
diff -puN arch/arm/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/arm/mm/mmap.c
--- a/arch/arm/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
+++ a/arch/arm/mm/mmap.c
@@ -7,6 +7,7 @@
 #include <linux/shm.h>
 #include <linux/sched.h>
 #include <linux/io.h>
+#include <linux/elf-randomization.h>
 #include <linux/personality.h>
 #include <linux/random.h>
 #include <asm/cachetype.h>
@@ -30,7 +31,7 @@ static int mmap_is_legacy(void)
 	return sysctl_legacy_va_layout;
 }
 
-static unsigned long mmap_rnd(void)
+unsigned long mmap_rnd(void)
 {
 	unsigned long rnd = 0;
 
@@ -241,13 +242,3 @@ int devmem_is_allowed(unsigned long pfn)
 }
 
 #endif
-
-unsigned long randomize_et_dyn(unsigned long base)
-{
-	unsigned long ret;
-	if ((current->personality & ADDR_NO_RANDOMIZE) ||
-		!(current->flags & PF_RANDOMIZE))
-		return base;
-	ret = base + mmap_rnd();
-	return (ret > base) ? ret : base;
-}
diff -puN arch/arm64/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/arm64/Kconfig
--- a/arch/arm64/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
+++ a/arch/arm64/Kconfig
@@ -1,4 +1,4 @@
-config ARM64
+qconfig ARM64
 	def_bool y
 	select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
 	select ARCH_HAS_GCOV_PROFILE_ALL
diff -puN arch/arm64/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/arm64/include/asm/elf.h
--- a/arch/arm64/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
+++ a/arch/arm64/include/asm/elf.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 ARM Ltd.
+ * Copyright (C) 20q12 ARM Ltd.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -125,7 +125,6 @@ typedef struct user_fpsimd_state elf_fpr
  * 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.
  */
-extern unsigned long randomize_et_dyn(unsigned long base);
 #define ELF_ET_DYN_BASE	(randomize_et_dyn(2 * TASK_SIZE_64 / 3))
 
 /*
diff -puN arch/arm64/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/arm64/mm/mmap.c
--- a/arch/arm64/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
+++ a/arch/arm64/mm/mmap.c
@@ -17,6 +17,7 @@
  */
 
 #include <linux/elf.h>
+#include <linux/elf-randomization.h>
 #include <linux/fs.h>
 #include <linux/mm.h>
 #include <linux/mman.h>
@@ -47,7 +48,7 @@ static int mmap_is_legacy(void)
 	return sysctl_legacy_va_layout;
 }
 
-static unsigned long mmap_rnd(void)
+unsigned long mmap_rnd(void)
 {
 	unsigned long rnd = 0;
 
@@ -89,17 +90,6 @@ void arch_pick_mmap_layout(struct mm_str
 }
 EXPORT_SYMBOL_GPL(arch_pick_mmap_layout);
 
-unsigned long randomize_et_dyn(unsigned long base)
-{
-	unsigned long ret;
-	if ((current->personality & ADDR_NO_RANDOMIZE) ||
-		!(current->flags & PF_RANDOMIZE))
-		return base;
-	ret = base + mmap_rnd();
-	return (ret > base) ? ret : base;
-}
-
-
 /*
  * You really shouldn't be using read() or write() on /dev/mem.  This might go
  * away in the future.
diff -puN arch/mips/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/mips/Kconfig
diff -puN arch/mips/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/mips/include/asm/elf.h
--- a/arch/mips/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
+++ a/arch/mips/include/asm/elf.h
@@ -402,7 +402,6 @@ extern const char *__elf_platform;
    that it will "exec", and that there is sufficient room for the brk.	*/
 
 #ifndef ELF_ET_DYN_BASE
-extern unsigned long randomize_et_dyn(unsigned long base);
 #define ELF_ET_DYN_BASE		(randomize_et_dyn(TASK_SIZE / 3 * 2))
 #endif
 
diff -puN arch/mips/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/mips/mm/mmap.c
--- a/arch/mips/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
+++ a/arch/mips/mm/mmap.c
@@ -9,6 +9,7 @@
 #include <linux/compiler.h>
 #include <linux/errno.h>
 #include <linux/mm.h>
+#include <linux/elf-randomization.h>
 #include <linux/mman.h>
 #include <linux/module.h>
 #include <linux/personality.h>
@@ -164,7 +165,7 @@ void arch_pick_mmap_layout(struct mm_str
 	}
 }
 
-static inline unsigned long mmap_rnd(void)
+unsigned long mmap_rnd(void)
 {
 	unsigned long rnd = get_random_int();
 
@@ -196,13 +197,3 @@ int __virt_addr_valid(const volatile voi
 	return pfn_valid(PFN_DOWN(virt_to_phys(kaddr)));
 }
 EXPORT_SYMBOL_GPL(__virt_addr_valid);
-
-unsigned long randomize_et_dyn(unsigned long base)
-{
-	unsigned long ret;
-	if ((current->personality & ADDR_NO_RANDOMIZE) ||
-		!(current->flags & PF_RANDOMIZE))
-		return base;
-	ret = base + brk_rnd();
-	return (ret > base) ? ret : base;
-}
diff -puN arch/powerpc/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/powerpc/Kconfig
diff -puN arch/powerpc/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/powerpc/include/asm/elf.h
--- a/arch/powerpc/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
+++ a/arch/powerpc/include/asm/elf.h
@@ -27,8 +27,6 @@
    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.  */
-
-extern unsigned long randomize_et_dyn(unsigned long base);
 #define ELF_ET_DYN_BASE	(randomize_et_dyn(0x20000000))
 
 #define ELF_CORE_EFLAGS (is_elf2_task() ? 2 : 0)
diff -puN arch/powerpc/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/powerpc/mm/mmap.c
--- a/arch/powerpc/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
+++ a/arch/powerpc/mm/mmap.c
@@ -24,6 +24,7 @@
 
 #include <linux/personality.h>
 #include <linux/mm.h>
+#include <linux/elf-randomization.h>
 #include <linux/random.h>
 #include <linux/sched.h>
 
@@ -53,7 +54,7 @@ static inline int mmap_is_legacy(void)
 	return sysctl_legacy_va_layout;
 }
 
-static unsigned long mmap_rnd(void)
+unsigned long mmap_rnd(void)
 {
 	unsigned long rnd = 0;
 
@@ -97,13 +98,3 @@ void arch_pick_mmap_layout(struct mm_str
 		mm->get_unmapped_area = arch_get_unmapped_area_topdown;
 	}
 }
-
-unsigned long randomize_et_dyn(unsigned long base)
-{
-	unsigned long ret;
-	if ((current->personality & ADDR_NO_RANDOMIZE) ||
-		!(current->flags & PF_RANDOMIZE))
-		return base;
-	ret = base + mmap_rnd();
-	return (ret > base) ? ret : base;
-}
diff -puN arch/x86/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/x86/Kconfig
diff -puN arch/x86/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/x86/include/asm/elf.h
--- a/arch/x86/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
+++ a/arch/x86/include/asm/elf.h
@@ -248,8 +248,6 @@ extern int force_personality32;
    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.  */
-
-extern unsigned long randomize_et_dyn(unsigned long base);
 #define ELF_ET_DYN_BASE		(randomize_et_dyn(TASK_SIZE / 3 * 2))
 
 /* This yields a mask that user programs can use to figure out what
diff -puN arch/x86/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/x86/mm/mmap.c
--- a/arch/x86/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
+++ a/arch/x86/mm/mmap.c
@@ -29,6 +29,7 @@
 #include <linux/random.h>
 #include <linux/limits.h>
 #include <linux/sched.h>
+#include <linux/elf-randomization.h>
 #include <asm/elf.h>
 
 struct va_alignment __read_mostly va_align = {
@@ -65,7 +66,7 @@ static int mmap_is_legacy(void)
 	return sysctl_legacy_va_layout;
 }
 
-static unsigned long mmap_rnd(void)
+unsigned long mmap_rnd(void)
 {
 	unsigned long rnd = 0;
 
@@ -122,12 +123,3 @@ void arch_pick_mmap_layout(struct mm_str
 		mm->get_unmapped_area = arch_get_unmapped_area_topdown;
 	}
 }
-unsigned long randomize_et_dyn(unsigned long base)
-{
-	unsigned long ret;
-	if ((current->personality & ADDR_NO_RANDOMIZE) ||
-		!(current->flags & PF_RANDOMIZE))
-		return base;
-	ret = base + mmap_rnd();
-	return (ret > base) ? ret : base;
-}
diff -puN fs/Kconfig.binfmt~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix fs/Kconfig.binfmt
diff -puN fs/binfmt_elf.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix fs/binfmt_elf.c
--- a/fs/binfmt_elf.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
+++ a/fs/binfmt_elf.c
@@ -22,6 +22,7 @@
 #include <linux/slab.h>
 #include <linux/personality.h>
 #include <linux/elfcore.h>
+#include <linux/elf-randomization.h>
 #include <linux/init.h>
 #include <linux/highuid.h>
 #include <linux/compiler.h>
@@ -2300,6 +2301,26 @@ out:
 
 #endif		/* CONFIG_ELF_CORE */
 
+/* Not all architectures implement mmap_rnd() */
+unsigned long __weak mmap_rnd(void)
+{
+}
+
+/*
+ * Not all architectures use randomize_et_dyn(), so use __weak to let the
+ * linker omit it from vmlinux
+ */
+unsigned long __weak randomize_et_dyn(unsigned long base)
+{
+	unsigned long ret;
+
+	if ((current->personality & ADDR_NO_RANDOMIZE) ||
+		!(current->flags & PF_RANDOMIZE))
+		return base;
+	ret = base + mmap_rnd();
+	return max(ret, base);
+}
+
 static int __init init_elf_binfmt(void)
 {
 	register_binfmt(&elf_format);
diff -puN include/linux/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix include/linux/elf.h
diff -puN /dev/null include/linux/elf-randomization.h
--- /dev/null
+++ a/include/linux/elf-randomization.h
@@ -0,0 +1,7 @@
+#ifndef __ELF_RANDOMIZATION_H
+#define __ELF_RANDOMIZATION_H
+
+unsigned long randomize_et_dyn(unsigned long base);
+unsigned long mmap_rnd(void);
+
+#endif	/* __ELF_RANDOMIZATION_H */
_

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

* Re: [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS
@ 2015-02-26 22:43           ` David Daney
  0 siblings, 0 replies; 56+ messages in thread
From: David Daney @ 2015-02-26 22:43 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Ingo Molnar, Hector Marco Gisbert, Kees Cook, LKML,
	ismael Ripoll, x86, linux-arm-kernel, Linux MIPS Mailing List,
	linuxppc-dev

On 02/26/2015 02:38 PM, Andrew Morton wrote:
[...]
>
> From: Andrew Morton<akpm@linux-foundation.org>
> Subject: fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
>
> Consolidate randomize_et_dyn() implementations into fs/binfmt_elf.c.
>
> There doesn't seem to be a compile-time way of making randomize_et_dyn()
> go away on architectures which don't need it, so mark it __weak to cause
> it to be discarded at link time.
>
> Cc: "H. Peter Anvin"<hpa@zytor.com>
> Cc: Benjamin Herrenschmidt<benh@kernel.crashing.org>
> Cc: Catalin Marinas<catalin.marinas@arm.com>
> Cc: Hector Marco Gisbert<hecmargi@upv.es>
> Cc: Hector Marco-Gisbert<hecmargi@upv.es>
> Cc: Ingo Molnar<mingo@kernel.org>
> Cc: Ismael Ripoll<iripoll@upv.es>
> Cc: Kees Cook<keescook@chromium.org>
> Cc: Ralf Baechle<ralf@linux-mips.org>
> Cc: Russell King<rmk@arm.linux.org.uk>
> Cc: Thomas Gleixner<tglx@linutronix.de>
> Cc: Will Deacon<will.deacon@arm.com>
> Signed-off-by: Andrew Morton<akpm@linux-foundation.org>
[...]
> diff -puN arch/arm64/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/arm64/include/asm/elf.h
> --- a/arch/arm64/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
> +++ a/arch/arm64/include/asm/elf.h
> @@ -1,5 +1,5 @@
>   /*
> - * Copyright (C) 2012 ARM Ltd.
> + * Copyright (C) 20q12 ARM Ltd.

This particular change looks like it may be a typo.

>    *
>    * This program is free software; you can redistribute it and/or modify
>    * it under the terms of the GNU General Public License version 2 as


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

* Re: [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS
@ 2015-02-26 22:43           ` David Daney
  0 siblings, 0 replies; 56+ messages in thread
From: David Daney @ 2015-02-26 22:43 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Ingo Molnar, Hector Marco Gisbert, Kees Cook, LKML,
	ismael Ripoll, x86, linux-arm-kernel, Linux MIPS Mailing List,
	linuxppc-dev

On 02/26/2015 02:38 PM, Andrew Morton wrote:
[...]
>
> From: Andrew Morton<akpm@linux-foundation.org>
> Subject: fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
>
> Consolidate randomize_et_dyn() implementations into fs/binfmt_elf.c.
>
> There doesn't seem to be a compile-time way of making randomize_et_dyn()
> go away on architectures which don't need it, so mark it __weak to cause
> it to be discarded at link time.
>
> Cc: "H. Peter Anvin"<hpa@zytor.com>
> Cc: Benjamin Herrenschmidt<benh@kernel.crashing.org>
> Cc: Catalin Marinas<catalin.marinas@arm.com>
> Cc: Hector Marco Gisbert<hecmargi@upv.es>
> Cc: Hector Marco-Gisbert<hecmargi@upv.es>
> Cc: Ingo Molnar<mingo@kernel.org>
> Cc: Ismael Ripoll<iripoll@upv.es>
> Cc: Kees Cook<keescook@chromium.org>
> Cc: Ralf Baechle<ralf@linux-mips.org>
> Cc: Russell King<rmk@arm.linux.org.uk>
> Cc: Thomas Gleixner<tglx@linutronix.de>
> Cc: Will Deacon<will.deacon@arm.com>
> Signed-off-by: Andrew Morton<akpm@linux-foundation.org>
[...]
> diff -puN arch/arm64/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/arm64/include/asm/elf.h
> --- a/arch/arm64/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
> +++ a/arch/arm64/include/asm/elf.h
> @@ -1,5 +1,5 @@
>   /*
> - * Copyright (C) 2012 ARM Ltd.
> + * Copyright (C) 20q12 ARM Ltd.

This particular change looks like it may be a typo.

>    *
>    * This program is free software; you can redistribute it and/or modify
>    * it under the terms of the GNU General Public License version 2 as

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

* Re: [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS
@ 2015-02-26 22:43           ` David Daney
  0 siblings, 0 replies; 56+ messages in thread
From: David Daney @ 2015-02-26 22:43 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Linux MIPS Mailing List, Kees Cook, x86, Hector Marco Gisbert,
	LKML, linux-arm-kernel, linuxppc-dev, Ingo Molnar, ismael Ripoll

On 02/26/2015 02:38 PM, Andrew Morton wrote:
[...]
>
> From: Andrew Morton<akpm@linux-foundation.org>
> Subject: fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
>
> Consolidate randomize_et_dyn() implementations into fs/binfmt_elf.c.
>
> There doesn't seem to be a compile-time way of making randomize_et_dyn()
> go away on architectures which don't need it, so mark it __weak to cause
> it to be discarded at link time.
>
> Cc: "H. Peter Anvin"<hpa@zytor.com>
> Cc: Benjamin Herrenschmidt<benh@kernel.crashing.org>
> Cc: Catalin Marinas<catalin.marinas@arm.com>
> Cc: Hector Marco Gisbert<hecmargi@upv.es>
> Cc: Hector Marco-Gisbert<hecmargi@upv.es>
> Cc: Ingo Molnar<mingo@kernel.org>
> Cc: Ismael Ripoll<iripoll@upv.es>
> Cc: Kees Cook<keescook@chromium.org>
> Cc: Ralf Baechle<ralf@linux-mips.org>
> Cc: Russell King<rmk@arm.linux.org.uk>
> Cc: Thomas Gleixner<tglx@linutronix.de>
> Cc: Will Deacon<will.deacon@arm.com>
> Signed-off-by: Andrew Morton<akpm@linux-foundation.org>
[...]
> diff -puN arch/arm64/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/arm64/include/asm/elf.h
> --- a/arch/arm64/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
> +++ a/arch/arm64/include/asm/elf.h
> @@ -1,5 +1,5 @@
>   /*
> - * Copyright (C) 2012 ARM Ltd.
> + * Copyright (C) 20q12 ARM Ltd.

This particular change looks like it may be a typo.

>    *
>    * This program is free software; you can redistribute it and/or modify
>    * it under the terms of the GNU General Public License version 2 as

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

* [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS
@ 2015-02-26 22:43           ` David Daney
  0 siblings, 0 replies; 56+ messages in thread
From: David Daney @ 2015-02-26 22:43 UTC (permalink / raw)
  To: linux-arm-kernel

On 02/26/2015 02:38 PM, Andrew Morton wrote:
[...]
>
> From: Andrew Morton<akpm@linux-foundation.org>
> Subject: fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
>
> Consolidate randomize_et_dyn() implementations into fs/binfmt_elf.c.
>
> There doesn't seem to be a compile-time way of making randomize_et_dyn()
> go away on architectures which don't need it, so mark it __weak to cause
> it to be discarded at link time.
>
> Cc: "H. Peter Anvin"<hpa@zytor.com>
> Cc: Benjamin Herrenschmidt<benh@kernel.crashing.org>
> Cc: Catalin Marinas<catalin.marinas@arm.com>
> Cc: Hector Marco Gisbert<hecmargi@upv.es>
> Cc: Hector Marco-Gisbert<hecmargi@upv.es>
> Cc: Ingo Molnar<mingo@kernel.org>
> Cc: Ismael Ripoll<iripoll@upv.es>
> Cc: Kees Cook<keescook@chromium.org>
> Cc: Ralf Baechle<ralf@linux-mips.org>
> Cc: Russell King<rmk@arm.linux.org.uk>
> Cc: Thomas Gleixner<tglx@linutronix.de>
> Cc: Will Deacon<will.deacon@arm.com>
> Signed-off-by: Andrew Morton<akpm@linux-foundation.org>
[...]
> diff -puN arch/arm64/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/arm64/include/asm/elf.h
> --- a/arch/arm64/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
> +++ a/arch/arm64/include/asm/elf.h
> @@ -1,5 +1,5 @@
>   /*
> - * Copyright (C) 2012 ARM Ltd.
> + * Copyright (C) 20q12 ARM Ltd.

This particular change looks like it may be a typo.

>    *
>    * This program is free software; you can redistribute it and/or modify
>    * it under the terms of the GNU General Public License version 2 as

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

* Re: [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS
@ 2015-02-26 23:00           ` Russell King - ARM Linux
  0 siblings, 0 replies; 56+ messages in thread
From: Russell King - ARM Linux @ 2015-02-26 23:00 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Ingo Molnar, Linux MIPS Mailing List, Kees Cook, x86,
	Hector Marco Gisbert, LKML, ismael Ripoll, linuxppc-dev,
	linux-arm-kernel

On Thu, Feb 26, 2015 at 02:38:15PM -0800, Andrew Morton wrote:
> diff -puN arch/arm64/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/arm64/Kconfig
> --- a/arch/arm64/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
> +++ a/arch/arm64/Kconfig
> @@ -1,4 +1,4 @@
> -config ARM64
> +qconfig ARM64

Is this a typo?

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.

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

* Re: [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS
@ 2015-02-26 23:00           ` Russell King - ARM Linux
  0 siblings, 0 replies; 56+ messages in thread
From: Russell King - ARM Linux @ 2015-02-26 23:00 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Ingo Molnar, Linux MIPS Mailing List, Kees Cook, x86,
	Hector Marco Gisbert, LKML, ismael Ripoll, linuxppc-dev,
	linux-arm-kernel

On Thu, Feb 26, 2015 at 02:38:15PM -0800, Andrew Morton wrote:
> diff -puN arch/arm64/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/arm64/Kconfig
> --- a/arch/arm64/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
> +++ a/arch/arm64/Kconfig
> @@ -1,4 +1,4 @@
> -config ARM64
> +qconfig ARM64

Is this a typo?

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.

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

* Re: [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS
@ 2015-02-26 23:00           ` Russell King - ARM Linux
  0 siblings, 0 replies; 56+ messages in thread
From: Russell King - ARM Linux @ 2015-02-26 23:00 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Linux MIPS Mailing List, Kees Cook, x86, Hector Marco Gisbert,
	LKML, linux-arm-kernel, linuxppc-dev, Ingo Molnar, ismael Ripoll

On Thu, Feb 26, 2015 at 02:38:15PM -0800, Andrew Morton wrote:
> diff -puN arch/arm64/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/arm64/Kconfig
> --- a/arch/arm64/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
> +++ a/arch/arm64/Kconfig
> @@ -1,4 +1,4 @@
> -config ARM64
> +qconfig ARM64

Is this a typo?

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.

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

* [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS
@ 2015-02-26 23:00           ` Russell King - ARM Linux
  0 siblings, 0 replies; 56+ messages in thread
From: Russell King - ARM Linux @ 2015-02-26 23:00 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Feb 26, 2015 at 02:38:15PM -0800, Andrew Morton wrote:
> diff -puN arch/arm64/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/arm64/Kconfig
> --- a/arch/arm64/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
> +++ a/arch/arm64/Kconfig
> @@ -1,4 +1,4 @@
> -config ARM64
> +qconfig ARM64

Is this a typo?

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.

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

* Re: [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS
@ 2015-02-26 23:03           ` Andrew Morton
  0 siblings, 0 replies; 56+ messages in thread
From: Andrew Morton @ 2015-02-26 23:03 UTC (permalink / raw)
  To: Ingo Molnar, Hector Marco Gisbert, Kees Cook, LKML,
	ismael Ripoll, x86, linux-arm-kernel, Linux MIPS Mailing List,
	linuxppc-dev

On Thu, 26 Feb 2015 14:38:15 -0800 Andrew Morton <akpm@linux-foundation.org> wrote:

> Does that __weak trick even work?

Nope.

--- a/fs/binfmt_elf.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix-fix
+++ a/fs/binfmt_elf.c
@@ -2307,10 +2307,10 @@ unsigned long __weak mmap_rnd(void)
 }
 
 /*
- * Not all architectures use randomize_et_dyn(), so use __weak to let the
- * linker omit it from vmlinux
+ * Not all architectures use randomize_et_dyn(), but there doesn't seem to be
+ * a compile-time way of avoiding its generation.
  */
-unsigned long __weak randomize_et_dyn(unsigned long base)
+unsigned long randomize_et_dyn(unsigned long base)
 {
 	unsigned long ret;
 
_


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

* Re: [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS
@ 2015-02-26 23:03           ` Andrew Morton
  0 siblings, 0 replies; 56+ messages in thread
From: Andrew Morton @ 2015-02-26 23:03 UTC (permalink / raw)
  To: Ingo Molnar, Hector Marco Gisbert, Kees Cook, LKML,
	ismael Ripoll, x86, linux-arm-kernel, Linux MIPS Mailing List,
	linuxppc-dev

On Thu, 26 Feb 2015 14:38:15 -0800 Andrew Morton <akpm@linux-foundation.org> wrote:

> Does that __weak trick even work?

Nope.

--- a/fs/binfmt_elf.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix-fix
+++ a/fs/binfmt_elf.c
@@ -2307,10 +2307,10 @@ unsigned long __weak mmap_rnd(void)
 }
 
 /*
- * Not all architectures use randomize_et_dyn(), so use __weak to let the
- * linker omit it from vmlinux
+ * Not all architectures use randomize_et_dyn(), but there doesn't seem to be
+ * a compile-time way of avoiding its generation.
  */
-unsigned long __weak randomize_et_dyn(unsigned long base)
+unsigned long randomize_et_dyn(unsigned long base)
 {
 	unsigned long ret;
 
_

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

* [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS
@ 2015-02-26 23:03           ` Andrew Morton
  0 siblings, 0 replies; 56+ messages in thread
From: Andrew Morton @ 2015-02-26 23:03 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, 26 Feb 2015 14:38:15 -0800 Andrew Morton <akpm@linux-foundation.org> wrote:

> Does that __weak trick even work?

Nope.

--- a/fs/binfmt_elf.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix-fix
+++ a/fs/binfmt_elf.c
@@ -2307,10 +2307,10 @@ unsigned long __weak mmap_rnd(void)
 }
 
 /*
- * Not all architectures use randomize_et_dyn(), so use __weak to let the
- * linker omit it from vmlinux
+ * Not all architectures use randomize_et_dyn(), but there doesn't seem to be
+ * a compile-time way of avoiding its generation.
  */
-unsigned long __weak randomize_et_dyn(unsigned long base)
+unsigned long randomize_et_dyn(unsigned long base)
 {
 	unsigned long ret;
 
_

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

* Re: [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS
@ 2015-02-26 23:05             ` Andrew Morton
  0 siblings, 0 replies; 56+ messages in thread
From: Andrew Morton @ 2015-02-26 23:05 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Ingo Molnar, Linux MIPS Mailing List, Kees Cook, x86,
	Hector Marco Gisbert, LKML, ismael Ripoll, linuxppc-dev,
	linux-arm-kernel

On Thu, 26 Feb 2015 23:00:52 +0000 Russell King - ARM Linux <linux@arm.linux.org.uk> wrote:

> On Thu, Feb 26, 2015 at 02:38:15PM -0800, Andrew Morton wrote:
> > diff -puN arch/arm64/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/arm64/Kconfig
> > --- a/arch/arm64/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
> > +++ a/arch/arm64/Kconfig
> > @@ -1,4 +1,4 @@
> > -config ARM64
> > +qconfig ARM64
> 
> Is this a typo?

yup.  But the coffee's nice and strong.

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

* Re: [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS
@ 2015-02-26 23:05             ` Andrew Morton
  0 siblings, 0 replies; 56+ messages in thread
From: Andrew Morton @ 2015-02-26 23:05 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Ingo Molnar, Linux MIPS Mailing List, Kees Cook, x86,
	Hector Marco Gisbert, LKML, ismael Ripoll, linuxppc-dev,
	linux-arm-kernel

On Thu, 26 Feb 2015 23:00:52 +0000 Russell King - ARM Linux <linux@arm.linux.org.uk> wrote:

> On Thu, Feb 26, 2015 at 02:38:15PM -0800, Andrew Morton wrote:
> > diff -puN arch/arm64/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/arm64/Kconfig
> > --- a/arch/arm64/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
> > +++ a/arch/arm64/Kconfig
> > @@ -1,4 +1,4 @@
> > -config ARM64
> > +qconfig ARM64
> 
> Is this a typo?

yup.  But the coffee's nice and strong.

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

* Re: [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS
@ 2015-02-26 23:05             ` Andrew Morton
  0 siblings, 0 replies; 56+ messages in thread
From: Andrew Morton @ 2015-02-26 23:05 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Linux MIPS Mailing List, Kees Cook, x86, Hector Marco Gisbert,
	LKML, linux-arm-kernel, linuxppc-dev, Ingo Molnar, ismael Ripoll

On Thu, 26 Feb 2015 23:00:52 +0000 Russell King - ARM Linux <linux@arm.linux.org.uk> wrote:

> On Thu, Feb 26, 2015 at 02:38:15PM -0800, Andrew Morton wrote:
> > diff -puN arch/arm64/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/arm64/Kconfig
> > --- a/arch/arm64/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
> > +++ a/arch/arm64/Kconfig
> > @@ -1,4 +1,4 @@
> > -config ARM64
> > +qconfig ARM64
> 
> Is this a typo?

yup.  But the coffee's nice and strong.

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

* [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS
@ 2015-02-26 23:05             ` Andrew Morton
  0 siblings, 0 replies; 56+ messages in thread
From: Andrew Morton @ 2015-02-26 23:05 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, 26 Feb 2015 23:00:52 +0000 Russell King - ARM Linux <linux@arm.linux.org.uk> wrote:

> On Thu, Feb 26, 2015 at 02:38:15PM -0800, Andrew Morton wrote:
> > diff -puN arch/arm64/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/arm64/Kconfig
> > --- a/arch/arm64/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
> > +++ a/arch/arm64/Kconfig
> > @@ -1,4 +1,4 @@
> > -config ARM64
> > +qconfig ARM64
> 
> Is this a typo?

yup.  But the coffee's nice and strong.

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

* Re: [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS
@ 2015-02-26 23:21           ` Stephen Rothwell
  0 siblings, 0 replies; 56+ messages in thread
From: Stephen Rothwell @ 2015-02-26 23:21 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Ingo Molnar, Hector Marco Gisbert, Kees Cook, LKML, ismael Ripoll, x86, 

[-- Attachment #1: Type: text/plain, Size: 1373 bytes --]

Hi Andrew,

On Thu, 26 Feb 2015 14:38:15 -0800 Andrew Morton <akpm@linux-foundation.org> wrote:
>
> diff -puN fs/binfmt_elf.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix fs/binfmt_elf.c
> --- a/fs/binfmt_elf.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
> +++ a/fs/binfmt_elf.c
> @@ -22,6 +22,7 @@
>  #include <linux/slab.h>
>  #include <linux/personality.h>
>  #include <linux/elfcore.h>
> +#include <linux/elf-randomization.h>
>  #include <linux/init.h>
>  #include <linux/highuid.h>
>  #include <linux/compiler.h>
> @@ -2300,6 +2301,26 @@ out:
>  
>  #endif		/* CONFIG_ELF_CORE */
>  
> +/* Not all architectures implement mmap_rnd() */
> +unsigned long __weak mmap_rnd(void)
> +{
> +}
> +
> +/*
> + * Not all architectures use randomize_et_dyn(), so use __weak to let the
> + * linker omit it from vmlinux
> + */
> +unsigned long __weak randomize_et_dyn(unsigned long base)
> +{
> +	unsigned long ret;
> +
> +	if ((current->personality & ADDR_NO_RANDOMIZE) ||
> +		!(current->flags & PF_RANDOMIZE))
> +		return base;
> +	ret = base + mmap_rnd();
> +	return max(ret, base);
> +}
> +

Didn't we have some trouble with some compilers when the weak function
(mmap_rnd) was defined and used in the same file i.e. the wrong one was
used?

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

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

* Re: [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS
@ 2015-02-26 23:21           ` Stephen Rothwell
  0 siblings, 0 replies; 56+ messages in thread
From: Stephen Rothwell @ 2015-02-26 23:21 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Ingo Molnar, Hector Marco Gisbert, Kees Cook, LKML,
	ismael Ripoll, x86, linux-arm-kernel

[-- Attachment #1: Type: text/plain, Size: 1373 bytes --]

Hi Andrew,

On Thu, 26 Feb 2015 14:38:15 -0800 Andrew Morton <akpm@linux-foundation.org> wrote:
>
> diff -puN fs/binfmt_elf.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix fs/binfmt_elf.c
> --- a/fs/binfmt_elf.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
> +++ a/fs/binfmt_elf.c
> @@ -22,6 +22,7 @@
>  #include <linux/slab.h>
>  #include <linux/personality.h>
>  #include <linux/elfcore.h>
> +#include <linux/elf-randomization.h>
>  #include <linux/init.h>
>  #include <linux/highuid.h>
>  #include <linux/compiler.h>
> @@ -2300,6 +2301,26 @@ out:
>  
>  #endif		/* CONFIG_ELF_CORE */
>  
> +/* Not all architectures implement mmap_rnd() */
> +unsigned long __weak mmap_rnd(void)
> +{
> +}
> +
> +/*
> + * Not all architectures use randomize_et_dyn(), so use __weak to let the
> + * linker omit it from vmlinux
> + */
> +unsigned long __weak randomize_et_dyn(unsigned long base)
> +{
> +	unsigned long ret;
> +
> +	if ((current->personality & ADDR_NO_RANDOMIZE) ||
> +		!(current->flags & PF_RANDOMIZE))
> +		return base;
> +	ret = base + mmap_rnd();
> +	return max(ret, base);
> +}
> +

Didn't we have some trouble with some compilers when the weak function
(mmap_rnd) was defined and used in the same file i.e. the wrong one was
used?

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

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

* Re: [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS
@ 2015-02-26 23:21           ` Stephen Rothwell
  0 siblings, 0 replies; 56+ messages in thread
From: Stephen Rothwell @ 2015-02-26 23:21 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Kees Cook, x86, Hector Marco Gisbert, LKML, linux-arm-kernel

[-- Attachment #1: Type: text/plain, Size: 1373 bytes --]

Hi Andrew,

On Thu, 26 Feb 2015 14:38:15 -0800 Andrew Morton <akpm@linux-foundation.org> wrote:
>
> diff -puN fs/binfmt_elf.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix fs/binfmt_elf.c
> --- a/fs/binfmt_elf.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
> +++ a/fs/binfmt_elf.c
> @@ -22,6 +22,7 @@
>  #include <linux/slab.h>
>  #include <linux/personality.h>
>  #include <linux/elfcore.h>
> +#include <linux/elf-randomization.h>
>  #include <linux/init.h>
>  #include <linux/highuid.h>
>  #include <linux/compiler.h>
> @@ -2300,6 +2301,26 @@ out:
>  
>  #endif		/* CONFIG_ELF_CORE */
>  
> +/* Not all architectures implement mmap_rnd() */
> +unsigned long __weak mmap_rnd(void)
> +{
> +}
> +
> +/*
> + * Not all architectures use randomize_et_dyn(), so use __weak to let the
> + * linker omit it from vmlinux
> + */
> +unsigned long __weak randomize_et_dyn(unsigned long base)
> +{
> +	unsigned long ret;
> +
> +	if ((current->personality & ADDR_NO_RANDOMIZE) ||
> +		!(current->flags & PF_RANDOMIZE))
> +		return base;
> +	ret = base + mmap_rnd();
> +	return max(ret, base);
> +}
> +

Didn't we have some trouble with some compilers when the weak function
(mmap_rnd) was defined and used in the same file i.e. the wrong one was
used?

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

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

* Re: [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS
@ 2015-02-26 23:26           ` Stephen Rothwell
  0 siblings, 0 replies; 56+ messages in thread
From: Stephen Rothwell @ 2015-02-26 23:26 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Ingo Molnar, Hector Marco Gisbert, Kees Cook, LKML,
	ismael Ripoll, x86, linux-arm-kernel, Linux MIPS Mailing List,
	linuxppc-dev

[-- Attachment #1: Type: text/plain, Size: 1454 bytes --]

Hi Andrew,

[Just resending to correct addresses - sorry for those who get a duplicate]

On Thu, 26 Feb 2015 14:38:15 -0800 Andrew Morton <akpm@linux-foundation.org> wrote:
>
> diff -puN fs/binfmt_elf.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix fs/binfmt_elf.c
> --- a/fs/binfmt_elf.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
> +++ a/fs/binfmt_elf.c
> @@ -22,6 +22,7 @@
>  #include <linux/slab.h>
>  #include <linux/personality.h>
>  #include <linux/elfcore.h>
> +#include <linux/elf-randomization.h>
>  #include <linux/init.h>
>  #include <linux/highuid.h>
>  #include <linux/compiler.h>
> @@ -2300,6 +2301,26 @@ out:
>  
>  #endif		/* CONFIG_ELF_CORE */
>  
> +/* Not all architectures implement mmap_rnd() */
> +unsigned long __weak mmap_rnd(void)
> +{
> +}
> +
> +/*
> + * Not all architectures use randomize_et_dyn(), so use __weak to let the
> + * linker omit it from vmlinux
> + */
> +unsigned long __weak randomize_et_dyn(unsigned long base)
> +{
> +	unsigned long ret;
> +
> +	if ((current->personality & ADDR_NO_RANDOMIZE) ||
> +		!(current->flags & PF_RANDOMIZE))
> +		return base;
> +	ret = base + mmap_rnd();
> +	return max(ret, base);
> +}
> +  

Didn't we have some trouble with some compilers when the weak function
(mmap_rnd) was defined and used in the same file i.e. the wrong one was
used?

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

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

* Re: [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS
@ 2015-02-26 23:26           ` Stephen Rothwell
  0 siblings, 0 replies; 56+ messages in thread
From: Stephen Rothwell @ 2015-02-26 23:26 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Ingo Molnar, Hector Marco Gisbert, Kees Cook, LKML,
	ismael Ripoll, x86, linux-arm-kernel, Linux MIPS Mailing List,
	linuxppc-dev

[-- Attachment #1: Type: text/plain, Size: 1454 bytes --]

Hi Andrew,

[Just resending to correct addresses - sorry for those who get a duplicate]

On Thu, 26 Feb 2015 14:38:15 -0800 Andrew Morton <akpm@linux-foundation.org> wrote:
>
> diff -puN fs/binfmt_elf.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix fs/binfmt_elf.c
> --- a/fs/binfmt_elf.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
> +++ a/fs/binfmt_elf.c
> @@ -22,6 +22,7 @@
>  #include <linux/slab.h>
>  #include <linux/personality.h>
>  #include <linux/elfcore.h>
> +#include <linux/elf-randomization.h>
>  #include <linux/init.h>
>  #include <linux/highuid.h>
>  #include <linux/compiler.h>
> @@ -2300,6 +2301,26 @@ out:
>  
>  #endif		/* CONFIG_ELF_CORE */
>  
> +/* Not all architectures implement mmap_rnd() */
> +unsigned long __weak mmap_rnd(void)
> +{
> +}
> +
> +/*
> + * Not all architectures use randomize_et_dyn(), so use __weak to let the
> + * linker omit it from vmlinux
> + */
> +unsigned long __weak randomize_et_dyn(unsigned long base)
> +{
> +	unsigned long ret;
> +
> +	if ((current->personality & ADDR_NO_RANDOMIZE) ||
> +		!(current->flags & PF_RANDOMIZE))
> +		return base;
> +	ret = base + mmap_rnd();
> +	return max(ret, base);
> +}
> +  

Didn't we have some trouble with some compilers when the weak function
(mmap_rnd) was defined and used in the same file i.e. the wrong one was
used?

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

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

* Re: [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS
@ 2015-02-26 23:26           ` Stephen Rothwell
  0 siblings, 0 replies; 56+ messages in thread
From: Stephen Rothwell @ 2015-02-26 23:26 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Linux MIPS Mailing List, Kees Cook, x86, Hector Marco Gisbert,
	LKML, linux-arm-kernel, linuxppc-dev, Ingo Molnar, ismael Ripoll

[-- Attachment #1: Type: text/plain, Size: 1454 bytes --]

Hi Andrew,

[Just resending to correct addresses - sorry for those who get a duplicate]

On Thu, 26 Feb 2015 14:38:15 -0800 Andrew Morton <akpm@linux-foundation.org> wrote:
>
> diff -puN fs/binfmt_elf.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix fs/binfmt_elf.c
> --- a/fs/binfmt_elf.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
> +++ a/fs/binfmt_elf.c
> @@ -22,6 +22,7 @@
>  #include <linux/slab.h>
>  #include <linux/personality.h>
>  #include <linux/elfcore.h>
> +#include <linux/elf-randomization.h>
>  #include <linux/init.h>
>  #include <linux/highuid.h>
>  #include <linux/compiler.h>
> @@ -2300,6 +2301,26 @@ out:
>  
>  #endif		/* CONFIG_ELF_CORE */
>  
> +/* Not all architectures implement mmap_rnd() */
> +unsigned long __weak mmap_rnd(void)
> +{
> +}
> +
> +/*
> + * Not all architectures use randomize_et_dyn(), so use __weak to let the
> + * linker omit it from vmlinux
> + */
> +unsigned long __weak randomize_et_dyn(unsigned long base)
> +{
> +	unsigned long ret;
> +
> +	if ((current->personality & ADDR_NO_RANDOMIZE) ||
> +		!(current->flags & PF_RANDOMIZE))
> +		return base;
> +	ret = base + mmap_rnd();
> +	return max(ret, base);
> +}
> +  

Didn't we have some trouble with some compilers when the weak function
(mmap_rnd) was defined and used in the same file i.e. the wrong one was
used?

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

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

* [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS
@ 2015-02-26 23:26           ` Stephen Rothwell
  0 siblings, 0 replies; 56+ messages in thread
From: Stephen Rothwell @ 2015-02-26 23:26 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Andrew,

[Just resending to correct addresses - sorry for those who get a duplicate]

On Thu, 26 Feb 2015 14:38:15 -0800 Andrew Morton <akpm@linux-foundation.org> wrote:
>
> diff -puN fs/binfmt_elf.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix fs/binfmt_elf.c
> --- a/fs/binfmt_elf.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
> +++ a/fs/binfmt_elf.c
> @@ -22,6 +22,7 @@
>  #include <linux/slab.h>
>  #include <linux/personality.h>
>  #include <linux/elfcore.h>
> +#include <linux/elf-randomization.h>
>  #include <linux/init.h>
>  #include <linux/highuid.h>
>  #include <linux/compiler.h>
> @@ -2300,6 +2301,26 @@ out:
>  
>  #endif		/* CONFIG_ELF_CORE */
>  
> +/* Not all architectures implement mmap_rnd() */
> +unsigned long __weak mmap_rnd(void)
> +{
> +}
> +
> +/*
> + * Not all architectures use randomize_et_dyn(), so use __weak to let the
> + * linker omit it from vmlinux
> + */
> +unsigned long __weak randomize_et_dyn(unsigned long base)
> +{
> +	unsigned long ret;
> +
> +	if ((current->personality & ADDR_NO_RANDOMIZE) ||
> +		!(current->flags & PF_RANDOMIZE))
> +		return base;
> +	ret = base + mmap_rnd();
> +	return max(ret, base);
> +}
> +  

Didn't we have some trouble with some compilers when the weak function
(mmap_rnd) was defined and used in the same file i.e. the wrong one was
used?

-- 
Cheers,
Stephen Rothwell                    sfr at canb.auug.org.au
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 819 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150227/3c80d6c1/attachment.sig>

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

* Re: [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS
  2015-02-26 23:21           ` Stephen Rothwell
@ 2015-02-26 23:34             ` Andrew Morton
  -1 siblings, 0 replies; 56+ messages in thread
From: Andrew Morton @ 2015-02-26 23:34 UTC (permalink / raw)
  To: Stephen Rothwell
  Cc: Ingo Molnar, Hector Marco Gisbert, Kees Cook, LKML,
	ismael Ripoll, x86,
	linux-arm-kernel@lists.infradead.org"
	<linux-arm-kernel@lists.infradead.org>,
	Linux MIPS Mailing List <linux-mips@linux-mips.org>,
	linuxppc-dev@lists.ozlabs.org

On Fri, 27 Feb 2015 10:21:36 +1100 Stephen Rothwell <sfr@canb.auug.org.au> wrote:

> > +/* Not all architectures implement mmap_rnd() */
> > +unsigned long __weak mmap_rnd(void)
> > +{
> > +}
> > +
> > +/*
> > + * Not all architectures use randomize_et_dyn(), so use __weak to let the
> > + * linker omit it from vmlinux
> > + */
> > +unsigned long __weak randomize_et_dyn(unsigned long base)
> > +{
> > +	unsigned long ret;
> > +
> > +	if ((current->personality & ADDR_NO_RANDOMIZE) ||
> > +		!(current->flags & PF_RANDOMIZE))
> > +		return base;
> > +	ret = base + mmap_rnd();
> > +	return max(ret, base);
> > +}
> > +
> 
> Didn't we have some trouble with some compilers when the weak function
> (mmap_rnd) was defined and used in the same file i.e. the wrong one was
> used?

I have vague memories, but I forget the details.

This sucks anyway - let's do it properly.

I'm just flinging together trollpatches here.  Someone please review,
test and fix this stuff.  Kees?

diff -puN arch/arm/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix-fix-2 arch/arm/Kconfig
--- a/arch/arm/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix-fix-2
+++ a/arch/arm/Kconfig
@@ -5,6 +5,7 @@ config ARM
 	select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
 	select ARCH_HAVE_CUSTOM_GPIO_H
 	select ARCH_HAS_GCOV_PROFILE_ALL
+	select ARCH_HAVE_ELF_ASLR
 	select ARCH_MIGHT_HAVE_PC_PARPORT
 	select ARCH_SUPPORTS_ATOMIC_RMW
 	select ARCH_USE_BUILTIN_BSWAP
diff -puN arch/arm64/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix-fix-2 arch/arm64/Kconfig
--- a/arch/arm64/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix-fix-2
+++ a/arch/arm64/Kconfig
@@ -9,6 +9,7 @@ config ARM64
 	select ARCH_WANT_OPTIONAL_GPIOLIB
 	select ARCH_WANT_COMPAT_IPC_PARSE_VERSION
 	select ARCH_WANT_FRAME_POINTERS
+	select ARCH_HAVE_ELF_ASLR
 	select ARM_AMBA
 	select ARM_ARCH_TIMER
 	select ARM_GIC
diff -puN arch/mips/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix-fix-2 arch/mips/Kconfig
--- a/arch/mips/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix-fix-2
+++ a/arch/mips/Kconfig
@@ -39,6 +39,7 @@ config MIPS
 	select HAVE_MEMBLOCK
 	select HAVE_MEMBLOCK_NODE_MAP
 	select ARCH_DISCARD_MEMBLOCK
+	select ARCH_HAVE_ELF_ASLR
 	select GENERIC_SMP_IDLE_THREAD
 	select BUILDTIME_EXTABLE_SORT
 	select GENERIC_CLOCKEVENTS
diff -puN arch/powerpc/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix-fix-2 arch/powerpc/Kconfig
--- a/arch/powerpc/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix-fix-2
+++ a/arch/powerpc/Kconfig
@@ -97,6 +97,7 @@ config PPC
 	select HAVE_FUNCTION_GRAPH_TRACER
 	select SYSCTL_EXCEPTION_TRACE
 	select ARCH_WANT_OPTIONAL_GPIOLIB
+	select ARCH_HAVE_ELF_ASLR
 	select VIRT_TO_BUS if !PPC64
 	select HAVE_IDE
 	select HAVE_IOREMAP_PROT
diff -puN arch/x86/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix-fix-2 arch/x86/Kconfig
--- a/arch/x86/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix-fix-2
+++ a/arch/x86/Kconfig
@@ -28,6 +28,7 @@ config X86
 	select ARCH_HAS_GCOV_PROFILE_ALL
 	select ARCH_MIGHT_HAVE_PC_PARPORT
 	select ARCH_MIGHT_HAVE_PC_SERIO
+	select ARCH_HAVE_ELF_ASLR
 	select HAVE_AOUT if X86_32
 	select HAVE_UNSTABLE_SCHED_CLOCK
 	select ARCH_SUPPORTS_NUMA_BALANCING if X86_64
diff -puN fs/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix-fix-2 fs/Kconfig
--- a/fs/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix-fix-2
+++ a/fs/Kconfig
@@ -50,6 +50,9 @@ config FS_DAX
 
 endif # BLOCK
 
+config ARCH_HAVE_ELF_ASLR
+	bool
+
 # Posix ACL utility routines
 #
 # Note: Posix ACLs can be implemented without these helpers.  Never use
diff -puN fs/binfmt_elf.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix-fix-2 fs/binfmt_elf.c
--- a/fs/binfmt_elf.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix-fix-2
+++ a/fs/binfmt_elf.c
@@ -2301,15 +2301,7 @@ out:
 
 #endif		/* CONFIG_ELF_CORE */
 
-/* Not all architectures implement mmap_rnd() */
-unsigned long __weak mmap_rnd(void)
-{
-}
-
-/*
- * Not all architectures use randomize_et_dyn(), but there doesn't seem to be
- * a compile-time way of avoiding its generation.
- */
+#ifdef ARCH_HAVE_ELF_ASLR
 unsigned long randomize_et_dyn(unsigned long base)
 {
 	unsigned long ret;
@@ -2320,6 +2312,7 @@ unsigned long randomize_et_dyn(unsigned
 	ret = base + mmap_rnd();
 	return max(ret, base);
 }
+#endif
 
 static int __init init_elf_binfmt(void)
 {
_

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

* Re: [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS
@ 2015-02-26 23:34             ` Andrew Morton
  0 siblings, 0 replies; 56+ messages in thread
From: Andrew Morton @ 2015-02-26 23:34 UTC (permalink / raw)
  To: Stephen Rothwell
  Cc: Kees Cook, x86, Hector Marco Gisbert, LKML,
	linux-arm-kernel@lists.infradead.org"
	<linux-arm-kernel@lists.infradead.org>,
	Linux MIPS Mailing List <linux-mips@linux-mips.org>,
	linuxppc-dev@lists.ozlabs.org, Ingo Molnar, ismael Ripoll

On Fri, 27 Feb 2015 10:21:36 +1100 Stephen Rothwell <sfr@canb.auug.org.au> wrote:

> > +/* Not all architectures implement mmap_rnd() */
> > +unsigned long __weak mmap_rnd(void)
> > +{
> > +}
> > +
> > +/*
> > + * Not all architectures use randomize_et_dyn(), so use __weak to let the
> > + * linker omit it from vmlinux
> > + */
> > +unsigned long __weak randomize_et_dyn(unsigned long base)
> > +{
> > +	unsigned long ret;
> > +
> > +	if ((current->personality & ADDR_NO_RANDOMIZE) ||
> > +		!(current->flags & PF_RANDOMIZE))
> > +		return base;
> > +	ret = base + mmap_rnd();
> > +	return max(ret, base);
> > +}
> > +
> 
> Didn't we have some trouble with some compilers when the weak function
> (mmap_rnd) was defined and used in the same file i.e. the wrong one was
> used?

I have vague memories, but I forget the details.

This sucks anyway - let's do it properly.

I'm just flinging together trollpatches here.  Someone please review,
test and fix this stuff.  Kees?

diff -puN arch/arm/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix-fix-2 arch/arm/Kconfig
--- a/arch/arm/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix-fix-2
+++ a/arch/arm/Kconfig
@@ -5,6 +5,7 @@ config ARM
 	select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
 	select ARCH_HAVE_CUSTOM_GPIO_H
 	select ARCH_HAS_GCOV_PROFILE_ALL
+	select ARCH_HAVE_ELF_ASLR
 	select ARCH_MIGHT_HAVE_PC_PARPORT
 	select ARCH_SUPPORTS_ATOMIC_RMW
 	select ARCH_USE_BUILTIN_BSWAP
diff -puN arch/arm64/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix-fix-2 arch/arm64/Kconfig
--- a/arch/arm64/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix-fix-2
+++ a/arch/arm64/Kconfig
@@ -9,6 +9,7 @@ config ARM64
 	select ARCH_WANT_OPTIONAL_GPIOLIB
 	select ARCH_WANT_COMPAT_IPC_PARSE_VERSION
 	select ARCH_WANT_FRAME_POINTERS
+	select ARCH_HAVE_ELF_ASLR
 	select ARM_AMBA
 	select ARM_ARCH_TIMER
 	select ARM_GIC
diff -puN arch/mips/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix-fix-2 arch/mips/Kconfig
--- a/arch/mips/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix-fix-2
+++ a/arch/mips/Kconfig
@@ -39,6 +39,7 @@ config MIPS
 	select HAVE_MEMBLOCK
 	select HAVE_MEMBLOCK_NODE_MAP
 	select ARCH_DISCARD_MEMBLOCK
+	select ARCH_HAVE_ELF_ASLR
 	select GENERIC_SMP_IDLE_THREAD
 	select BUILDTIME_EXTABLE_SORT
 	select GENERIC_CLOCKEVENTS
diff -puN arch/powerpc/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix-fix-2 arch/powerpc/Kconfig
--- a/arch/powerpc/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix-fix-2
+++ a/arch/powerpc/Kconfig
@@ -97,6 +97,7 @@ config PPC
 	select HAVE_FUNCTION_GRAPH_TRACER
 	select SYSCTL_EXCEPTION_TRACE
 	select ARCH_WANT_OPTIONAL_GPIOLIB
+	select ARCH_HAVE_ELF_ASLR
 	select VIRT_TO_BUS if !PPC64
 	select HAVE_IDE
 	select HAVE_IOREMAP_PROT
diff -puN arch/x86/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix-fix-2 arch/x86/Kconfig
--- a/arch/x86/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix-fix-2
+++ a/arch/x86/Kconfig
@@ -28,6 +28,7 @@ config X86
 	select ARCH_HAS_GCOV_PROFILE_ALL
 	select ARCH_MIGHT_HAVE_PC_PARPORT
 	select ARCH_MIGHT_HAVE_PC_SERIO
+	select ARCH_HAVE_ELF_ASLR
 	select HAVE_AOUT if X86_32
 	select HAVE_UNSTABLE_SCHED_CLOCK
 	select ARCH_SUPPORTS_NUMA_BALANCING if X86_64
diff -puN fs/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix-fix-2 fs/Kconfig
--- a/fs/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix-fix-2
+++ a/fs/Kconfig
@@ -50,6 +50,9 @@ config FS_DAX
 
 endif # BLOCK
 
+config ARCH_HAVE_ELF_ASLR
+	bool
+
 # Posix ACL utility routines
 #
 # Note: Posix ACLs can be implemented without these helpers.  Never use
diff -puN fs/binfmt_elf.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix-fix-2 fs/binfmt_elf.c
--- a/fs/binfmt_elf.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix-fix-2
+++ a/fs/binfmt_elf.c
@@ -2301,15 +2301,7 @@ out:
 
 #endif		/* CONFIG_ELF_CORE */
 
-/* Not all architectures implement mmap_rnd() */
-unsigned long __weak mmap_rnd(void)
-{
-}
-
-/*
- * Not all architectures use randomize_et_dyn(), but there doesn't seem to be
- * a compile-time way of avoiding its generation.
- */
+#ifdef ARCH_HAVE_ELF_ASLR
 unsigned long randomize_et_dyn(unsigned long base)
 {
 	unsigned long ret;
@@ -2320,6 +2312,7 @@ unsigned long randomize_et_dyn(unsigned
 	ret = base + mmap_rnd();
 	return max(ret, base);
 }
+#endif
 
 static int __init init_elf_binfmt(void)
 {
_

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

* Re: [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS
@ 2015-02-26 23:34           ` Kees Cook
  0 siblings, 0 replies; 56+ messages in thread
From: Kees Cook @ 2015-02-26 23:34 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Ingo Molnar, Hector Marco Gisbert, LKML, ismael Ripoll, x86,
	linux-arm-kernel, Linux MIPS Mailing List, linuxppc-dev

On Thu, Feb 26, 2015 at 2:38 PM, Andrew Morton
<akpm@linux-foundation.org> wrote:
> On Tue, 24 Feb 2015 08:39:06 +0100 Ingo Molnar <mingo@kernel.org> wrote:
>
>>
>> * Hector Marco Gisbert <hecmargi@upv.es> wrote:
>>
>> > +unsigned long randomize_et_dyn(unsigned long base)
>> > +{
>> > +   unsigned long ret;
>> > +   if ((current->personality & ADDR_NO_RANDOMIZE) ||
>> > +           !(current->flags & PF_RANDOMIZE))
>> > +           return base;
>> > +   ret = base + mmap_rnd();
>> > +   return (ret > base) ? ret : base;
>> > +}
>>
>> > +unsigned long randomize_et_dyn(unsigned long base)
>> > +{
>> > +   unsigned long ret;
>> > +   if ((current->personality & ADDR_NO_RANDOMIZE) ||
>> > +           !(current->flags & PF_RANDOMIZE))
>> > +           return base;
>> > +   ret = base + mmap_rnd();
>> > +   return (ret > base) ? ret : base;
>> > +}
>>
>> > +unsigned long randomize_et_dyn(unsigned long base)
>> > +{
>> > +   unsigned long ret;
>> > +   if ((current->personality & ADDR_NO_RANDOMIZE) ||
>> > +           !(current->flags & PF_RANDOMIZE))
>> > +           return base;
>> > +   ret = base + brk_rnd();
>> > +   return (ret > base) ? ret : base;
>> > +}
>>
>> > +unsigned long randomize_et_dyn(unsigned long base)
>> > +{
>> > +   unsigned long ret;
>> > +   if ((current->personality & ADDR_NO_RANDOMIZE) ||
>> > +           !(current->flags & PF_RANDOMIZE))
>> > +           return base;
>> > +   ret = base + mmap_rnd();
>> > +   return (ret > base) ? ret : base;
>> > +}
>>
>> > +unsigned long randomize_et_dyn(unsigned long base)
>> > +{
>> > +   unsigned long ret;
>> > +   if ((current->personality & ADDR_NO_RANDOMIZE) ||
>> > +           !(current->flags & PF_RANDOMIZE))
>> > +           return base;
>> > +   ret = base + mmap_rnd();
>> > +   return (ret > base) ? ret : base;
>> > +}
>>
>> That pointless repetition should be avoided.
>
> That's surprisingly hard!
>
> After renaming mips brk_rnd() to mmap_rnd() I had a shot.  I'm not very
> confident in the result.  Does that __weak trick even work?

In theory, it shouldn't be needed since only randomize_et_dyn will
call mmap_rnd, and only architectures that use randomize_et_dyn will
call it ... and will define mmap_rnd.

>
> Someone tell me how important Hector's patch is?

I consider it a reasonable improvement to userspace ASLR. I look at it
more as a new feature than a bug fix, but it could be argued as a bug
fix too.

>
>
> From: Andrew Morton <akpm@linux-foundation.org>
> Subject: fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
>
> Consolidate randomize_et_dyn() implementations into fs/binfmt_elf.c.
>
> There doesn't seem to be a compile-time way of making randomize_et_dyn()
> go away on architectures which don't need it, so mark it __weak to cause
> it to be discarded at link time.
>
> Cc: "H. Peter Anvin" <hpa@zytor.com>
> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Hector Marco Gisbert <hecmargi@upv.es>
> Cc: Hector Marco-Gisbert <hecmargi@upv.es>
> Cc: Ingo Molnar <mingo@kernel.org>
> Cc: Ismael Ripoll <iripoll@upv.es>
> Cc: Kees Cook <keescook@chromium.org>
> Cc: Ralf Baechle <ralf@linux-mips.org>
> Cc: Russell King <rmk@arm.linux.org.uk>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Will Deacon <will.deacon@arm.com>
> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

Acked-by: Kees Cook <keescook@chromium.org>

Thanks for fixing it up!

-Kees

> ---
>
>  arch/arm/include/asm/elf.h        |    3 +--
>  arch/arm/mm/mmap.c                |   13 ++-----------
>  arch/arm64/Kconfig                |    2 +-
>  arch/arm64/include/asm/elf.h      |    3 +--
>  arch/arm64/mm/mmap.c              |   14 ++------------
>  arch/mips/include/asm/elf.h       |    1 -
>  arch/mips/mm/mmap.c               |   13 ++-----------
>  arch/powerpc/include/asm/elf.h    |    2 --
>  arch/powerpc/mm/mmap.c            |   13 ++-----------
>  arch/x86/include/asm/elf.h        |    2 --
>  arch/x86/mm/mmap.c                |   12 ++----------
>  fs/binfmt_elf.c                   |   21 +++++++++++++++++++++
>  include/linux/elf-randomization.h |    7 +++++++
>  13 files changed, 41 insertions(+), 65 deletions(-)
>
> diff -puN arch/arm/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/arm/Kconfig
> diff -puN arch/arm/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/arm/include/asm/elf.h
> --- a/arch/arm/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
> +++ a/arch/arm/include/asm/elf.h
> @@ -2,7 +2,7 @@
>  #define __ASMARM_ELF_H
>
>  #include <asm/hwcap.h>
> -
> +#include <linux/elf-randomization.h>
>  /*
>   * ELF register definitions..
>   */
> @@ -115,7 +115,6 @@ int dump_task_regs(struct task_struct *t
>     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.  */
>
> -extern unsigned long randomize_et_dyn(unsigned long base);
>  #define ELF_ET_DYN_BASE        (randomize_et_dyn(2 * TASK_SIZE / 3))
>
>  /* When the program starts, a1 contains a pointer to a function to be
> diff -puN arch/arm/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/arm/mm/mmap.c
> --- a/arch/arm/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
> +++ a/arch/arm/mm/mmap.c
> @@ -7,6 +7,7 @@
>  #include <linux/shm.h>
>  #include <linux/sched.h>
>  #include <linux/io.h>
> +#include <linux/elf-randomization.h>
>  #include <linux/personality.h>
>  #include <linux/random.h>
>  #include <asm/cachetype.h>
> @@ -30,7 +31,7 @@ static int mmap_is_legacy(void)
>         return sysctl_legacy_va_layout;
>  }
>
> -static unsigned long mmap_rnd(void)
> +unsigned long mmap_rnd(void)
>  {
>         unsigned long rnd = 0;
>
> @@ -241,13 +242,3 @@ int devmem_is_allowed(unsigned long pfn)
>  }
>
>  #endif
> -
> -unsigned long randomize_et_dyn(unsigned long base)
> -{
> -       unsigned long ret;
> -       if ((current->personality & ADDR_NO_RANDOMIZE) ||
> -               !(current->flags & PF_RANDOMIZE))
> -               return base;
> -       ret = base + mmap_rnd();
> -       return (ret > base) ? ret : base;
> -}
> diff -puN arch/arm64/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/arm64/Kconfig
> --- a/arch/arm64/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
> +++ a/arch/arm64/Kconfig
> @@ -1,4 +1,4 @@
> -config ARM64
> +qconfig ARM64
>         def_bool y
>         select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
>         select ARCH_HAS_GCOV_PROFILE_ALL
> diff -puN arch/arm64/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/arm64/include/asm/elf.h
> --- a/arch/arm64/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
> +++ a/arch/arm64/include/asm/elf.h
> @@ -1,5 +1,5 @@
>  /*
> - * Copyright (C) 2012 ARM Ltd.
> + * Copyright (C) 20q12 ARM Ltd.
>   *
>   * This program is free software; you can redistribute it and/or modify
>   * it under the terms of the GNU General Public License version 2 as
> @@ -125,7 +125,6 @@ typedef struct user_fpsimd_state elf_fpr
>   * 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.
>   */
> -extern unsigned long randomize_et_dyn(unsigned long base);
>  #define ELF_ET_DYN_BASE        (randomize_et_dyn(2 * TASK_SIZE_64 / 3))
>
>  /*
> diff -puN arch/arm64/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/arm64/mm/mmap.c
> --- a/arch/arm64/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
> +++ a/arch/arm64/mm/mmap.c
> @@ -17,6 +17,7 @@
>   */
>
>  #include <linux/elf.h>
> +#include <linux/elf-randomization.h>
>  #include <linux/fs.h>
>  #include <linux/mm.h>
>  #include <linux/mman.h>
> @@ -47,7 +48,7 @@ static int mmap_is_legacy(void)
>         return sysctl_legacy_va_layout;
>  }
>
> -static unsigned long mmap_rnd(void)
> +unsigned long mmap_rnd(void)
>  {
>         unsigned long rnd = 0;
>
> @@ -89,17 +90,6 @@ void arch_pick_mmap_layout(struct mm_str
>  }
>  EXPORT_SYMBOL_GPL(arch_pick_mmap_layout);
>
> -unsigned long randomize_et_dyn(unsigned long base)
> -{
> -       unsigned long ret;
> -       if ((current->personality & ADDR_NO_RANDOMIZE) ||
> -               !(current->flags & PF_RANDOMIZE))
> -               return base;
> -       ret = base + mmap_rnd();
> -       return (ret > base) ? ret : base;
> -}
> -
> -
>  /*
>   * You really shouldn't be using read() or write() on /dev/mem.  This might go
>   * away in the future.
> diff -puN arch/mips/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/mips/Kconfig
> diff -puN arch/mips/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/mips/include/asm/elf.h
> --- a/arch/mips/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
> +++ a/arch/mips/include/asm/elf.h
> @@ -402,7 +402,6 @@ extern const char *__elf_platform;
>     that it will "exec", and that there is sufficient room for the brk. */
>
>  #ifndef ELF_ET_DYN_BASE
> -extern unsigned long randomize_et_dyn(unsigned long base);
>  #define ELF_ET_DYN_BASE                (randomize_et_dyn(TASK_SIZE / 3 * 2))
>  #endif
>
> diff -puN arch/mips/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/mips/mm/mmap.c
> --- a/arch/mips/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
> +++ a/arch/mips/mm/mmap.c
> @@ -9,6 +9,7 @@
>  #include <linux/compiler.h>
>  #include <linux/errno.h>
>  #include <linux/mm.h>
> +#include <linux/elf-randomization.h>
>  #include <linux/mman.h>
>  #include <linux/module.h>
>  #include <linux/personality.h>
> @@ -164,7 +165,7 @@ void arch_pick_mmap_layout(struct mm_str
>         }
>  }
>
> -static inline unsigned long mmap_rnd(void)
> +unsigned long mmap_rnd(void)
>  {
>         unsigned long rnd = get_random_int();
>
> @@ -196,13 +197,3 @@ int __virt_addr_valid(const volatile voi
>         return pfn_valid(PFN_DOWN(virt_to_phys(kaddr)));
>  }
>  EXPORT_SYMBOL_GPL(__virt_addr_valid);
> -
> -unsigned long randomize_et_dyn(unsigned long base)
> -{
> -       unsigned long ret;
> -       if ((current->personality & ADDR_NO_RANDOMIZE) ||
> -               !(current->flags & PF_RANDOMIZE))
> -               return base;
> -       ret = base + brk_rnd();
> -       return (ret > base) ? ret : base;
> -}
> diff -puN arch/powerpc/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/powerpc/Kconfig
> diff -puN arch/powerpc/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/powerpc/include/asm/elf.h
> --- a/arch/powerpc/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
> +++ a/arch/powerpc/include/asm/elf.h
> @@ -27,8 +27,6 @@
>     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.  */
> -
> -extern unsigned long randomize_et_dyn(unsigned long base);
>  #define ELF_ET_DYN_BASE        (randomize_et_dyn(0x20000000))
>
>  #define ELF_CORE_EFLAGS (is_elf2_task() ? 2 : 0)
> diff -puN arch/powerpc/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/powerpc/mm/mmap.c
> --- a/arch/powerpc/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
> +++ a/arch/powerpc/mm/mmap.c
> @@ -24,6 +24,7 @@
>
>  #include <linux/personality.h>
>  #include <linux/mm.h>
> +#include <linux/elf-randomization.h>
>  #include <linux/random.h>
>  #include <linux/sched.h>
>
> @@ -53,7 +54,7 @@ static inline int mmap_is_legacy(void)
>         return sysctl_legacy_va_layout;
>  }
>
> -static unsigned long mmap_rnd(void)
> +unsigned long mmap_rnd(void)
>  {
>         unsigned long rnd = 0;
>
> @@ -97,13 +98,3 @@ void arch_pick_mmap_layout(struct mm_str
>                 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
>         }
>  }
> -
> -unsigned long randomize_et_dyn(unsigned long base)
> -{
> -       unsigned long ret;
> -       if ((current->personality & ADDR_NO_RANDOMIZE) ||
> -               !(current->flags & PF_RANDOMIZE))
> -               return base;
> -       ret = base + mmap_rnd();
> -       return (ret > base) ? ret : base;
> -}
> diff -puN arch/x86/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/x86/Kconfig
> diff -puN arch/x86/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/x86/include/asm/elf.h
> --- a/arch/x86/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
> +++ a/arch/x86/include/asm/elf.h
> @@ -248,8 +248,6 @@ extern int force_personality32;
>     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.  */
> -
> -extern unsigned long randomize_et_dyn(unsigned long base);
>  #define ELF_ET_DYN_BASE                (randomize_et_dyn(TASK_SIZE / 3 * 2))
>
>  /* This yields a mask that user programs can use to figure out what
> diff -puN arch/x86/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/x86/mm/mmap.c
> --- a/arch/x86/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
> +++ a/arch/x86/mm/mmap.c
> @@ -29,6 +29,7 @@
>  #include <linux/random.h>
>  #include <linux/limits.h>
>  #include <linux/sched.h>
> +#include <linux/elf-randomization.h>
>  #include <asm/elf.h>
>
>  struct va_alignment __read_mostly va_align = {
> @@ -65,7 +66,7 @@ static int mmap_is_legacy(void)
>         return sysctl_legacy_va_layout;
>  }
>
> -static unsigned long mmap_rnd(void)
> +unsigned long mmap_rnd(void)
>  {
>         unsigned long rnd = 0;
>
> @@ -122,12 +123,3 @@ void arch_pick_mmap_layout(struct mm_str
>                 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
>         }
>  }
> -unsigned long randomize_et_dyn(unsigned long base)
> -{
> -       unsigned long ret;
> -       if ((current->personality & ADDR_NO_RANDOMIZE) ||
> -               !(current->flags & PF_RANDOMIZE))
> -               return base;
> -       ret = base + mmap_rnd();
> -       return (ret > base) ? ret : base;
> -}
> diff -puN fs/Kconfig.binfmt~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix fs/Kconfig.binfmt
> diff -puN fs/binfmt_elf.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix fs/binfmt_elf.c
> --- a/fs/binfmt_elf.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
> +++ a/fs/binfmt_elf.c
> @@ -22,6 +22,7 @@
>  #include <linux/slab.h>
>  #include <linux/personality.h>
>  #include <linux/elfcore.h>
> +#include <linux/elf-randomization.h>
>  #include <linux/init.h>
>  #include <linux/highuid.h>
>  #include <linux/compiler.h>
> @@ -2300,6 +2301,26 @@ out:
>
>  #endif         /* CONFIG_ELF_CORE */
>
> +/* Not all architectures implement mmap_rnd() */
> +unsigned long __weak mmap_rnd(void)
> +{
> +}
> +
> +/*
> + * Not all architectures use randomize_et_dyn(), so use __weak to let the
> + * linker omit it from vmlinux
> + */
> +unsigned long __weak randomize_et_dyn(unsigned long base)
> +{
> +       unsigned long ret;
> +
> +       if ((current->personality & ADDR_NO_RANDOMIZE) ||
> +               !(current->flags & PF_RANDOMIZE))
> +               return base;
> +       ret = base + mmap_rnd();
> +       return max(ret, base);
> +}
> +
>  static int __init init_elf_binfmt(void)
>  {
>         register_binfmt(&elf_format);
> diff -puN include/linux/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix include/linux/elf.h
> diff -puN /dev/null include/linux/elf-randomization.h
> --- /dev/null
> +++ a/include/linux/elf-randomization.h
> @@ -0,0 +1,7 @@
> +#ifndef __ELF_RANDOMIZATION_H
> +#define __ELF_RANDOMIZATION_H
> +
> +unsigned long randomize_et_dyn(unsigned long base);
> +unsigned long mmap_rnd(void);
> +
> +#endif /* __ELF_RANDOMIZATION_H */
> _
>



-- 
Kees Cook
Chrome OS Security

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

* Re: [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS
@ 2015-02-26 23:34           ` Kees Cook
  0 siblings, 0 replies; 56+ messages in thread
From: Kees Cook @ 2015-02-26 23:34 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Ingo Molnar, Hector Marco Gisbert, LKML, ismael Ripoll, x86,
	linux-arm-kernel, Linux MIPS Mailing List, linuxppc-dev

On Thu, Feb 26, 2015 at 2:38 PM, Andrew Morton
<akpm@linux-foundation.org> wrote:
> On Tue, 24 Feb 2015 08:39:06 +0100 Ingo Molnar <mingo@kernel.org> wrote:
>
>>
>> * Hector Marco Gisbert <hecmargi@upv.es> wrote:
>>
>> > +unsigned long randomize_et_dyn(unsigned long base)
>> > +{
>> > +   unsigned long ret;
>> > +   if ((current->personality & ADDR_NO_RANDOMIZE) ||
>> > +           !(current->flags & PF_RANDOMIZE))
>> > +           return base;
>> > +   ret = base + mmap_rnd();
>> > +   return (ret > base) ? ret : base;
>> > +}
>>
>> > +unsigned long randomize_et_dyn(unsigned long base)
>> > +{
>> > +   unsigned long ret;
>> > +   if ((current->personality & ADDR_NO_RANDOMIZE) ||
>> > +           !(current->flags & PF_RANDOMIZE))
>> > +           return base;
>> > +   ret = base + mmap_rnd();
>> > +   return (ret > base) ? ret : base;
>> > +}
>>
>> > +unsigned long randomize_et_dyn(unsigned long base)
>> > +{
>> > +   unsigned long ret;
>> > +   if ((current->personality & ADDR_NO_RANDOMIZE) ||
>> > +           !(current->flags & PF_RANDOMIZE))
>> > +           return base;
>> > +   ret = base + brk_rnd();
>> > +   return (ret > base) ? ret : base;
>> > +}
>>
>> > +unsigned long randomize_et_dyn(unsigned long base)
>> > +{
>> > +   unsigned long ret;
>> > +   if ((current->personality & ADDR_NO_RANDOMIZE) ||
>> > +           !(current->flags & PF_RANDOMIZE))
>> > +           return base;
>> > +   ret = base + mmap_rnd();
>> > +   return (ret > base) ? ret : base;
>> > +}
>>
>> > +unsigned long randomize_et_dyn(unsigned long base)
>> > +{
>> > +   unsigned long ret;
>> > +   if ((current->personality & ADDR_NO_RANDOMIZE) ||
>> > +           !(current->flags & PF_RANDOMIZE))
>> > +           return base;
>> > +   ret = base + mmap_rnd();
>> > +   return (ret > base) ? ret : base;
>> > +}
>>
>> That pointless repetition should be avoided.
>
> That's surprisingly hard!
>
> After renaming mips brk_rnd() to mmap_rnd() I had a shot.  I'm not very
> confident in the result.  Does that __weak trick even work?

In theory, it shouldn't be needed since only randomize_et_dyn will
call mmap_rnd, and only architectures that use randomize_et_dyn will
call it ... and will define mmap_rnd.

>
> Someone tell me how important Hector's patch is?

I consider it a reasonable improvement to userspace ASLR. I look at it
more as a new feature than a bug fix, but it could be argued as a bug
fix too.

>
>
> From: Andrew Morton <akpm@linux-foundation.org>
> Subject: fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
>
> Consolidate randomize_et_dyn() implementations into fs/binfmt_elf.c.
>
> There doesn't seem to be a compile-time way of making randomize_et_dyn()
> go away on architectures which don't need it, so mark it __weak to cause
> it to be discarded at link time.
>
> Cc: "H. Peter Anvin" <hpa@zytor.com>
> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Hector Marco Gisbert <hecmargi@upv.es>
> Cc: Hector Marco-Gisbert <hecmargi@upv.es>
> Cc: Ingo Molnar <mingo@kernel.org>
> Cc: Ismael Ripoll <iripoll@upv.es>
> Cc: Kees Cook <keescook@chromium.org>
> Cc: Ralf Baechle <ralf@linux-mips.org>
> Cc: Russell King <rmk@arm.linux.org.uk>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Will Deacon <will.deacon@arm.com>
> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

Acked-by: Kees Cook <keescook@chromium.org>

Thanks for fixing it up!

-Kees

> ---
>
>  arch/arm/include/asm/elf.h        |    3 +--
>  arch/arm/mm/mmap.c                |   13 ++-----------
>  arch/arm64/Kconfig                |    2 +-
>  arch/arm64/include/asm/elf.h      |    3 +--
>  arch/arm64/mm/mmap.c              |   14 ++------------
>  arch/mips/include/asm/elf.h       |    1 -
>  arch/mips/mm/mmap.c               |   13 ++-----------
>  arch/powerpc/include/asm/elf.h    |    2 --
>  arch/powerpc/mm/mmap.c            |   13 ++-----------
>  arch/x86/include/asm/elf.h        |    2 --
>  arch/x86/mm/mmap.c                |   12 ++----------
>  fs/binfmt_elf.c                   |   21 +++++++++++++++++++++
>  include/linux/elf-randomization.h |    7 +++++++
>  13 files changed, 41 insertions(+), 65 deletions(-)
>
> diff -puN arch/arm/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/arm/Kconfig
> diff -puN arch/arm/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/arm/include/asm/elf.h
> --- a/arch/arm/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
> +++ a/arch/arm/include/asm/elf.h
> @@ -2,7 +2,7 @@
>  #define __ASMARM_ELF_H
>
>  #include <asm/hwcap.h>
> -
> +#include <linux/elf-randomization.h>
>  /*
>   * ELF register definitions..
>   */
> @@ -115,7 +115,6 @@ int dump_task_regs(struct task_struct *t
>     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.  */
>
> -extern unsigned long randomize_et_dyn(unsigned long base);
>  #define ELF_ET_DYN_BASE        (randomize_et_dyn(2 * TASK_SIZE / 3))
>
>  /* When the program starts, a1 contains a pointer to a function to be
> diff -puN arch/arm/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/arm/mm/mmap.c
> --- a/arch/arm/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
> +++ a/arch/arm/mm/mmap.c
> @@ -7,6 +7,7 @@
>  #include <linux/shm.h>
>  #include <linux/sched.h>
>  #include <linux/io.h>
> +#include <linux/elf-randomization.h>
>  #include <linux/personality.h>
>  #include <linux/random.h>
>  #include <asm/cachetype.h>
> @@ -30,7 +31,7 @@ static int mmap_is_legacy(void)
>         return sysctl_legacy_va_layout;
>  }
>
> -static unsigned long mmap_rnd(void)
> +unsigned long mmap_rnd(void)
>  {
>         unsigned long rnd = 0;
>
> @@ -241,13 +242,3 @@ int devmem_is_allowed(unsigned long pfn)
>  }
>
>  #endif
> -
> -unsigned long randomize_et_dyn(unsigned long base)
> -{
> -       unsigned long ret;
> -       if ((current->personality & ADDR_NO_RANDOMIZE) ||
> -               !(current->flags & PF_RANDOMIZE))
> -               return base;
> -       ret = base + mmap_rnd();
> -       return (ret > base) ? ret : base;
> -}
> diff -puN arch/arm64/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/arm64/Kconfig
> --- a/arch/arm64/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
> +++ a/arch/arm64/Kconfig
> @@ -1,4 +1,4 @@
> -config ARM64
> +qconfig ARM64
>         def_bool y
>         select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
>         select ARCH_HAS_GCOV_PROFILE_ALL
> diff -puN arch/arm64/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/arm64/include/asm/elf.h
> --- a/arch/arm64/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
> +++ a/arch/arm64/include/asm/elf.h
> @@ -1,5 +1,5 @@
>  /*
> - * Copyright (C) 2012 ARM Ltd.
> + * Copyright (C) 20q12 ARM Ltd.
>   *
>   * This program is free software; you can redistribute it and/or modify
>   * it under the terms of the GNU General Public License version 2 as
> @@ -125,7 +125,6 @@ typedef struct user_fpsimd_state elf_fpr
>   * 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.
>   */
> -extern unsigned long randomize_et_dyn(unsigned long base);
>  #define ELF_ET_DYN_BASE        (randomize_et_dyn(2 * TASK_SIZE_64 / 3))
>
>  /*
> diff -puN arch/arm64/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/arm64/mm/mmap.c
> --- a/arch/arm64/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
> +++ a/arch/arm64/mm/mmap.c
> @@ -17,6 +17,7 @@
>   */
>
>  #include <linux/elf.h>
> +#include <linux/elf-randomization.h>
>  #include <linux/fs.h>
>  #include <linux/mm.h>
>  #include <linux/mman.h>
> @@ -47,7 +48,7 @@ static int mmap_is_legacy(void)
>         return sysctl_legacy_va_layout;
>  }
>
> -static unsigned long mmap_rnd(void)
> +unsigned long mmap_rnd(void)
>  {
>         unsigned long rnd = 0;
>
> @@ -89,17 +90,6 @@ void arch_pick_mmap_layout(struct mm_str
>  }
>  EXPORT_SYMBOL_GPL(arch_pick_mmap_layout);
>
> -unsigned long randomize_et_dyn(unsigned long base)
> -{
> -       unsigned long ret;
> -       if ((current->personality & ADDR_NO_RANDOMIZE) ||
> -               !(current->flags & PF_RANDOMIZE))
> -               return base;
> -       ret = base + mmap_rnd();
> -       return (ret > base) ? ret : base;
> -}
> -
> -
>  /*
>   * You really shouldn't be using read() or write() on /dev/mem.  This might go
>   * away in the future.
> diff -puN arch/mips/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/mips/Kconfig
> diff -puN arch/mips/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/mips/include/asm/elf.h
> --- a/arch/mips/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
> +++ a/arch/mips/include/asm/elf.h
> @@ -402,7 +402,6 @@ extern const char *__elf_platform;
>     that it will "exec", and that there is sufficient room for the brk. */
>
>  #ifndef ELF_ET_DYN_BASE
> -extern unsigned long randomize_et_dyn(unsigned long base);
>  #define ELF_ET_DYN_BASE                (randomize_et_dyn(TASK_SIZE / 3 * 2))
>  #endif
>
> diff -puN arch/mips/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/mips/mm/mmap.c
> --- a/arch/mips/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
> +++ a/arch/mips/mm/mmap.c
> @@ -9,6 +9,7 @@
>  #include <linux/compiler.h>
>  #include <linux/errno.h>
>  #include <linux/mm.h>
> +#include <linux/elf-randomization.h>
>  #include <linux/mman.h>
>  #include <linux/module.h>
>  #include <linux/personality.h>
> @@ -164,7 +165,7 @@ void arch_pick_mmap_layout(struct mm_str
>         }
>  }
>
> -static inline unsigned long mmap_rnd(void)
> +unsigned long mmap_rnd(void)
>  {
>         unsigned long rnd = get_random_int();
>
> @@ -196,13 +197,3 @@ int __virt_addr_valid(const volatile voi
>         return pfn_valid(PFN_DOWN(virt_to_phys(kaddr)));
>  }
>  EXPORT_SYMBOL_GPL(__virt_addr_valid);
> -
> -unsigned long randomize_et_dyn(unsigned long base)
> -{
> -       unsigned long ret;
> -       if ((current->personality & ADDR_NO_RANDOMIZE) ||
> -               !(current->flags & PF_RANDOMIZE))
> -               return base;
> -       ret = base + brk_rnd();
> -       return (ret > base) ? ret : base;
> -}
> diff -puN arch/powerpc/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/powerpc/Kconfig
> diff -puN arch/powerpc/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/powerpc/include/asm/elf.h
> --- a/arch/powerpc/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
> +++ a/arch/powerpc/include/asm/elf.h
> @@ -27,8 +27,6 @@
>     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.  */
> -
> -extern unsigned long randomize_et_dyn(unsigned long base);
>  #define ELF_ET_DYN_BASE        (randomize_et_dyn(0x20000000))
>
>  #define ELF_CORE_EFLAGS (is_elf2_task() ? 2 : 0)
> diff -puN arch/powerpc/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/powerpc/mm/mmap.c
> --- a/arch/powerpc/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
> +++ a/arch/powerpc/mm/mmap.c
> @@ -24,6 +24,7 @@
>
>  #include <linux/personality.h>
>  #include <linux/mm.h>
> +#include <linux/elf-randomization.h>
>  #include <linux/random.h>
>  #include <linux/sched.h>
>
> @@ -53,7 +54,7 @@ static inline int mmap_is_legacy(void)
>         return sysctl_legacy_va_layout;
>  }
>
> -static unsigned long mmap_rnd(void)
> +unsigned long mmap_rnd(void)
>  {
>         unsigned long rnd = 0;
>
> @@ -97,13 +98,3 @@ void arch_pick_mmap_layout(struct mm_str
>                 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
>         }
>  }
> -
> -unsigned long randomize_et_dyn(unsigned long base)
> -{
> -       unsigned long ret;
> -       if ((current->personality & ADDR_NO_RANDOMIZE) ||
> -               !(current->flags & PF_RANDOMIZE))
> -               return base;
> -       ret = base + mmap_rnd();
> -       return (ret > base) ? ret : base;
> -}
> diff -puN arch/x86/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/x86/Kconfig
> diff -puN arch/x86/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/x86/include/asm/elf.h
> --- a/arch/x86/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
> +++ a/arch/x86/include/asm/elf.h
> @@ -248,8 +248,6 @@ extern int force_personality32;
>     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.  */
> -
> -extern unsigned long randomize_et_dyn(unsigned long base);
>  #define ELF_ET_DYN_BASE                (randomize_et_dyn(TASK_SIZE / 3 * 2))
>
>  /* This yields a mask that user programs can use to figure out what
> diff -puN arch/x86/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/x86/mm/mmap.c
> --- a/arch/x86/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
> +++ a/arch/x86/mm/mmap.c
> @@ -29,6 +29,7 @@
>  #include <linux/random.h>
>  #include <linux/limits.h>
>  #include <linux/sched.h>
> +#include <linux/elf-randomization.h>
>  #include <asm/elf.h>
>
>  struct va_alignment __read_mostly va_align = {
> @@ -65,7 +66,7 @@ static int mmap_is_legacy(void)
>         return sysctl_legacy_va_layout;
>  }
>
> -static unsigned long mmap_rnd(void)
> +unsigned long mmap_rnd(void)
>  {
>         unsigned long rnd = 0;
>
> @@ -122,12 +123,3 @@ void arch_pick_mmap_layout(struct mm_str
>                 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
>         }
>  }
> -unsigned long randomize_et_dyn(unsigned long base)
> -{
> -       unsigned long ret;
> -       if ((current->personality & ADDR_NO_RANDOMIZE) ||
> -               !(current->flags & PF_RANDOMIZE))
> -               return base;
> -       ret = base + mmap_rnd();
> -       return (ret > base) ? ret : base;
> -}
> diff -puN fs/Kconfig.binfmt~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix fs/Kconfig.binfmt
> diff -puN fs/binfmt_elf.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix fs/binfmt_elf.c
> --- a/fs/binfmt_elf.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
> +++ a/fs/binfmt_elf.c
> @@ -22,6 +22,7 @@
>  #include <linux/slab.h>
>  #include <linux/personality.h>
>  #include <linux/elfcore.h>
> +#include <linux/elf-randomization.h>
>  #include <linux/init.h>
>  #include <linux/highuid.h>
>  #include <linux/compiler.h>
> @@ -2300,6 +2301,26 @@ out:
>
>  #endif         /* CONFIG_ELF_CORE */
>
> +/* Not all architectures implement mmap_rnd() */
> +unsigned long __weak mmap_rnd(void)
> +{
> +}
> +
> +/*
> + * Not all architectures use randomize_et_dyn(), so use __weak to let the
> + * linker omit it from vmlinux
> + */
> +unsigned long __weak randomize_et_dyn(unsigned long base)
> +{
> +       unsigned long ret;
> +
> +       if ((current->personality & ADDR_NO_RANDOMIZE) ||
> +               !(current->flags & PF_RANDOMIZE))
> +               return base;
> +       ret = base + mmap_rnd();
> +       return max(ret, base);
> +}
> +
>  static int __init init_elf_binfmt(void)
>  {
>         register_binfmt(&elf_format);
> diff -puN include/linux/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix include/linux/elf.h
> diff -puN /dev/null include/linux/elf-randomization.h
> --- /dev/null
> +++ a/include/linux/elf-randomization.h
> @@ -0,0 +1,7 @@
> +#ifndef __ELF_RANDOMIZATION_H
> +#define __ELF_RANDOMIZATION_H
> +
> +unsigned long randomize_et_dyn(unsigned long base);
> +unsigned long mmap_rnd(void);
> +
> +#endif /* __ELF_RANDOMIZATION_H */
> _
>



-- 
Kees Cook
Chrome OS Security

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

* Re: [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS
@ 2015-02-26 23:34           ` Kees Cook
  0 siblings, 0 replies; 56+ messages in thread
From: Kees Cook @ 2015-02-26 23:34 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Linux MIPS Mailing List, x86, Hector Marco Gisbert, LKML,
	ismael Ripoll, linuxppc-dev, Ingo Molnar, linux-arm-kernel

On Thu, Feb 26, 2015 at 2:38 PM, Andrew Morton
<akpm@linux-foundation.org> wrote:
> On Tue, 24 Feb 2015 08:39:06 +0100 Ingo Molnar <mingo@kernel.org> wrote:
>
>>
>> * Hector Marco Gisbert <hecmargi@upv.es> wrote:
>>
>> > +unsigned long randomize_et_dyn(unsigned long base)
>> > +{
>> > +   unsigned long ret;
>> > +   if ((current->personality & ADDR_NO_RANDOMIZE) ||
>> > +           !(current->flags & PF_RANDOMIZE))
>> > +           return base;
>> > +   ret = base + mmap_rnd();
>> > +   return (ret > base) ? ret : base;
>> > +}
>>
>> > +unsigned long randomize_et_dyn(unsigned long base)
>> > +{
>> > +   unsigned long ret;
>> > +   if ((current->personality & ADDR_NO_RANDOMIZE) ||
>> > +           !(current->flags & PF_RANDOMIZE))
>> > +           return base;
>> > +   ret = base + mmap_rnd();
>> > +   return (ret > base) ? ret : base;
>> > +}
>>
>> > +unsigned long randomize_et_dyn(unsigned long base)
>> > +{
>> > +   unsigned long ret;
>> > +   if ((current->personality & ADDR_NO_RANDOMIZE) ||
>> > +           !(current->flags & PF_RANDOMIZE))
>> > +           return base;
>> > +   ret = base + brk_rnd();
>> > +   return (ret > base) ? ret : base;
>> > +}
>>
>> > +unsigned long randomize_et_dyn(unsigned long base)
>> > +{
>> > +   unsigned long ret;
>> > +   if ((current->personality & ADDR_NO_RANDOMIZE) ||
>> > +           !(current->flags & PF_RANDOMIZE))
>> > +           return base;
>> > +   ret = base + mmap_rnd();
>> > +   return (ret > base) ? ret : base;
>> > +}
>>
>> > +unsigned long randomize_et_dyn(unsigned long base)
>> > +{
>> > +   unsigned long ret;
>> > +   if ((current->personality & ADDR_NO_RANDOMIZE) ||
>> > +           !(current->flags & PF_RANDOMIZE))
>> > +           return base;
>> > +   ret = base + mmap_rnd();
>> > +   return (ret > base) ? ret : base;
>> > +}
>>
>> That pointless repetition should be avoided.
>
> That's surprisingly hard!
>
> After renaming mips brk_rnd() to mmap_rnd() I had a shot.  I'm not very
> confident in the result.  Does that __weak trick even work?

In theory, it shouldn't be needed since only randomize_et_dyn will
call mmap_rnd, and only architectures that use randomize_et_dyn will
call it ... and will define mmap_rnd.

>
> Someone tell me how important Hector's patch is?

I consider it a reasonable improvement to userspace ASLR. I look at it
more as a new feature than a bug fix, but it could be argued as a bug
fix too.

>
>
> From: Andrew Morton <akpm@linux-foundation.org>
> Subject: fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
>
> Consolidate randomize_et_dyn() implementations into fs/binfmt_elf.c.
>
> There doesn't seem to be a compile-time way of making randomize_et_dyn()
> go away on architectures which don't need it, so mark it __weak to cause
> it to be discarded at link time.
>
> Cc: "H. Peter Anvin" <hpa@zytor.com>
> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Hector Marco Gisbert <hecmargi@upv.es>
> Cc: Hector Marco-Gisbert <hecmargi@upv.es>
> Cc: Ingo Molnar <mingo@kernel.org>
> Cc: Ismael Ripoll <iripoll@upv.es>
> Cc: Kees Cook <keescook@chromium.org>
> Cc: Ralf Baechle <ralf@linux-mips.org>
> Cc: Russell King <rmk@arm.linux.org.uk>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Will Deacon <will.deacon@arm.com>
> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

Acked-by: Kees Cook <keescook@chromium.org>

Thanks for fixing it up!

-Kees

> ---
>
>  arch/arm/include/asm/elf.h        |    3 +--
>  arch/arm/mm/mmap.c                |   13 ++-----------
>  arch/arm64/Kconfig                |    2 +-
>  arch/arm64/include/asm/elf.h      |    3 +--
>  arch/arm64/mm/mmap.c              |   14 ++------------
>  arch/mips/include/asm/elf.h       |    1 -
>  arch/mips/mm/mmap.c               |   13 ++-----------
>  arch/powerpc/include/asm/elf.h    |    2 --
>  arch/powerpc/mm/mmap.c            |   13 ++-----------
>  arch/x86/include/asm/elf.h        |    2 --
>  arch/x86/mm/mmap.c                |   12 ++----------
>  fs/binfmt_elf.c                   |   21 +++++++++++++++++++++
>  include/linux/elf-randomization.h |    7 +++++++
>  13 files changed, 41 insertions(+), 65 deletions(-)
>
> diff -puN arch/arm/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/arm/Kconfig
> diff -puN arch/arm/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/arm/include/asm/elf.h
> --- a/arch/arm/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
> +++ a/arch/arm/include/asm/elf.h
> @@ -2,7 +2,7 @@
>  #define __ASMARM_ELF_H
>
>  #include <asm/hwcap.h>
> -
> +#include <linux/elf-randomization.h>
>  /*
>   * ELF register definitions..
>   */
> @@ -115,7 +115,6 @@ int dump_task_regs(struct task_struct *t
>     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.  */
>
> -extern unsigned long randomize_et_dyn(unsigned long base);
>  #define ELF_ET_DYN_BASE        (randomize_et_dyn(2 * TASK_SIZE / 3))
>
>  /* When the program starts, a1 contains a pointer to a function to be
> diff -puN arch/arm/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/arm/mm/mmap.c
> --- a/arch/arm/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
> +++ a/arch/arm/mm/mmap.c
> @@ -7,6 +7,7 @@
>  #include <linux/shm.h>
>  #include <linux/sched.h>
>  #include <linux/io.h>
> +#include <linux/elf-randomization.h>
>  #include <linux/personality.h>
>  #include <linux/random.h>
>  #include <asm/cachetype.h>
> @@ -30,7 +31,7 @@ static int mmap_is_legacy(void)
>         return sysctl_legacy_va_layout;
>  }
>
> -static unsigned long mmap_rnd(void)
> +unsigned long mmap_rnd(void)
>  {
>         unsigned long rnd = 0;
>
> @@ -241,13 +242,3 @@ int devmem_is_allowed(unsigned long pfn)
>  }
>
>  #endif
> -
> -unsigned long randomize_et_dyn(unsigned long base)
> -{
> -       unsigned long ret;
> -       if ((current->personality & ADDR_NO_RANDOMIZE) ||
> -               !(current->flags & PF_RANDOMIZE))
> -               return base;
> -       ret = base + mmap_rnd();
> -       return (ret > base) ? ret : base;
> -}
> diff -puN arch/arm64/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/arm64/Kconfig
> --- a/arch/arm64/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
> +++ a/arch/arm64/Kconfig
> @@ -1,4 +1,4 @@
> -config ARM64
> +qconfig ARM64
>         def_bool y
>         select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
>         select ARCH_HAS_GCOV_PROFILE_ALL
> diff -puN arch/arm64/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/arm64/include/asm/elf.h
> --- a/arch/arm64/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
> +++ a/arch/arm64/include/asm/elf.h
> @@ -1,5 +1,5 @@
>  /*
> - * Copyright (C) 2012 ARM Ltd.
> + * Copyright (C) 20q12 ARM Ltd.
>   *
>   * This program is free software; you can redistribute it and/or modify
>   * it under the terms of the GNU General Public License version 2 as
> @@ -125,7 +125,6 @@ typedef struct user_fpsimd_state elf_fpr
>   * 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.
>   */
> -extern unsigned long randomize_et_dyn(unsigned long base);
>  #define ELF_ET_DYN_BASE        (randomize_et_dyn(2 * TASK_SIZE_64 / 3))
>
>  /*
> diff -puN arch/arm64/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/arm64/mm/mmap.c
> --- a/arch/arm64/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
> +++ a/arch/arm64/mm/mmap.c
> @@ -17,6 +17,7 @@
>   */
>
>  #include <linux/elf.h>
> +#include <linux/elf-randomization.h>
>  #include <linux/fs.h>
>  #include <linux/mm.h>
>  #include <linux/mman.h>
> @@ -47,7 +48,7 @@ static int mmap_is_legacy(void)
>         return sysctl_legacy_va_layout;
>  }
>
> -static unsigned long mmap_rnd(void)
> +unsigned long mmap_rnd(void)
>  {
>         unsigned long rnd = 0;
>
> @@ -89,17 +90,6 @@ void arch_pick_mmap_layout(struct mm_str
>  }
>  EXPORT_SYMBOL_GPL(arch_pick_mmap_layout);
>
> -unsigned long randomize_et_dyn(unsigned long base)
> -{
> -       unsigned long ret;
> -       if ((current->personality & ADDR_NO_RANDOMIZE) ||
> -               !(current->flags & PF_RANDOMIZE))
> -               return base;
> -       ret = base + mmap_rnd();
> -       return (ret > base) ? ret : base;
> -}
> -
> -
>  /*
>   * You really shouldn't be using read() or write() on /dev/mem.  This might go
>   * away in the future.
> diff -puN arch/mips/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/mips/Kconfig
> diff -puN arch/mips/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/mips/include/asm/elf.h
> --- a/arch/mips/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
> +++ a/arch/mips/include/asm/elf.h
> @@ -402,7 +402,6 @@ extern const char *__elf_platform;
>     that it will "exec", and that there is sufficient room for the brk. */
>
>  #ifndef ELF_ET_DYN_BASE
> -extern unsigned long randomize_et_dyn(unsigned long base);
>  #define ELF_ET_DYN_BASE                (randomize_et_dyn(TASK_SIZE / 3 * 2))
>  #endif
>
> diff -puN arch/mips/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/mips/mm/mmap.c
> --- a/arch/mips/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
> +++ a/arch/mips/mm/mmap.c
> @@ -9,6 +9,7 @@
>  #include <linux/compiler.h>
>  #include <linux/errno.h>
>  #include <linux/mm.h>
> +#include <linux/elf-randomization.h>
>  #include <linux/mman.h>
>  #include <linux/module.h>
>  #include <linux/personality.h>
> @@ -164,7 +165,7 @@ void arch_pick_mmap_layout(struct mm_str
>         }
>  }
>
> -static inline unsigned long mmap_rnd(void)
> +unsigned long mmap_rnd(void)
>  {
>         unsigned long rnd = get_random_int();
>
> @@ -196,13 +197,3 @@ int __virt_addr_valid(const volatile voi
>         return pfn_valid(PFN_DOWN(virt_to_phys(kaddr)));
>  }
>  EXPORT_SYMBOL_GPL(__virt_addr_valid);
> -
> -unsigned long randomize_et_dyn(unsigned long base)
> -{
> -       unsigned long ret;
> -       if ((current->personality & ADDR_NO_RANDOMIZE) ||
> -               !(current->flags & PF_RANDOMIZE))
> -               return base;
> -       ret = base + brk_rnd();
> -       return (ret > base) ? ret : base;
> -}
> diff -puN arch/powerpc/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/powerpc/Kconfig
> diff -puN arch/powerpc/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/powerpc/include/asm/elf.h
> --- a/arch/powerpc/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
> +++ a/arch/powerpc/include/asm/elf.h
> @@ -27,8 +27,6 @@
>     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.  */
> -
> -extern unsigned long randomize_et_dyn(unsigned long base);
>  #define ELF_ET_DYN_BASE        (randomize_et_dyn(0x20000000))
>
>  #define ELF_CORE_EFLAGS (is_elf2_task() ? 2 : 0)
> diff -puN arch/powerpc/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/powerpc/mm/mmap.c
> --- a/arch/powerpc/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
> +++ a/arch/powerpc/mm/mmap.c
> @@ -24,6 +24,7 @@
>
>  #include <linux/personality.h>
>  #include <linux/mm.h>
> +#include <linux/elf-randomization.h>
>  #include <linux/random.h>
>  #include <linux/sched.h>
>
> @@ -53,7 +54,7 @@ static inline int mmap_is_legacy(void)
>         return sysctl_legacy_va_layout;
>  }
>
> -static unsigned long mmap_rnd(void)
> +unsigned long mmap_rnd(void)
>  {
>         unsigned long rnd = 0;
>
> @@ -97,13 +98,3 @@ void arch_pick_mmap_layout(struct mm_str
>                 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
>         }
>  }
> -
> -unsigned long randomize_et_dyn(unsigned long base)
> -{
> -       unsigned long ret;
> -       if ((current->personality & ADDR_NO_RANDOMIZE) ||
> -               !(current->flags & PF_RANDOMIZE))
> -               return base;
> -       ret = base + mmap_rnd();
> -       return (ret > base) ? ret : base;
> -}
> diff -puN arch/x86/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/x86/Kconfig
> diff -puN arch/x86/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/x86/include/asm/elf.h
> --- a/arch/x86/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
> +++ a/arch/x86/include/asm/elf.h
> @@ -248,8 +248,6 @@ extern int force_personality32;
>     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.  */
> -
> -extern unsigned long randomize_et_dyn(unsigned long base);
>  #define ELF_ET_DYN_BASE                (randomize_et_dyn(TASK_SIZE / 3 * 2))
>
>  /* This yields a mask that user programs can use to figure out what
> diff -puN arch/x86/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/x86/mm/mmap.c
> --- a/arch/x86/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
> +++ a/arch/x86/mm/mmap.c
> @@ -29,6 +29,7 @@
>  #include <linux/random.h>
>  #include <linux/limits.h>
>  #include <linux/sched.h>
> +#include <linux/elf-randomization.h>
>  #include <asm/elf.h>
>
>  struct va_alignment __read_mostly va_align = {
> @@ -65,7 +66,7 @@ static int mmap_is_legacy(void)
>         return sysctl_legacy_va_layout;
>  }
>
> -static unsigned long mmap_rnd(void)
> +unsigned long mmap_rnd(void)
>  {
>         unsigned long rnd = 0;
>
> @@ -122,12 +123,3 @@ void arch_pick_mmap_layout(struct mm_str
>                 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
>         }
>  }
> -unsigned long randomize_et_dyn(unsigned long base)
> -{
> -       unsigned long ret;
> -       if ((current->personality & ADDR_NO_RANDOMIZE) ||
> -               !(current->flags & PF_RANDOMIZE))
> -               return base;
> -       ret = base + mmap_rnd();
> -       return (ret > base) ? ret : base;
> -}
> diff -puN fs/Kconfig.binfmt~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix fs/Kconfig.binfmt
> diff -puN fs/binfmt_elf.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix fs/binfmt_elf.c
> --- a/fs/binfmt_elf.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
> +++ a/fs/binfmt_elf.c
> @@ -22,6 +22,7 @@
>  #include <linux/slab.h>
>  #include <linux/personality.h>
>  #include <linux/elfcore.h>
> +#include <linux/elf-randomization.h>
>  #include <linux/init.h>
>  #include <linux/highuid.h>
>  #include <linux/compiler.h>
> @@ -2300,6 +2301,26 @@ out:
>
>  #endif         /* CONFIG_ELF_CORE */
>
> +/* Not all architectures implement mmap_rnd() */
> +unsigned long __weak mmap_rnd(void)
> +{
> +}
> +
> +/*
> + * Not all architectures use randomize_et_dyn(), so use __weak to let the
> + * linker omit it from vmlinux
> + */
> +unsigned long __weak randomize_et_dyn(unsigned long base)
> +{
> +       unsigned long ret;
> +
> +       if ((current->personality & ADDR_NO_RANDOMIZE) ||
> +               !(current->flags & PF_RANDOMIZE))
> +               return base;
> +       ret = base + mmap_rnd();
> +       return max(ret, base);
> +}
> +
>  static int __init init_elf_binfmt(void)
>  {
>         register_binfmt(&elf_format);
> diff -puN include/linux/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix include/linux/elf.h
> diff -puN /dev/null include/linux/elf-randomization.h
> --- /dev/null
> +++ a/include/linux/elf-randomization.h
> @@ -0,0 +1,7 @@
> +#ifndef __ELF_RANDOMIZATION_H
> +#define __ELF_RANDOMIZATION_H
> +
> +unsigned long randomize_et_dyn(unsigned long base);
> +unsigned long mmap_rnd(void);
> +
> +#endif /* __ELF_RANDOMIZATION_H */
> _
>



-- 
Kees Cook
Chrome OS Security

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

* [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS
@ 2015-02-26 23:34           ` Kees Cook
  0 siblings, 0 replies; 56+ messages in thread
From: Kees Cook @ 2015-02-26 23:34 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Feb 26, 2015 at 2:38 PM, Andrew Morton
<akpm@linux-foundation.org> wrote:
> On Tue, 24 Feb 2015 08:39:06 +0100 Ingo Molnar <mingo@kernel.org> wrote:
>
>>
>> * Hector Marco Gisbert <hecmargi@upv.es> wrote:
>>
>> > +unsigned long randomize_et_dyn(unsigned long base)
>> > +{
>> > +   unsigned long ret;
>> > +   if ((current->personality & ADDR_NO_RANDOMIZE) ||
>> > +           !(current->flags & PF_RANDOMIZE))
>> > +           return base;
>> > +   ret = base + mmap_rnd();
>> > +   return (ret > base) ? ret : base;
>> > +}
>>
>> > +unsigned long randomize_et_dyn(unsigned long base)
>> > +{
>> > +   unsigned long ret;
>> > +   if ((current->personality & ADDR_NO_RANDOMIZE) ||
>> > +           !(current->flags & PF_RANDOMIZE))
>> > +           return base;
>> > +   ret = base + mmap_rnd();
>> > +   return (ret > base) ? ret : base;
>> > +}
>>
>> > +unsigned long randomize_et_dyn(unsigned long base)
>> > +{
>> > +   unsigned long ret;
>> > +   if ((current->personality & ADDR_NO_RANDOMIZE) ||
>> > +           !(current->flags & PF_RANDOMIZE))
>> > +           return base;
>> > +   ret = base + brk_rnd();
>> > +   return (ret > base) ? ret : base;
>> > +}
>>
>> > +unsigned long randomize_et_dyn(unsigned long base)
>> > +{
>> > +   unsigned long ret;
>> > +   if ((current->personality & ADDR_NO_RANDOMIZE) ||
>> > +           !(current->flags & PF_RANDOMIZE))
>> > +           return base;
>> > +   ret = base + mmap_rnd();
>> > +   return (ret > base) ? ret : base;
>> > +}
>>
>> > +unsigned long randomize_et_dyn(unsigned long base)
>> > +{
>> > +   unsigned long ret;
>> > +   if ((current->personality & ADDR_NO_RANDOMIZE) ||
>> > +           !(current->flags & PF_RANDOMIZE))
>> > +           return base;
>> > +   ret = base + mmap_rnd();
>> > +   return (ret > base) ? ret : base;
>> > +}
>>
>> That pointless repetition should be avoided.
>
> That's surprisingly hard!
>
> After renaming mips brk_rnd() to mmap_rnd() I had a shot.  I'm not very
> confident in the result.  Does that __weak trick even work?

In theory, it shouldn't be needed since only randomize_et_dyn will
call mmap_rnd, and only architectures that use randomize_et_dyn will
call it ... and will define mmap_rnd.

>
> Someone tell me how important Hector's patch is?

I consider it a reasonable improvement to userspace ASLR. I look at it
more as a new feature than a bug fix, but it could be argued as a bug
fix too.

>
>
> From: Andrew Morton <akpm@linux-foundation.org>
> Subject: fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
>
> Consolidate randomize_et_dyn() implementations into fs/binfmt_elf.c.
>
> There doesn't seem to be a compile-time way of making randomize_et_dyn()
> go away on architectures which don't need it, so mark it __weak to cause
> it to be discarded at link time.
>
> Cc: "H. Peter Anvin" <hpa@zytor.com>
> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Hector Marco Gisbert <hecmargi@upv.es>
> Cc: Hector Marco-Gisbert <hecmargi@upv.es>
> Cc: Ingo Molnar <mingo@kernel.org>
> Cc: Ismael Ripoll <iripoll@upv.es>
> Cc: Kees Cook <keescook@chromium.org>
> Cc: Ralf Baechle <ralf@linux-mips.org>
> Cc: Russell King <rmk@arm.linux.org.uk>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Will Deacon <will.deacon@arm.com>
> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

Acked-by: Kees Cook <keescook@chromium.org>

Thanks for fixing it up!

-Kees

> ---
>
>  arch/arm/include/asm/elf.h        |    3 +--
>  arch/arm/mm/mmap.c                |   13 ++-----------
>  arch/arm64/Kconfig                |    2 +-
>  arch/arm64/include/asm/elf.h      |    3 +--
>  arch/arm64/mm/mmap.c              |   14 ++------------
>  arch/mips/include/asm/elf.h       |    1 -
>  arch/mips/mm/mmap.c               |   13 ++-----------
>  arch/powerpc/include/asm/elf.h    |    2 --
>  arch/powerpc/mm/mmap.c            |   13 ++-----------
>  arch/x86/include/asm/elf.h        |    2 --
>  arch/x86/mm/mmap.c                |   12 ++----------
>  fs/binfmt_elf.c                   |   21 +++++++++++++++++++++
>  include/linux/elf-randomization.h |    7 +++++++
>  13 files changed, 41 insertions(+), 65 deletions(-)
>
> diff -puN arch/arm/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/arm/Kconfig
> diff -puN arch/arm/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/arm/include/asm/elf.h
> --- a/arch/arm/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
> +++ a/arch/arm/include/asm/elf.h
> @@ -2,7 +2,7 @@
>  #define __ASMARM_ELF_H
>
>  #include <asm/hwcap.h>
> -
> +#include <linux/elf-randomization.h>
>  /*
>   * ELF register definitions..
>   */
> @@ -115,7 +115,6 @@ int dump_task_regs(struct task_struct *t
>     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.  */
>
> -extern unsigned long randomize_et_dyn(unsigned long base);
>  #define ELF_ET_DYN_BASE        (randomize_et_dyn(2 * TASK_SIZE / 3))
>
>  /* When the program starts, a1 contains a pointer to a function to be
> diff -puN arch/arm/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/arm/mm/mmap.c
> --- a/arch/arm/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
> +++ a/arch/arm/mm/mmap.c
> @@ -7,6 +7,7 @@
>  #include <linux/shm.h>
>  #include <linux/sched.h>
>  #include <linux/io.h>
> +#include <linux/elf-randomization.h>
>  #include <linux/personality.h>
>  #include <linux/random.h>
>  #include <asm/cachetype.h>
> @@ -30,7 +31,7 @@ static int mmap_is_legacy(void)
>         return sysctl_legacy_va_layout;
>  }
>
> -static unsigned long mmap_rnd(void)
> +unsigned long mmap_rnd(void)
>  {
>         unsigned long rnd = 0;
>
> @@ -241,13 +242,3 @@ int devmem_is_allowed(unsigned long pfn)
>  }
>
>  #endif
> -
> -unsigned long randomize_et_dyn(unsigned long base)
> -{
> -       unsigned long ret;
> -       if ((current->personality & ADDR_NO_RANDOMIZE) ||
> -               !(current->flags & PF_RANDOMIZE))
> -               return base;
> -       ret = base + mmap_rnd();
> -       return (ret > base) ? ret : base;
> -}
> diff -puN arch/arm64/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/arm64/Kconfig
> --- a/arch/arm64/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
> +++ a/arch/arm64/Kconfig
> @@ -1,4 +1,4 @@
> -config ARM64
> +qconfig ARM64
>         def_bool y
>         select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
>         select ARCH_HAS_GCOV_PROFILE_ALL
> diff -puN arch/arm64/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/arm64/include/asm/elf.h
> --- a/arch/arm64/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
> +++ a/arch/arm64/include/asm/elf.h
> @@ -1,5 +1,5 @@
>  /*
> - * Copyright (C) 2012 ARM Ltd.
> + * Copyright (C) 20q12 ARM Ltd.
>   *
>   * This program is free software; you can redistribute it and/or modify
>   * it under the terms of the GNU General Public License version 2 as
> @@ -125,7 +125,6 @@ typedef struct user_fpsimd_state elf_fpr
>   * 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.
>   */
> -extern unsigned long randomize_et_dyn(unsigned long base);
>  #define ELF_ET_DYN_BASE        (randomize_et_dyn(2 * TASK_SIZE_64 / 3))
>
>  /*
> diff -puN arch/arm64/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/arm64/mm/mmap.c
> --- a/arch/arm64/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
> +++ a/arch/arm64/mm/mmap.c
> @@ -17,6 +17,7 @@
>   */
>
>  #include <linux/elf.h>
> +#include <linux/elf-randomization.h>
>  #include <linux/fs.h>
>  #include <linux/mm.h>
>  #include <linux/mman.h>
> @@ -47,7 +48,7 @@ static int mmap_is_legacy(void)
>         return sysctl_legacy_va_layout;
>  }
>
> -static unsigned long mmap_rnd(void)
> +unsigned long mmap_rnd(void)
>  {
>         unsigned long rnd = 0;
>
> @@ -89,17 +90,6 @@ void arch_pick_mmap_layout(struct mm_str
>  }
>  EXPORT_SYMBOL_GPL(arch_pick_mmap_layout);
>
> -unsigned long randomize_et_dyn(unsigned long base)
> -{
> -       unsigned long ret;
> -       if ((current->personality & ADDR_NO_RANDOMIZE) ||
> -               !(current->flags & PF_RANDOMIZE))
> -               return base;
> -       ret = base + mmap_rnd();
> -       return (ret > base) ? ret : base;
> -}
> -
> -
>  /*
>   * You really shouldn't be using read() or write() on /dev/mem.  This might go
>   * away in the future.
> diff -puN arch/mips/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/mips/Kconfig
> diff -puN arch/mips/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/mips/include/asm/elf.h
> --- a/arch/mips/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
> +++ a/arch/mips/include/asm/elf.h
> @@ -402,7 +402,6 @@ extern const char *__elf_platform;
>     that it will "exec", and that there is sufficient room for the brk. */
>
>  #ifndef ELF_ET_DYN_BASE
> -extern unsigned long randomize_et_dyn(unsigned long base);
>  #define ELF_ET_DYN_BASE                (randomize_et_dyn(TASK_SIZE / 3 * 2))
>  #endif
>
> diff -puN arch/mips/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/mips/mm/mmap.c
> --- a/arch/mips/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
> +++ a/arch/mips/mm/mmap.c
> @@ -9,6 +9,7 @@
>  #include <linux/compiler.h>
>  #include <linux/errno.h>
>  #include <linux/mm.h>
> +#include <linux/elf-randomization.h>
>  #include <linux/mman.h>
>  #include <linux/module.h>
>  #include <linux/personality.h>
> @@ -164,7 +165,7 @@ void arch_pick_mmap_layout(struct mm_str
>         }
>  }
>
> -static inline unsigned long mmap_rnd(void)
> +unsigned long mmap_rnd(void)
>  {
>         unsigned long rnd = get_random_int();
>
> @@ -196,13 +197,3 @@ int __virt_addr_valid(const volatile voi
>         return pfn_valid(PFN_DOWN(virt_to_phys(kaddr)));
>  }
>  EXPORT_SYMBOL_GPL(__virt_addr_valid);
> -
> -unsigned long randomize_et_dyn(unsigned long base)
> -{
> -       unsigned long ret;
> -       if ((current->personality & ADDR_NO_RANDOMIZE) ||
> -               !(current->flags & PF_RANDOMIZE))
> -               return base;
> -       ret = base + brk_rnd();
> -       return (ret > base) ? ret : base;
> -}
> diff -puN arch/powerpc/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/powerpc/Kconfig
> diff -puN arch/powerpc/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/powerpc/include/asm/elf.h
> --- a/arch/powerpc/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
> +++ a/arch/powerpc/include/asm/elf.h
> @@ -27,8 +27,6 @@
>     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.  */
> -
> -extern unsigned long randomize_et_dyn(unsigned long base);
>  #define ELF_ET_DYN_BASE        (randomize_et_dyn(0x20000000))
>
>  #define ELF_CORE_EFLAGS (is_elf2_task() ? 2 : 0)
> diff -puN arch/powerpc/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/powerpc/mm/mmap.c
> --- a/arch/powerpc/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
> +++ a/arch/powerpc/mm/mmap.c
> @@ -24,6 +24,7 @@
>
>  #include <linux/personality.h>
>  #include <linux/mm.h>
> +#include <linux/elf-randomization.h>
>  #include <linux/random.h>
>  #include <linux/sched.h>
>
> @@ -53,7 +54,7 @@ static inline int mmap_is_legacy(void)
>         return sysctl_legacy_va_layout;
>  }
>
> -static unsigned long mmap_rnd(void)
> +unsigned long mmap_rnd(void)
>  {
>         unsigned long rnd = 0;
>
> @@ -97,13 +98,3 @@ void arch_pick_mmap_layout(struct mm_str
>                 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
>         }
>  }
> -
> -unsigned long randomize_et_dyn(unsigned long base)
> -{
> -       unsigned long ret;
> -       if ((current->personality & ADDR_NO_RANDOMIZE) ||
> -               !(current->flags & PF_RANDOMIZE))
> -               return base;
> -       ret = base + mmap_rnd();
> -       return (ret > base) ? ret : base;
> -}
> diff -puN arch/x86/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/x86/Kconfig
> diff -puN arch/x86/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/x86/include/asm/elf.h
> --- a/arch/x86/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
> +++ a/arch/x86/include/asm/elf.h
> @@ -248,8 +248,6 @@ extern int force_personality32;
>     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.  */
> -
> -extern unsigned long randomize_et_dyn(unsigned long base);
>  #define ELF_ET_DYN_BASE                (randomize_et_dyn(TASK_SIZE / 3 * 2))
>
>  /* This yields a mask that user programs can use to figure out what
> diff -puN arch/x86/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix arch/x86/mm/mmap.c
> --- a/arch/x86/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
> +++ a/arch/x86/mm/mmap.c
> @@ -29,6 +29,7 @@
>  #include <linux/random.h>
>  #include <linux/limits.h>
>  #include <linux/sched.h>
> +#include <linux/elf-randomization.h>
>  #include <asm/elf.h>
>
>  struct va_alignment __read_mostly va_align = {
> @@ -65,7 +66,7 @@ static int mmap_is_legacy(void)
>         return sysctl_legacy_va_layout;
>  }
>
> -static unsigned long mmap_rnd(void)
> +unsigned long mmap_rnd(void)
>  {
>         unsigned long rnd = 0;
>
> @@ -122,12 +123,3 @@ void arch_pick_mmap_layout(struct mm_str
>                 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
>         }
>  }
> -unsigned long randomize_et_dyn(unsigned long base)
> -{
> -       unsigned long ret;
> -       if ((current->personality & ADDR_NO_RANDOMIZE) ||
> -               !(current->flags & PF_RANDOMIZE))
> -               return base;
> -       ret = base + mmap_rnd();
> -       return (ret > base) ? ret : base;
> -}
> diff -puN fs/Kconfig.binfmt~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix fs/Kconfig.binfmt
> diff -puN fs/binfmt_elf.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix fs/binfmt_elf.c
> --- a/fs/binfmt_elf.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix
> +++ a/fs/binfmt_elf.c
> @@ -22,6 +22,7 @@
>  #include <linux/slab.h>
>  #include <linux/personality.h>
>  #include <linux/elfcore.h>
> +#include <linux/elf-randomization.h>
>  #include <linux/init.h>
>  #include <linux/highuid.h>
>  #include <linux/compiler.h>
> @@ -2300,6 +2301,26 @@ out:
>
>  #endif         /* CONFIG_ELF_CORE */
>
> +/* Not all architectures implement mmap_rnd() */
> +unsigned long __weak mmap_rnd(void)
> +{
> +}
> +
> +/*
> + * Not all architectures use randomize_et_dyn(), so use __weak to let the
> + * linker omit it from vmlinux
> + */
> +unsigned long __weak randomize_et_dyn(unsigned long base)
> +{
> +       unsigned long ret;
> +
> +       if ((current->personality & ADDR_NO_RANDOMIZE) ||
> +               !(current->flags & PF_RANDOMIZE))
> +               return base;
> +       ret = base + mmap_rnd();
> +       return max(ret, base);
> +}
> +
>  static int __init init_elf_binfmt(void)
>  {
>         register_binfmt(&elf_format);
> diff -puN include/linux/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix include/linux/elf.h
> diff -puN /dev/null include/linux/elf-randomization.h
> --- /dev/null
> +++ a/include/linux/elf-randomization.h
> @@ -0,0 +1,7 @@
> +#ifndef __ELF_RANDOMIZATION_H
> +#define __ELF_RANDOMIZATION_H
> +
> +unsigned long randomize_et_dyn(unsigned long base);
> +unsigned long mmap_rnd(void);
> +
> +#endif /* __ELF_RANDOMIZATION_H */
> _
>



-- 
Kees Cook
Chrome OS Security

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

* Re: [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS
@ 2015-02-26 23:39             ` Andrew Morton
  0 siblings, 0 replies; 56+ messages in thread
From: Andrew Morton @ 2015-02-26 23:39 UTC (permalink / raw)
  To: Kees Cook
  Cc: Ingo Molnar, Hector Marco Gisbert, LKML, ismael Ripoll, x86,
	linux-arm-kernel, Linux MIPS Mailing List, linuxppc-dev

On Thu, 26 Feb 2015 15:34:36 -0800 Kees Cook <keescook@chromium.org> wrote:

> >> That pointless repetition should be avoided.
> >
> > That's surprisingly hard!
> >
> > After renaming mips brk_rnd() to mmap_rnd() I had a shot.  I'm not very
> > confident in the result.  Does that __weak trick even work?
> 
> In theory, it shouldn't be needed since only randomize_et_dyn will
> call mmap_rnd, and only architectures that use randomize_et_dyn will
> call it ... and will define mmap_rnd.

But randomize_et_dyn() is compiled for all architectures.  Or it was,
until I did the CONFIG_ARCH_HAVE_ELF_ASLR thing.

It seems odd that we have this per-arch feature but no Kconfig switch
for it.


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

* Re: [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS
@ 2015-02-26 23:39             ` Andrew Morton
  0 siblings, 0 replies; 56+ messages in thread
From: Andrew Morton @ 2015-02-26 23:39 UTC (permalink / raw)
  To: Kees Cook
  Cc: Ingo Molnar, Hector Marco Gisbert, LKML, ismael Ripoll, x86,
	linux-arm-kernel, Linux MIPS Mailing List, linuxppc-dev

On Thu, 26 Feb 2015 15:34:36 -0800 Kees Cook <keescook@chromium.org> wrote:

> >> That pointless repetition should be avoided.
> >
> > That's surprisingly hard!
> >
> > After renaming mips brk_rnd() to mmap_rnd() I had a shot.  I'm not very
> > confident in the result.  Does that __weak trick even work?
> 
> In theory, it shouldn't be needed since only randomize_et_dyn will
> call mmap_rnd, and only architectures that use randomize_et_dyn will
> call it ... and will define mmap_rnd.

But randomize_et_dyn() is compiled for all architectures.  Or it was,
until I did the CONFIG_ARCH_HAVE_ELF_ASLR thing.

It seems odd that we have this per-arch feature but no Kconfig switch
for it.

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

* Re: [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS
@ 2015-02-26 23:39             ` Andrew Morton
  0 siblings, 0 replies; 56+ messages in thread
From: Andrew Morton @ 2015-02-26 23:39 UTC (permalink / raw)
  To: Kees Cook
  Cc: Linux MIPS Mailing List, x86, Hector Marco Gisbert, LKML,
	ismael Ripoll, linuxppc-dev, Ingo Molnar, linux-arm-kernel

On Thu, 26 Feb 2015 15:34:36 -0800 Kees Cook <keescook@chromium.org> wrote:

> >> That pointless repetition should be avoided.
> >
> > That's surprisingly hard!
> >
> > After renaming mips brk_rnd() to mmap_rnd() I had a shot.  I'm not very
> > confident in the result.  Does that __weak trick even work?
> 
> In theory, it shouldn't be needed since only randomize_et_dyn will
> call mmap_rnd, and only architectures that use randomize_et_dyn will
> call it ... and will define mmap_rnd.

But randomize_et_dyn() is compiled for all architectures.  Or it was,
until I did the CONFIG_ARCH_HAVE_ELF_ASLR thing.

It seems odd that we have this per-arch feature but no Kconfig switch
for it.

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

* [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS
@ 2015-02-26 23:39             ` Andrew Morton
  0 siblings, 0 replies; 56+ messages in thread
From: Andrew Morton @ 2015-02-26 23:39 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, 26 Feb 2015 15:34:36 -0800 Kees Cook <keescook@chromium.org> wrote:

> >> That pointless repetition should be avoided.
> >
> > That's surprisingly hard!
> >
> > After renaming mips brk_rnd() to mmap_rnd() I had a shot.  I'm not very
> > confident in the result.  Does that __weak trick even work?
> 
> In theory, it shouldn't be needed since only randomize_et_dyn will
> call mmap_rnd, and only architectures that use randomize_et_dyn will
> call it ... and will define mmap_rnd.

But randomize_et_dyn() is compiled for all architectures.  Or it was,
until I did the CONFIG_ARCH_HAVE_ELF_ASLR thing.

It seems odd that we have this per-arch feature but no Kconfig switch
for it.

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

* Re: [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS
@ 2015-02-27  0:06                 ` Andrew Morton
  0 siblings, 0 replies; 56+ messages in thread
From: Andrew Morton @ 2015-02-27  0:06 UTC (permalink / raw)
  To: Kees Cook
  Cc: Stephen Rothwell, Ingo Molnar, Hector Marco Gisbert, LKML,
	ismael Ripoll, x86,
	linux-arm-kernel@lists.infradead.org"
	<linux-arm-kernel@lists.infradead.org>,
	Linux MIPS Mailing List <linux-mips@linux-mips.org>,
	linuxppc-dev@lists.ozlabs.org

On Thu, 26 Feb 2015 15:37:37 -0800 Kees Cook <keescook@chromium.org> wrote:

> Agh, no, please let's avoid the CONFIG addition.

That is precisely how we do this.

> Hector mentioned in private mail that he was looking at an alternative
> that adds exec_base to struct mm which would avoid all this insanity.
> 
> Can't we do something like:
> 
> #ifndef mmap_rnd
> # define mmap_rnd 0
> #endif

Sure, and sprinkle

#define mmap_rnd mmap_rnd

in five arch header files where nobody thinks to look.

For better or for worse, we are consolidating such things into arch/*/Kconfig.

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

* Re: [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS
@ 2015-02-27  0:06                 ` Andrew Morton
  0 siblings, 0 replies; 56+ messages in thread
From: Andrew Morton @ 2015-02-27  0:06 UTC (permalink / raw)
  To: Kees Cook
  Cc: Stephen Rothwell, Ingo Molnar, Hector Marco Gisbert, LKML,
	ismael Ripoll, x86,
	linux-arm-kernel@lists.infradead.org"
	<linux-arm-kernel@lists.infradead.org>,
	Linux MIPS Mailing List <linux-mips@linux-mips.org>,
	linuxppc-dev@lists.ozlabs.org

On Thu, 26 Feb 2015 15:37:37 -0800 Kees Cook <keescook@chromium.org> wrote:

> Agh, no, please let's avoid the CONFIG addition.

That is precisely how we do this.

> Hector mentioned in private mail that he was looking at an alternative
> that adds exec_base to struct mm which would avoid all this insanity.
> 
> Can't we do something like:
> 
> #ifndef mmap_rnd
> # define mmap_rnd 0
> #endif

Sure, and sprinkle

#define mmap_rnd mmap_rnd

in five arch header files where nobody thinks to look.

For better or for worse, we are consolidating such things into arch/*/Kconfig.

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

* Re: [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS
@ 2015-02-27  0:06                 ` Andrew Morton
  0 siblings, 0 replies; 56+ messages in thread
From: Andrew Morton @ 2015-02-27  0:06 UTC (permalink / raw)
  To: Kees Cook
  Cc: Stephen Rothwell, x86, Hector Marco Gisbert, LKML,
	linux-arm-kernel@lists.infradead.org"
	<linux-arm-kernel@lists.infradead.org>,
	Linux MIPS Mailing List <linux-mips@linux-mips.org>,
	linuxppc-dev@lists.ozlabs.org, Ingo Molnar, ismael Ripoll

On Thu, 26 Feb 2015 15:37:37 -0800 Kees Cook <keescook@chromium.org> wrote:

> Agh, no, please let's avoid the CONFIG addition.

That is precisely how we do this.

> Hector mentioned in private mail that he was looking at an alternative
> that adds exec_base to struct mm which would avoid all this insanity.
> 
> Can't we do something like:
> 
> #ifndef mmap_rnd
> # define mmap_rnd 0
> #endif

Sure, and sprinkle

#define mmap_rnd mmap_rnd

in five arch header files where nobody thinks to look.

For better or for worse, we are consolidating such things into arch/*/Kconfig.

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

* Re: [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS
@ 2015-02-27  0:20                     ` Kees Cook
  0 siblings, 0 replies; 56+ messages in thread
From: Kees Cook @ 2015-02-27  0:20 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Stephen Rothwell, Ingo Molnar, Hector Marco Gisbert, LKML,
	ismael Ripoll, x86, linuxppc-dev, linux-arm-kernel,
	Linux MIPS Mailing List

On Thu, Feb 26, 2015 at 4:11 PM, Kees Cook <keescook@chromium.org> wrote:
> On Thu, Feb 26, 2015 at 4:06 PM, Andrew Morton
> <akpm@linux-foundation.org> wrote:
>> On Thu, 26 Feb 2015 15:37:37 -0800 Kees Cook <keescook@chromium.org> wrote:
>>
>>> Agh, no, please let's avoid the CONFIG addition.
>>
>> That is precisely how we do this.
>>
>>> Hector mentioned in private mail that he was looking at an alternative
>>> that adds exec_base to struct mm which would avoid all this insanity.
>>>
>>> Can't we do something like:
>>>
>>> #ifndef mmap_rnd
>>> # define mmap_rnd 0
>>> #endif
>>
>> Sure, and sprinkle
>>
>> #define mmap_rnd mmap_rnd
>>
>> in five arch header files where nobody thinks to look.
>>
>> For better or for worse, we are consolidating such things into arch/*/Kconfig.
>
> Okay, fair enough. Even with your configs (though shouldn't they be
> ARCH_HAS or just HAVE?) I've now stumbled over the issue that we can't
> put randomize_et_dyn in binfmt_elf because it conflicts with linking
> against compat_binfmt_elf.

Instead of all this, how about we rework the existing CONFIG and just
change around how s390 does this to match the other architectures and
remove the ifdef in binfmt_elf.c at the same time? Let me work
something up...

-Kees

-- 
Kees Cook
Chrome OS Security

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

* Re: [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS
@ 2015-02-27  0:20                     ` Kees Cook
  0 siblings, 0 replies; 56+ messages in thread
From: Kees Cook @ 2015-02-27  0:20 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Stephen Rothwell, Ingo Molnar, Hector Marco Gisbert, LKML,
	ismael Ripoll, x86, linuxppc-dev, linux-arm-kernel,
	Linux MIPS Mailing List

On Thu, Feb 26, 2015 at 4:11 PM, Kees Cook <keescook@chromium.org> wrote:
> On Thu, Feb 26, 2015 at 4:06 PM, Andrew Morton
> <akpm@linux-foundation.org> wrote:
>> On Thu, 26 Feb 2015 15:37:37 -0800 Kees Cook <keescook@chromium.org> wrote:
>>
>>> Agh, no, please let's avoid the CONFIG addition.
>>
>> That is precisely how we do this.
>>
>>> Hector mentioned in private mail that he was looking at an alternative
>>> that adds exec_base to struct mm which would avoid all this insanity.
>>>
>>> Can't we do something like:
>>>
>>> #ifndef mmap_rnd
>>> # define mmap_rnd 0
>>> #endif
>>
>> Sure, and sprinkle
>>
>> #define mmap_rnd mmap_rnd
>>
>> in five arch header files where nobody thinks to look.
>>
>> For better or for worse, we are consolidating such things into arch/*/Kconfig.
>
> Okay, fair enough. Even with your configs (though shouldn't they be
> ARCH_HAS or just HAVE?) I've now stumbled over the issue that we can't
> put randomize_et_dyn in binfmt_elf because it conflicts with linking
> against compat_binfmt_elf.

Instead of all this, how about we rework the existing CONFIG and just
change around how s390 does this to match the other architectures and
remove the ifdef in binfmt_elf.c at the same time? Let me work
something up...

-Kees

-- 
Kees Cook
Chrome OS Security

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

* Re: [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS
@ 2015-02-27  0:20                     ` Kees Cook
  0 siblings, 0 replies; 56+ messages in thread
From: Kees Cook @ 2015-02-27  0:20 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Stephen Rothwell, Linux MIPS Mailing List, x86,
	Hector Marco Gisbert, LKML, linux-arm-kernel, linuxppc-dev,
	Ingo Molnar, ismael Ripoll

On Thu, Feb 26, 2015 at 4:11 PM, Kees Cook <keescook@chromium.org> wrote:
> On Thu, Feb 26, 2015 at 4:06 PM, Andrew Morton
> <akpm@linux-foundation.org> wrote:
>> On Thu, 26 Feb 2015 15:37:37 -0800 Kees Cook <keescook@chromium.org> wrote:
>>
>>> Agh, no, please let's avoid the CONFIG addition.
>>
>> That is precisely how we do this.
>>
>>> Hector mentioned in private mail that he was looking at an alternative
>>> that adds exec_base to struct mm which would avoid all this insanity.
>>>
>>> Can't we do something like:
>>>
>>> #ifndef mmap_rnd
>>> # define mmap_rnd 0
>>> #endif
>>
>> Sure, and sprinkle
>>
>> #define mmap_rnd mmap_rnd
>>
>> in five arch header files where nobody thinks to look.
>>
>> For better or for worse, we are consolidating such things into arch/*/Kconfig.
>
> Okay, fair enough. Even with your configs (though shouldn't they be
> ARCH_HAS or just HAVE?) I've now stumbled over the issue that we can't
> put randomize_et_dyn in binfmt_elf because it conflicts with linking
> against compat_binfmt_elf.

Instead of all this, how about we rework the existing CONFIG and just
change around how s390 does this to match the other architectures and
remove the ifdef in binfmt_elf.c at the same time? Let me work
something up...

-Kees

-- 
Kees Cook
Chrome OS Security

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

* [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS
@ 2015-02-27  0:20                     ` Kees Cook
  0 siblings, 0 replies; 56+ messages in thread
From: Kees Cook @ 2015-02-27  0:20 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Feb 26, 2015 at 4:11 PM, Kees Cook <keescook@chromium.org> wrote:
> On Thu, Feb 26, 2015 at 4:06 PM, Andrew Morton
> <akpm@linux-foundation.org> wrote:
>> On Thu, 26 Feb 2015 15:37:37 -0800 Kees Cook <keescook@chromium.org> wrote:
>>
>>> Agh, no, please let's avoid the CONFIG addition.
>>
>> That is precisely how we do this.
>>
>>> Hector mentioned in private mail that he was looking at an alternative
>>> that adds exec_base to struct mm which would avoid all this insanity.
>>>
>>> Can't we do something like:
>>>
>>> #ifndef mmap_rnd
>>> # define mmap_rnd 0
>>> #endif
>>
>> Sure, and sprinkle
>>
>> #define mmap_rnd mmap_rnd
>>
>> in five arch header files where nobody thinks to look.
>>
>> For better or for worse, we are consolidating such things into arch/*/Kconfig.
>
> Okay, fair enough. Even with your configs (though shouldn't they be
> ARCH_HAS or just HAVE?) I've now stumbled over the issue that we can't
> put randomize_et_dyn in binfmt_elf because it conflicts with linking
> against compat_binfmt_elf.

Instead of all this, how about we rework the existing CONFIG and just
change around how s390 does this to match the other architectures and
remove the ifdef in binfmt_elf.c at the same time? Let me work
something up...

-Kees

-- 
Kees Cook
Chrome OS Security

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

end of thread, other threads:[~2015-02-27  0:20 UTC | newest]

Thread overview: 56+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-02-23 18:37 [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS Hector Marco
2015-02-23 19:34 ` Kees Cook
2015-02-23 19:34   ` Kees Cook
2015-02-23 19:34   ` Kees Cook
2015-02-23 19:34   ` Kees Cook
2015-02-23 19:54   ` Hector Marco Gisbert
2015-02-23 19:54     ` Hector Marco Gisbert
2015-02-23 19:54     ` Hector Marco Gisbert
2015-02-23 19:54     ` Hector Marco Gisbert
2015-02-24  7:39     ` Ingo Molnar
2015-02-24  7:39       ` Ingo Molnar
2015-02-24  7:39       ` Ingo Molnar
2015-02-24  7:39       ` Ingo Molnar
2015-02-26 22:38       ` Andrew Morton
2015-02-26 22:38         ` Andrew Morton
2015-02-26 22:38         ` Andrew Morton
2015-02-26 22:38         ` Andrew Morton
2015-02-26 22:43         ` David Daney
2015-02-26 22:43           ` David Daney
2015-02-26 22:43           ` David Daney
2015-02-26 22:43           ` David Daney
2015-02-26 23:00         ` Russell King - ARM Linux
2015-02-26 23:00           ` Russell King - ARM Linux
2015-02-26 23:00           ` Russell King - ARM Linux
2015-02-26 23:00           ` Russell King - ARM Linux
2015-02-26 23:05           ` Andrew Morton
2015-02-26 23:05             ` Andrew Morton
2015-02-26 23:05             ` Andrew Morton
2015-02-26 23:05             ` Andrew Morton
2015-02-26 23:03         ` Andrew Morton
2015-02-26 23:03           ` Andrew Morton
2015-02-26 23:03           ` Andrew Morton
2015-02-26 23:21         ` Stephen Rothwell
2015-02-26 23:21           ` Stephen Rothwell
2015-02-26 23:21           ` Stephen Rothwell
2015-02-26 23:34           ` Andrew Morton
2015-02-26 23:34             ` Andrew Morton
     [not found]             ` <CAGXu5jK0YbyL+Z=YrCfkfGbYz6=65Rr_MAXLwrF36gJa2Ce4_w@mail.gmail.com>
2015-02-27  0:06               ` Andrew Morton
2015-02-27  0:06                 ` Andrew Morton
2015-02-27  0:06                 ` Andrew Morton
     [not found]                 ` <CAGXu5j+3D7FrAJNLHTgEuK5wnOmUZG13xxi6eONuWiY2zKCMqQ@mail.gmail.com>
2015-02-27  0:20                   ` Kees Cook
2015-02-27  0:20                     ` Kees Cook
2015-02-27  0:20                     ` Kees Cook
2015-02-27  0:20                     ` Kees Cook
2015-02-26 23:26         ` Stephen Rothwell
2015-02-26 23:26           ` Stephen Rothwell
2015-02-26 23:26           ` Stephen Rothwell
2015-02-26 23:26           ` Stephen Rothwell
2015-02-26 23:34         ` Kees Cook
2015-02-26 23:34           ` Kees Cook
2015-02-26 23:34           ` Kees Cook
2015-02-26 23:34           ` Kees Cook
2015-02-26 23:39           ` Andrew Morton
2015-02-26 23:39             ` Andrew Morton
2015-02-26 23:39             ` Andrew Morton
2015-02-26 23:39             ` Andrew Morton

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.