(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 [off-list ref] 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.
@@ -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
@@ -30,6 +30,17 @@ static int mmap_is_legacy(void)returnsysctl_legacy_va_layout;}+staticunsignedlongmmap_rnd(void)+{+unsignedlongrnd=0;++/* 8 bits of randomness in 20 address space bits */+if(current->flags&PF_RANDOMIZE)+rnd=(long)get_random_int()%(1<<8);++returnrnd<<PAGE_SHIFT;+}+staticunsignedlongmmap_base(unsignedlongrnd){unsignedlonggap=rlimit(RLIMIT_STACK);
@@ -230,3 +241,13 @@ int devmem_is_allowed(unsigned long pfn)}#endif++unsignedlongrandomize_et_dyn(unsignedlongbase)+{+unsignedlongret;+if((current->personality&ADDR_NO_RANDOMIZE)||+!(current->flags&PF_RANDOMIZE))+returnbase;+ret=base+mmap_rnd();+return(ret>base)?ret:base;+}
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)
@@ -249,7 +249,8 @@ extern int force_personality32;theloader.Weneedtomakesurethatitisoutofthewayofthe
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,
@@ -908,21 +908,7 @@ static int load_elf_binary(struct linux_binprm *bprm)*defaultmmapbase,aswellaswhateverprogram
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
From: Hector Marco Gisbert <hidden> Date: 2015-02-23 19:55:47
[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 <redacted>
Signed-off-by: Ismael Ripoll <redacted>
@@ -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
@@ -30,6 +30,17 @@ static int mmap_is_legacy(void)returnsysctl_legacy_va_layout;}+staticunsignedlongmmap_rnd(void)+{+unsignedlongrnd=0;++/* 8 bits of randomness in 20 address space bits */+if(current->flags&PF_RANDOMIZE)+rnd=(long)get_random_int()%(1<<8);++returnrnd<<PAGE_SHIFT;+}+staticunsignedlongmmap_base(unsignedlongrnd){unsignedlonggap=rlimit(RLIMIT_STACK);
@@ -230,3 +241,13 @@ int devmem_is_allowed(unsigned long pfn)}#endif++unsignedlongrandomize_et_dyn(unsignedlongbase)+{+unsignedlongret;+if((current->personality&ADDR_NO_RANDOMIZE)||+!(current->flags&PF_RANDOMIZE))+returnbase;+ret=base+mmap_rnd();+return(ret>base)?ret:base;+}
@@ -249,7 +249,8 @@ extern int force_personality32;theloader.Weneedtomakesurethatitisoutofthewayoftheprogramthatitwill"exec",andthatthereissufficientroomforthebrk.*/-#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)+externunsignedlongrandomize_et_dyn(unsignedlongbase);+#define ELF_ET_DYN_BASE (randomize_et_dyn(TASK_SIZE / 3 * 2))/* This yields a mask that user programs can use to figure out whatinstructionsetthisCPUsupports.Thiscouldbedoneinuserspace,
@@ -908,21 +908,7 @@ static int load_elf_binary(struct linux_binprm *bprm)*defaultmmapbase,aswellaswhateverprogramthey*mighttrytoexec.Thisisbecausethebrkwill*followtheloader,andisnotmovable.*/-#ifdef CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE-/* Memory randomization might have been switched off-*inruntimeviasysctlorexplicitsettingof-*personalityflags.-*Ifthatisthecase,retaintheoriginalnon-zero-*load_biasvalueinordertoestablishproper-*non-randomizedmappings.-*/-if(current->flags&PF_RANDOMIZE)-load_bias=0;-else-load_bias=ELF_PAGESTART(ELF_ET_DYN_BASE-vaddr);-#elseload_bias=ELF_PAGESTART(ELF_ET_DYN_BASE-vaddr);-#endif}error=elf_map(bprm->file,load_bias+vaddr,elf_ppnt,
Kees Cook [off-list ref] 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 [off-list ref] wrote:
quoted
[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.
@@ -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
@@ -30,6 +30,17 @@ static int mmap_is_legacy(void)returnsysctl_legacy_va_layout;}+staticunsignedlongmmap_rnd(void)+{+unsignedlongrnd=0;++/* 8 bits of randomness in 20 address space bits */+if(current->flags&PF_RANDOMIZE)+rnd=(long)get_random_int()%(1<<8);++returnrnd<<PAGE_SHIFT;+}+staticunsignedlongmmap_base(unsignedlongrnd){unsignedlonggap=rlimit(RLIMIT_STACK);
@@ -230,3 +241,13 @@ int devmem_is_allowed(unsigned long pfn)}#endif++unsignedlongrandomize_et_dyn(unsignedlongbase)+{+unsignedlongret;+if((current->personality&ADDR_NO_RANDOMIZE)||+!(current->flags&PF_RANDOMIZE))+returnbase;+ret=base+mmap_rnd();+return(ret>base)?ret:base;+}
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)
@@ -249,7 +249,8 @@ extern int force_personality32;theloader.Weneedtomakesurethatitisoutofthewayofthe
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,
@@ -908,21 +908,7 @@ static int load_elf_binary(struct linux_binprm *bprm)*defaultmmapbase,aswellaswhateverprogram
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
From: Andrew Morton <akpm@linux-foundation.org> Date: 2015-02-26 22:38:19
On Tue, 24 Feb 2015 08:39:06 +0100 Ingo Molnar [off-list ref] wrote:
* Hector Marco Gisbert [off-list ref] wrote:
quoted
+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
+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
+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;
+}
quoted
+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
+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 <redacted>
Cc: Hector Marco-Gisbert <redacted>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Ismael Ripoll <redacted>
Cc: Kees Cook <redacted>
Cc: Ralf Baechle <redacted>
Cc: Russell King <redacted>
Cc: Thomas Gleixner <redacted>
Cc: Will Deacon <redacted>
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
@@ -115,7 +115,6 @@ int dump_task_regs(struct task_struct *ttheloader.Weneedtomakesurethatitisoutofthewayoftheprogramthatitwill"exec",andthatthereissufficientroomforthebrk.*/-externunsignedlongrandomize_et_dyn(unsignedlongbase);#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
@@ -30,7 +31,7 @@ static int mmap_is_legacy(void)returnsysctl_legacy_va_layout;}-staticunsignedlongmmap_rnd(void)+unsignedlongmmap_rnd(void){unsignedlongrnd=0;
@@ -241,13 +242,3 @@ int devmem_is_allowed(unsigned long pfn)}#endif--unsignedlongrandomize_et_dyn(unsignedlongbase)-{-unsignedlongret;-if((current->personality&ADDR_NO_RANDOMIZE)||-!(current->flags&PF_RANDOMIZE))-returnbase;-ret=base+mmap_rnd();-return(ret>base)?ret:base;-}
@@ -248,8 +248,6 @@ extern int force_personality32;useofthisistoinvoke"./ld.so someprog"totestoutanewversionoftheloader.Weneedtomakesurethatitisoutofthewayoftheprogramthatitwill"exec",andthatthereissufficientroomforthebrk.*/--externunsignedlongrandomize_et_dyn(unsignedlongbase);#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
From: David Daney <hidden> Date: 2015-02-26 22:43:28
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<redacted>
Cc: Hector Marco-Gisbert<redacted>
Cc: Ingo Molnar<mingo@kernel.org>
Cc: Ismael Ripoll<redacted>
Cc: Kees Cook<redacted>
Cc: Ralf Baechle<redacted>
Cc: Russell King<redacted>
Cc: Thomas Gleixner<redacted>
Cc: Will Deacon<redacted>
Signed-off-by: Andrew Morton<akpm@linux-foundation.org>
From: Stephen Rothwell <hidden> Date: 2015-02-26 23:26:53
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 [off-list ref] wrote:
@@ -2300,6 +2301,26 @@ out:#endif /* CONFIG_ELF_CORE */+/* Not all architectures implement mmap_rnd() */+unsignedlong__weakmmap_rnd(void)+{+}++/*+*Notallarchitecturesuserandomize_et_dyn(),souse__weaktoletthe+*linkeromititfromvmlinux+*/+unsignedlong__weakrandomize_et_dyn(unsignedlongbase)+{+unsignedlongret;++if((current->personality&ADDR_NO_RANDOMIZE)||+!(current->flags&PF_RANDOMIZE))+returnbase;+ret=base+mmap_rnd();+returnmax(ret,base);+}+
Didn't we have some trouble with some compilers when the weak function
(mmap_rnd) was defined and used in the same file i.e. the wrong one was
used?
--
Cheers,
Stephen Rothwell sfr at canb.auug.org.au
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 819 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150227/3c80d6c1/attachment.sig>
On Thu, Feb 26, 2015 at 2:38 PM, Andrew Morton
[off-list ref] wrote:
On Tue, 24 Feb 2015 08:39:06 +0100 Ingo Molnar [off-list ref] wrote:
quoted
* Hector Marco Gisbert [off-list ref] wrote:
quoted
+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
+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
+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;
+}
quoted
+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
+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 <redacted>
Cc: Hector Marco-Gisbert <redacted>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Ismael Ripoll <redacted>
Cc: Kees Cook <redacted>
Cc: Ralf Baechle <redacted>
Cc: Russell King <redacted>
Cc: Thomas Gleixner <redacted>
Cc: Will Deacon <redacted>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Acked-by: Kees Cook <redacted>
Thanks for fixing it up!
-Kees
@@ -115,7 +115,6 @@ int dump_task_regs(struct task_struct *ttheloader.Weneedtomakesurethatitisoutofthewayoftheprogramthatitwill"exec",andthatthereissufficientroomforthebrk.*/-externunsignedlongrandomize_et_dyn(unsignedlongbase);#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
@@ -30,7 +31,7 @@ static int mmap_is_legacy(void)returnsysctl_legacy_va_layout;}-staticunsignedlongmmap_rnd(void)+unsignedlongmmap_rnd(void){unsignedlongrnd=0;
@@ -241,13 +242,3 @@ int devmem_is_allowed(unsigned long pfn)}#endif--unsignedlongrandomize_et_dyn(unsignedlongbase)-{-unsignedlongret;-if((current->personality&ADDR_NO_RANDOMIZE)||-!(current->flags&PF_RANDOMIZE))-returnbase;-ret=base+mmap_rnd();-return(ret>base)?ret:base;-}
@@ -248,8 +248,6 @@ extern int force_personality32;useofthisistoinvoke"./ld.so someprog"totestoutanewversionoftheloader.Weneedtomakesurethatitisoutofthewayoftheprogramthatitwill"exec",andthatthereissufficientroomforthebrk.*/--externunsignedlongrandomize_et_dyn(unsignedlongbase);#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
From: Andrew Morton <akpm@linux-foundation.org> Date: 2015-02-26 23:39:31
On Thu, 26 Feb 2015 15:34:36 -0800 Kees Cook [off-list ref] wrote:
quoted
quoted
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.