|
@@ -895,7 +895,7 @@ static int load_elf_binary(struct linux_binprm *bprm)
|
|
|
the correct location in memory. */
|
|
|
for(i = 0, elf_ppnt = elf_phdata;
|
|
|
i < loc->elf_ex.e_phnum; i++, elf_ppnt++) {
|
|
|
- int elf_prot = 0, elf_flags;
|
|
|
+ int elf_prot = 0, elf_flags, elf_fixed = MAP_FIXED_NOREPLACE;
|
|
|
unsigned long k, vaddr;
|
|
|
unsigned long total_size = 0;
|
|
|
|
|
@@ -927,6 +927,13 @@ static int load_elf_binary(struct linux_binprm *bprm)
|
|
|
*/
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Some binaries have overlapping elf segments and then
|
|
|
+ * we have to forcefully map over an existing mapping
|
|
|
+ * e.g. over this newly established brk mapping.
|
|
|
+ */
|
|
|
+ elf_fixed = MAP_FIXED;
|
|
|
}
|
|
|
|
|
|
if (elf_ppnt->p_flags & PF_R)
|
|
@@ -944,7 +951,7 @@ static int load_elf_binary(struct linux_binprm *bprm)
|
|
|
* the ET_DYN load_addr calculations, proceed normally.
|
|
|
*/
|
|
|
if (loc->elf_ex.e_type == ET_EXEC || load_addr_set) {
|
|
|
- elf_flags |= MAP_FIXED_NOREPLACE;
|
|
|
+ elf_flags |= elf_fixed;
|
|
|
} else if (loc->elf_ex.e_type == ET_DYN) {
|
|
|
/*
|
|
|
* This logic is run once for the first LOAD Program
|
|
@@ -980,7 +987,7 @@ static int load_elf_binary(struct linux_binprm *bprm)
|
|
|
load_bias = ELF_ET_DYN_BASE;
|
|
|
if (current->flags & PF_RANDOMIZE)
|
|
|
load_bias += arch_mmap_rnd();
|
|
|
- elf_flags |= MAP_FIXED_NOREPLACE;
|
|
|
+ elf_flags |= elf_fixed;
|
|
|
} else
|
|
|
load_bias = 0;
|
|
|
|