Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS
Subsystems (8)
PATCH 1/1 Fix offset2lib issue for x86*, ARM*, PowerPC and MIPS
[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
arch/arm/Kconfig +0 -1
@@ -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
arch/arm/include/asm/elf.h +2 -1
@@ -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
arch/arm/mm/mmap.c +21 -0
@@ -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; +}
arch/arm64/Kconfig +0 -1
@@ -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
arch/arm64/include/asm/elf.h +2 -2
@@ -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
arch/arm64/mm/mmap.c +10 -0
@@ -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
arch/mips/Kconfig +0 -1
@@ -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
arch/mips/include/asm/elf.h +2 -1
@@ -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
arch/mips/mm/mmap.c +10 -0
@@ -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; +}
arch/powerpc/Kconfig +0 -1
@@ -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
arch/powerpc/include/asm/elf.h +2 -1
@@ -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)
arch/powerpc/mm/mmap.c +10 -0
@@ -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; +}
arch/x86/Kconfig +0 -1
@@ -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
arch/x86/include/asm/elf.h +2 -1
@@ -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,
arch/x86/mm/mmap.c +9 -0
@@ -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; +}
fs/Kconfig.binfmt +0 -2
@@ -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
fs/binfmt_elf.c +0 -14
@@ -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'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?
Quoted 37 lines · Hector Marco
[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.htmlThis 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]
Quoted 1 line
Once corrected, the PIE linked application is loaded in a different area.
Thanks for working on this!
Quoted 7 lines
We updated the "Fixing Offset2lib weakness" page:
http://cybersecurity.upv.es/solutions/aslrv2/aslrv2.htmlSigned-off-by Hector Marco-Gisbert <[email protected]>Signed-off-by Ismael Ripoll <[email protected]>
Quoted 294 lines
arch/arm/Kconfig +0
-1@@ -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_Harch/arm/include/asm/elf.h +0
-0@@ -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 theprogram
that it will "exec", and that there is sufficient room for the brk. */arch/arm/include/asm/elf.h +2
-1-#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 arch/arm/mm/mmap.c +21
-0@@ -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; +}arch/arm64/Kconfig +0
-1@@ -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_CHAINarch/arm64/include/asm/elf.h +2
-2@@ -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. */
#defineCOMPAT_ELF_NGREG18arch/arm64/mm/mmap.c +10
-0@@ -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
arch/mips/Kconfig +0
-1@@ -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
selectRTC_LIBif !MACH_LOONGSON
selectGENERIC_ATOMIC64if !64BITarch/mips/include/asm/elf.h +2
-1@@ -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_PAGES1arch/mips/mm/mmap.c +10
-0@@ -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; +}arch/powerpc/Kconfig +0
-1@@ -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_MEMarch/powerpc/include/asm/elf.h +0
-0@@ -28,7 +28,8 @@ the loader. We need to make sure that it is out of the way of theprogram
that it will "exec", and that there is sufficient room for the brk. */arch/powerpc/include/asm/elf.h +2
-1-#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)arch/powerpc/mm/mmap.c +10
-0@@ -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; +}arch/x86/Kconfig +0
-1@@ -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_IRQarch/x86/include/asm/elf.h +0
-0@@ -249,7 +249,8 @@ extern int force_personality32; the loader. We need to make sure that it is out of the way of theprogram
that it will "exec", and that there is sufficient room for the brk. */arch/x86/include/asm/elf.h +2
-1-#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,arch/x86/mm/mmap.c +9
-0@@ -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; +}fs/Kconfig.binfmt +0
-2@@ -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 boolfs/binfmt_elf.c +0
-0@@ -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. */fs/binfmt_elf.c +0
-12-#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);
fs/binfmt_elf.c static int load_elf_binary(struct linux_binprm *bprm) · line 914
Quoted 6 lines
fs/binfmt_elf.c +0
-2-#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
Signature · 2 lines
Kees Cook Chrome OS Security
[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
arch/arm/Kconfig +0 -1
@@ -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
arch/arm/include/asm/elf.h +0 -0
@@ -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
arch/arm/mm/mmap.c +21 -0
@@ -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; +}
arch/arm64/Kconfig +0 -1
@@ -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
arch/arm64/include/asm/elf.h +1 -1
@@ -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
arch/arm64/mm/mmap.c +10 -0
@@ -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
arch/mips/Kconfig +0 -1
@@ -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
arch/mips/include/asm/elf.h +2 -1
@@ -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
arch/mips/mm/mmap.c +10 -0
@@ -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; +}
arch/powerpc/Kconfig +0 -1
@@ -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
arch/powerpc/include/asm/elf.h +2 -1
@@ -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)
arch/powerpc/mm/mmap.c +10 -0
@@ -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; +}
arch/x86/Kconfig +0 -1
@@ -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
arch/x86/include/asm/elf.h +2 -1
@@ -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,
arch/x86/mm/mmap.c +9 -0
@@ -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; +}
fs/Kconfig.binfmt +0 -2
@@ -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
fs/binfmt_elf.c +0 -14
@@ -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 <[email protected]> escribi?:
Quoted 374 lines
(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?
Quoted 37 lines · Hector Marco
[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.htmlThis 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]Quoted 1 line
Once corrected, the PIE linked application is loaded in a different area.
Thanks for working on this!
Quoted 7 lines
We updated the "Fixing Offset2lib weakness" page:
http://cybersecurity.upv.es/solutions/aslrv2/aslrv2.htmlSigned-off-by Hector Marco-Gisbert <[email protected]>Signed-off-by Ismael Ripoll <[email protected]>Acked-by Kees Cook <[email protected]>Quoted 294 lines
arch/arm/Kconfig +0
-1@@ -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_Harch/arm/include/asm/elf.h +0
-0@@ -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 theprogram
that it will "exec", and that there is sufficient room for the brk. */arch/arm/include/asm/elf.h +2
-1-#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 arch/arm/mm/mmap.c +21
-0@@ -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; +}arch/arm64/Kconfig +0
-1@@ -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_CHAINarch/arm64/include/asm/elf.h +2
-2@@ -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. */
#defineCOMPAT_ELF_NGREG18arch/arm64/mm/mmap.c +10
-0@@ -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
arch/mips/Kconfig +0
-1@@ -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
selectRTC_LIBif !MACH_LOONGSON
selectGENERIC_ATOMIC64if !64BITarch/mips/include/asm/elf.h +2
-1@@ -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_PAGES1arch/mips/mm/mmap.c +10
-0@@ -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; +}arch/powerpc/Kconfig +0
-1@@ -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_MEMarch/powerpc/include/asm/elf.h +0
-0@@ -28,7 +28,8 @@ the loader. We need to make sure that it is out of the way of theprogram
that it will "exec", and that there is sufficient room for the brk. */arch/powerpc/include/asm/elf.h +2
-1-#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)arch/powerpc/mm/mmap.c +10
-0@@ -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; +}arch/x86/Kconfig +0
-1@@ -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_IRQarch/x86/include/asm/elf.h +0
-0@@ -249,7 +249,8 @@ extern int force_personality32; the loader. We need to make sure that it is out of the way of theprogram
that it will "exec", and that there is sufficient room for the brk. */arch/x86/include/asm/elf.h +2
-1-#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,arch/x86/mm/mmap.c +9
-0@@ -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; +}fs/Kconfig.binfmt +0
-2@@ -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 boolfs/binfmt_elf.c +0
-0@@ -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. */fs/binfmt_elf.c +0
-12-#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);
fs/binfmt_elf.c
Quoted 6 lines
fs/binfmt_elf.c +0
-2-#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
Quoted 39 lines · Hector Marco Gisbert
(quoted diff) +36
-0+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; +}
Review
Quoted 10 lines
(quoted diff) +9
-0+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
Quoted 43 lines · On Tue, 24 Feb 2015 08:39:06 +0100 Ingo Molnar <[email protected]> wrote:
Quoted 39 lines · Hector Marco Gisbert
(quoted diff) +36
-0+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; +}
Quoted 11 lines
Review
Quoted 9 lines
(quoted diff) +9
-0+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 <[email protected]>
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.
---
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
arch/arm/include/asm/elf.h renamed from arch/arm/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix +1 -2
@@ -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 *tthe 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
arch/arm/mm/mmap.c renamed from arch/arm/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix +2 -11
@@ -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; -}
arch/arm64/Kconfig renamed from arch/arm64/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix +1 -1
@@ -1,4 +1,4 @@ -config ARM64 +qconfig ARM64 def_bool y select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE select ARCH_HAS_GCOV_PROFILE_ALL
arch/arm64/include/asm/elf.h renamed from arch/arm64/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix +1 -2
@@ -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))/*
arch/arm64/mm/mmap.c renamed from arch/arm64/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix +2 -12
@@ -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
arch/mips/include/asm/elf.h renamed from arch/mips/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix +0 -1
@@ -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
arch/mips/mm/mmap.c renamed from arch/mips/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix +2 -11
@@ -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 voireturn 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
arch/powerpc/include/asm/elf.h renamed from arch/powerpc/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix +0 -2
@@ -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)
arch/powerpc/mm/mmap.c renamed from arch/powerpc/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix +2 -11
@@ -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
arch/x86/include/asm/elf.h renamed from arch/x86/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix +0 -2
@@ -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
arch/x86/mm/mmap.c renamed from arch/x86/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix +2 -10
@@ -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
fs/binfmt_elf.c renamed from fs/binfmt_elf.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix +21 -0
@@ -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
include/linux/elf-randomization.h new file +7 -0
@@ -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 */
_
On 02/26/2015 02:38 PM, Andrew Morton wrote:
[...]
Quoted 23 lines
From: Andrew Morton<[email protected]>
Subject: fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fixConsolidate
randomize_et_dyn()implementations intofs/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__weakto cause it to be discarded at link time.Cc "H. Peter Anvin"<[email protected]>Cc Benjamin Herrenschmidt<[email protected]>Cc Catalin Marinas<[email protected]>Cc Hector Marco Gisbert<[email protected]>Cc Hector Marco-Gisbert<[email protected]>Cc Ingo Molnar<[email protected]>Cc Ismael Ripoll<[email protected]>Cc Kees Cook<[email protected]>Cc Ralf Baechle<[email protected]>Cc Russell King<[email protected]>Cc Thomas Gleixner<[email protected]>Cc Will Deacon<[email protected]>Signed-off-by Andrew Morton<[email protected]>
[...]
arch/arm64/include/asm/elf.h line 2
Quoted 7 lines
diff -puN
arch/arm64/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fixarch/arm64/include/asm/elf.harch/arm64/include/asm/elf.h renamed from arch/arm64/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix +1
-1@@ -1,5 +1,5 @@/* -* Copyright (C) 2012 ARM Ltd. +* Copyright (C) 20q12 ARM Ltd.
This particular change looks like it may be a typo.
Quoted 3 lines
arch/arm64/include/asm/elf.h renamed from arch/arm64/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix +0
-0* * 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
arch/arm64/Kconfig line 1
Quoted 6 lines · Andrew Morton
diff -puN
arch/arm64/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fixarch/arm64/Kconfigarch/arm64/Kconfig renamed from arch/arm64/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix +1
-1@@ -1,4 +1,4 @@ -config ARM64 +qconfig ARM64
Is this a typo?
Signature · 2 lines
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up according to speedtest.net.
Quoted 1 line · On Thu, 26 Feb 2015 14:38:15 -0800 Andrew Morton <[email protected]>…
Does that
__weaktrick even work?
Nope.
fs/binfmt_elf.c renamed from fs/binfmt_elf.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix-fix +3 -3
@@ -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;
_
Quoted 9 lines · On Thu, 26 Feb 2015 23:00:52 +0000 Russell King - ARM Linux…
arch/arm64/Kconfig line 1
Quoted 6 lines · Andrew Morton
diff -puN
arch/arm64/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fixarch/arm64/Kconfigarch/arm64/Kconfig renamed from arch/arm64/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix +1
-1@@ -1,4 +1,4 @@ -config ARM64 +qconfig ARM64Is this a typo?
yup. But the coffee's nice and strong.
Hi Andrew,
Quoted 26 lines · On Thu, 26 Feb 2015 14:38:15 -0800 Andrew Morton <[email protected]>…
diff -puN
fs/binfmt_elf.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fixfs/binfmt_elf.cfs/binfmt_elf.c renamed from fs/binfmt_elf.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix +11
-0@@ -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)
fs/binfmt_elf.c out: · line 2323
Quoted 10 lines
fs/binfmt_elf.c renamed from fs/binfmt_elf.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix +10
-0+{ +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?
Signature · 2 lines
Cheers, Stephen Rothwell [email protected]
Hi Andrew,
[Just resending to correct addresses - sorry for those who get a duplicate]
Quoted 26 lines · On Thu, 26 Feb 2015 14:38:15 -0800 Andrew Morton <[email protected]>…
diff -puN
fs/binfmt_elf.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fixfs/binfmt_elf.cfs/binfmt_elf.c renamed from fs/binfmt_elf.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix +11
-0@@ -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)
fs/binfmt_elf.c out: · line 2323
Quoted 10 lines
fs/binfmt_elf.c renamed from fs/binfmt_elf.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix +10
-0+{ +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?
Signature · 9 lines
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>
Kees Cook
Acked-byQuoted 57 lines · Andrew Morton
Quoted 43 lines · On Tue, 24 Feb 2015 08:39:06 +0100 Ingo Molnar <[email protected]> wrote:
Quoted 39 lines · Hector Marco Gisbert
(quoted diff) +36
-0+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; +}Quoted 11 lines
fs/binfmt_elf.c out: · line 2322
Quoted 9 lines
fs/binfmt_elf.c renamed from fs/binfmt_elf.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix +9
-0+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.
Quoted 4 lines
That's surprisingly hard!
After renaming mips
brk_rnd()tommap_rnd()I had a shot. I'm not very confident in the result. Does that__weaktrick 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.
Quoted 2 lines
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.
Quoted 11 lines
From: Andrew Morton <[email protected]>
Subject: fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fixConsolidate
randomize_et_dyn()implementations intofs/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__weakto cause it to be discarded at link time.
Quoted 13 lines
Cc "H. Peter Anvin" <[email protected]>Cc Benjamin Herrenschmidt <[email protected]>Cc Catalin Marinas <[email protected]>Cc Hector Marco Gisbert <[email protected]>Cc Hector Marco-Gisbert <[email protected]>Cc Ingo Molnar <[email protected]>Cc Ismael Ripoll <[email protected]>Cc Kees Cook <[email protected]>Cc Ralf Baechle <[email protected]>Cc Russell King <[email protected]>Cc Thomas Gleixner <[email protected]>Cc Will Deacon <[email protected]>Signed-off-by Andrew Morton <[email protected]>
Thanks for fixing it up!
-Kees
Quoted 329 lines
---
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-fixarch/arm/Kconfigdiff -puNarch/arm/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fixarch/arm/include/asm/elf.harch/arm/include/asm/elf.h renamed from arch/arm/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix +1
-2@@ -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 *tthe 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-fixarch/arm/mm/mmap.carch/arm/mm/mmap.c renamed from arch/arm/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix +2
-11@@ -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-fixarch/arm64/Kconfigarch/arm64/Kconfig renamed from arch/arm64/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix +1
-1@@ -1,4 +1,4 @@ -config ARM64 +qconfig ARM64 def_bool y select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE select ARCH_HAS_GCOV_PROFILE_ALLdiff -puN
arch/arm64/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fixarch/arm64/include/asm/elf.harch/arm64/include/asm/elf.h renamed from arch/arm64/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix +1
-2@@ -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-fixarch/arm64/mm/mmap.carch/arm64/mm/mmap.c renamed from arch/arm64/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix +2
-12@@ -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-fixarch/mips/Kconfigdiff -puNarch/mips/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fixarch/mips/include/asm/elf.harch/mips/include/asm/elf.h renamed from arch/mips/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix +0
-1@@ -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-fixarch/mips/mm/mmap.carch/mips/mm/mmap.c renamed from arch/mips/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix +2
-11@@ -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 voireturn 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-fixarch/powerpc/Kconfigdiff -puNarch/powerpc/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fixarch/powerpc/include/asm/elf.harch/powerpc/include/asm/elf.h renamed from arch/powerpc/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix +0
-2@@ -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-fixarch/powerpc/mm/mmap.carch/powerpc/mm/mmap.c renamed from arch/powerpc/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix +2
-11@@ -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-fixarch/x86/Kconfigdiff -puNarch/x86/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fixarch/x86/include/asm/elf.harch/x86/include/asm/elf.h renamed from arch/x86/include/asm/elf.h~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix +0
-2@@ -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-fixarch/x86/mm/mmap.carch/x86/mm/mmap.c renamed from arch/x86/mm/mmap.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix +2
-10@@ -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-fixfs/Kconfig.binfmtdiff -puNfs/binfmt_elf.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fixfs/binfmt_elf.cfs/binfmt_elf.c renamed from fs/binfmt_elf.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix +21
-0@@ -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-fixinclude/linux/elf.hdiff -puN/dev/nullinclude/linux/elf-randomization.hinclude/linux/elf-randomization.h new file +7
-0@@ -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 */ _
Signature · 2 lines
Kees Cook Chrome OS Security
Quoted 16 lines · On Fri, 27 Feb 2015 10:21:36 +1100 Stephen Rothwell <[email protected]>…
Quoted 16 lines
(quoted diff) +16
-0+/* 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;
Quoted 8 lines
Review
Quoted 4 lines
(quoted diff) +4
-0+ 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?
arch/arm/Kconfig renamed from arch/arm/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix-fix-2 +1 -0
@@ -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
arch/arm64/Kconfig renamed from arch/arm64/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix-fix-2 +1 -0
@@ -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
arch/mips/Kconfig renamed from arch/mips/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix-fix-2 +1 -0
@@ -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
arch/powerpc/Kconfig renamed from arch/powerpc/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix-fix-2 +1 -0
@@ -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
arch/x86/Kconfig renamed from arch/x86/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix-fix-2 +1 -0
@@ -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
fs/Kconfig renamed from fs/Kconfig~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix-fix-2 +3 -0
@@ -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
fs/binfmt_elf.c renamed from fs/binfmt_elf.c~fix-offset2lib-issue-for-x86-arm-powerpc-and-mips-fix-fix-2 +2 -9
@@ -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 ) {
_
Quoted 10 lines · On Thu, 26 Feb 2015 15:34:36 -0800 Kees Cook <[email protected]> wrote:
Quoted 6 lines
Quoted 1 line
That pointless repetition should be avoided.
That's surprisingly hard!
After renaming mips
brk_rnd()tommap_rnd()I had a shot. I'm not very confident in the result. Does that__weaktrick even work?In theory, it shouldn't be needed since only
randomize_et_dynwill callmmap_rnd, and only architectures that userandomize_et_dynwill call it ... and will definemmap_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.
Quoted 1 line · On Thu, 26 Feb 2015 15:37:37 -0800 Kees Cook <[email protected]> wrote:
Agh, no, please let's avoid the CONFIG addition.
That is precisely how we do this.
Quoted 8 lines
Hector mentioned in private mail that he was looking at an alternative that adds
exec_baseto 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.
Quoted 21 lines · Kees Cook
Quoted 19 lines · Andrew Morton
Quoted 1 line · On Thu, 26 Feb 2015 15:37:37 -0800 Kees Cook <[email protected]> wrote:
Agh, no, please let's avoid the CONFIG addition.
That is precisely how we do this.
Quoted 8 lines
Hector mentioned in private mail that he was looking at an alternative that adds
exec_baseto struct mm which would avoid all this insanity.Can't we do something like:
#ifndef
mmap_rnd# define mmap_rnd 0 #endifSure, and sprinkle
#define
mmap_rndmmap_rnd
Quoted 8 lines
Quoted 3 lines
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_HASor just HAVE?) I've now stumbled over the issue that we can't putrandomize_et_dyninbinfmt_elfbecause it conflicts with linking againstcompat_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
Signature · 2 lines
Kees Cook Chrome OS Security