x86: Fix boot on Twinhead H12Y
[firefly-linux-kernel-4.4.55.git] / fs / binfmt_elf.c
index f34078d702d3bdbe1ee69bc1122b63d3facf5009..618493e44ae0953a6321924d0c294e699b3ba841 100644 (file)
@@ -796,7 +796,16 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
                         * 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
@@ -941,9 +950,13 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
        current->mm->start_stack = bprm->p;
 
 #ifdef arch_randomize_brk
-       if ((current->flags & PF_RANDOMIZE) && (randomize_va_space > 1))
+       if ((current->flags & PF_RANDOMIZE) && (randomize_va_space > 1)) {
                current->mm->brk = current->mm->start_brk =
                        arch_randomize_brk(current->mm);
+#ifdef CONFIG_COMPAT_BRK
+               current->brk_randomized = 1;
+#endif
+       }
 #endif
 
        if (current->personality & MMAP_PAGE_ZERO) {
@@ -1409,7 +1422,7 @@ static int fill_thread_core_info(struct elf_thread_core_info *t,
        for (i = 1; i < view->n; ++i) {
                const struct user_regset *regset = &view->regsets[i];
                do_thread_regset_writeback(t->task, regset);
-               if (regset->core_note_type &&
+               if (regset->core_note_type && regset->get &&
                    (!regset->active || regset->active(t->task, regset))) {
                        int ret;
                        size_t size = regset->n * regset->size;