* Re: [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS [not found] <54EB735F.5030207@upv.es> @ 2015-02-23 19:34 ` Kees Cook 2015-02-23 19:54 ` Hector Marco Gisbert 0 siblings, 1 reply; 15+ 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@kernel.org, LKML, ismael Ripoll, linuxppc-dev, linux-arm-kernel@lists.infradead.org (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] 15+ messages in thread
* Re: [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS 2015-02-23 19:34 ` [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS Kees Cook @ 2015-02-23 19:54 ` Hector Marco Gisbert 2015-02-24 7:39 ` Ingo Molnar 0 siblings, 1 reply; 15+ messages in thread From: Hector Marco Gisbert @ 2015-02-23 19:54 UTC (permalink / raw) To: Kees Cook Cc: Linux MIPS Mailing List, x86@kernel.org, LKML, ismael Ripoll, Andrew Morton, linuxppc-dev, linux-arm-kernel@lists.infradead.org [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] 15+ messages in thread
* Re: [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS 2015-02-23 19:54 ` Hector Marco Gisbert @ 2015-02-24 7:39 ` Ingo Molnar 2015-02-26 22:38 ` Andrew Morton 0 siblings, 1 reply; 15+ 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@kernel.org, LKML, ismael Ripoll, Andrew Morton, linuxppc-dev, linux-arm-kernel@lists.infradead.org * 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] 15+ messages in thread
* Re: [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS 2015-02-24 7:39 ` Ingo Molnar @ 2015-02-26 22:38 ` Andrew Morton 2015-02-26 22:43 ` David Daney ` (5 more replies) 0 siblings, 6 replies; 15+ 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@kernel.org, Hector Marco Gisbert, LKML, ismael Ripoll, linuxppc-dev, linux-arm-kernel@lists.infradead.org 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] 15+ messages in thread
* Re: [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS 2015-02-26 22:38 ` Andrew Morton @ 2015-02-26 22:43 ` David Daney 2015-02-26 23:00 ` Russell King - ARM Linux ` (4 subsequent siblings) 5 siblings, 0 replies; 15+ 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@kernel.org, Hector Marco Gisbert, LKML, linux-arm-kernel@lists.infradead.org, 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] 15+ messages in thread
* Re: [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS 2015-02-26 22:38 ` Andrew Morton 2015-02-26 22:43 ` David Daney @ 2015-02-26 23:00 ` Russell King - ARM Linux 2015-02-26 23:05 ` Andrew Morton 2015-02-26 23:03 ` Andrew Morton ` (3 subsequent siblings) 5 siblings, 1 reply; 15+ 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@kernel.org, Hector Marco Gisbert, LKML, linux-arm-kernel@lists.infradead.org, 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] 15+ messages in thread
* Re: [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS 2015-02-26 23:00 ` Russell King - ARM Linux @ 2015-02-26 23:05 ` Andrew Morton 0 siblings, 0 replies; 15+ 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@kernel.org, Hector Marco Gisbert, LKML, linux-arm-kernel@lists.infradead.org, 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] 15+ messages in thread
* Re: [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS 2015-02-26 22:38 ` Andrew Morton 2015-02-26 22:43 ` David Daney 2015-02-26 23:00 ` Russell King - ARM Linux @ 2015-02-26 23:03 ` Andrew Morton 2015-02-26 23:21 ` Stephen Rothwell ` (2 subsequent siblings) 5 siblings, 0 replies; 15+ 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@kernel.org, linux-arm-kernel@lists.infradead.org, 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] 15+ messages in thread
* Re: [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS 2015-02-26 22:38 ` Andrew Morton ` (2 preceding siblings ...) 2015-02-26 23:03 ` Andrew Morton @ 2015-02-26 23:21 ` Stephen Rothwell 2015-02-26 23:34 ` Andrew Morton 2015-02-26 23:26 ` Stephen Rothwell 2015-02-26 23:34 ` Kees Cook 5 siblings, 1 reply; 15+ messages in thread From: Stephen Rothwell @ 2015-02-26 23:21 UTC (permalink / raw) To: Andrew Morton Cc: Kees Cook, x86@kernel.org, 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] 15+ 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 [not found] ` <CAGXu5jK0YbyL+Z=YrCfkfGbYz6=65Rr_MAXLwrF36gJa2Ce4_w@mail.gmail.com> 0 siblings, 1 reply; 15+ messages in thread From: Andrew Morton @ 2015-02-26 23:34 UTC (permalink / raw) To: Stephen Rothwell Cc: Kees Cook, x86@kernel.org, Hector Marco Gisbert, LKML, "linux-arm-kernel, 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] 15+ messages in thread
[parent not found: <CAGXu5jK0YbyL+Z=YrCfkfGbYz6=65Rr_MAXLwrF36gJa2Ce4_w@mail.gmail.com>]
* Re: [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS [not found] ` <CAGXu5jK0YbyL+Z=YrCfkfGbYz6=65Rr_MAXLwrF36gJa2Ce4_w@mail.gmail.com> @ 2015-02-27 0:06 ` Andrew Morton [not found] ` <CAGXu5j+3D7FrAJNLHTgEuK5wnOmUZG13xxi6eONuWiY2zKCMqQ@mail.gmail.com> 0 siblings, 1 reply; 15+ messages in thread From: Andrew Morton @ 2015-02-27 0:06 UTC (permalink / raw) To: Kees Cook Cc: Stephen Rothwell, x86@kernel.org, Hector Marco Gisbert, LKML, "linux-arm-kernel, 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] 15+ messages in thread
[parent not found: <CAGXu5j+3D7FrAJNLHTgEuK5wnOmUZG13xxi6eONuWiY2zKCMqQ@mail.gmail.com>]
* Re: [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS [not found] ` <CAGXu5j+3D7FrAJNLHTgEuK5wnOmUZG13xxi6eONuWiY2zKCMqQ@mail.gmail.com> @ 2015-02-27 0:20 ` Kees Cook 0 siblings, 0 replies; 15+ 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@kernel.org, Hector Marco Gisbert, LKML, linux-arm-kernel@lists.infradead.org, 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] 15+ messages in thread
* Re: [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS 2015-02-26 22:38 ` Andrew Morton ` (3 preceding siblings ...) 2015-02-26 23:21 ` Stephen Rothwell @ 2015-02-26 23:26 ` Stephen Rothwell 2015-02-26 23:34 ` Kees Cook 5 siblings, 0 replies; 15+ 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] 15+ messages in thread
* Re: [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS 2015-02-26 22:38 ` Andrew Morton ` (4 preceding siblings ...) 2015-02-26 23:26 ` Stephen Rothwell @ 2015-02-26 23:34 ` Kees Cook 2015-02-26 23:39 ` Andrew Morton 5 siblings, 1 reply; 15+ messages in thread From: Kees Cook @ 2015-02-26 23:34 UTC (permalink / raw) To: Andrew Morton Cc: Linux MIPS Mailing List, x86@kernel.org, Hector Marco Gisbert, LKML, ismael Ripoll, linuxppc-dev, Ingo Molnar, linux-arm-kernel@lists.infradead.org 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] 15+ messages in thread
* Re: [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS 2015-02-26 23:34 ` Kees Cook @ 2015-02-26 23:39 ` Andrew Morton 0 siblings, 0 replies; 15+ messages in thread From: Andrew Morton @ 2015-02-26 23:39 UTC (permalink / raw) To: Kees Cook Cc: Linux MIPS Mailing List, x86@kernel.org, Hector Marco Gisbert, LKML, ismael Ripoll, linuxppc-dev, Ingo Molnar, linux-arm-kernel@lists.infradead.org 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] 15+ messages in thread
end of thread, other threads:[~2015-02-27 0:20 UTC | newest] Thread overview: 15+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- [not found] <54EB735F.5030207@upv.es> 2015-02-23 19:34 ` [PATCH] Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS Kees Cook 2015-02-23 19:54 ` Hector Marco Gisbert 2015-02-24 7:39 ` Ingo Molnar 2015-02-26 22:38 ` Andrew Morton 2015-02-26 22:43 ` David Daney 2015-02-26 23:00 ` Russell King - ARM Linux 2015-02-26 23:05 ` Andrew Morton 2015-02-26 23:03 ` Andrew Morton 2015-02-26 23:21 ` Stephen Rothwell 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 [not found] ` <CAGXu5j+3D7FrAJNLHTgEuK5wnOmUZG13xxi6eONuWiY2zKCMqQ@mail.gmail.com> 2015-02-27 0:20 ` Kees Cook 2015-02-26 23:26 ` Stephen Rothwell 2015-02-26 23:34 ` Kees Cook 2015-02-26 23:39 ` Andrew Morton
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).