| From a3defbe5c337dbc6da911f8cc49ae3cc3b49b453 Mon Sep 17 00:00:00 2001 |
| From: Jiri Kosina <jkosina@suse.cz> |
| Date: Wed, 2 Nov 2011 13:37:41 -0700 |
| Subject: binfmt_elf: fix PIE execution with randomization disabled |
| |
| From: Jiri Kosina <jkosina@suse.cz> |
| |
| commit a3defbe5c337dbc6da911f8cc49ae3cc3b49b453 upstream. |
| |
| The case of address space randomization being disabled in runtime through |
| randomize_va_space sysctl is not treated properly in load_elf_binary(), |
| resulting in SIGKILL coming at exec() time for certain PIE-linked binaries |
| in case the randomization has been disabled at runtime prior to calling |
| exec(). |
| |
| Handle the randomize_va_space == 0 case the same way as if we were not |
| supporting .text randomization at all. |
| |
| Based on original patch by H.J. Lu and Josh Boyer. |
| |
| Signed-off-by: Jiri Kosina <jkosina@suse.cz> |
| Cc: Ingo Molnar <mingo@elte.hu> |
| Cc: Russell King <rmk@arm.linux.org.uk> |
| Cc: H.J. Lu <hongjiu.lu@intel.com> |
| Cc: <stable@kernel.org> |
| Tested-by: Josh Boyer <jwboyer@redhat.com> |
| Acked-by: Nicolas Pitre <nicolas.pitre@linaro.org> |
| Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
| Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> |
| |
| --- |
| fs/binfmt_elf.c | 11 ++++++++++- |
| 1 file changed, 10 insertions(+), 1 deletion(-) |
| |
| --- a/fs/binfmt_elf.c |
| +++ b/fs/binfmt_elf.c |
| @@ -795,7 +795,16 @@ static int load_elf_binary(struct linux_ |
| * might try to exec. This is because the brk will |
| * follow the loader, and is not movable. */ |
| #if defined(CONFIG_X86) || defined(CONFIG_ARM) |
| - load_bias = 0; |
| + /* Memory randomization might have been switched off |
| + * in runtime via sysctl. |
| + * 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 |