aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/include/asm/elf.h13
-rw-r--r--fs/binfmt_elf.c59
2 files changed, 58 insertions, 14 deletions
diff --git a/arch/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h
index e8ab9a46bc68..1c18d83d3f09 100644
--- a/arch/x86/include/asm/elf.h
+++ b/arch/x86/include/asm/elf.h
@@ -245,12 +245,13 @@ extern int force_personality32;
245#define CORE_DUMP_USE_REGSET 245#define CORE_DUMP_USE_REGSET
246#define ELF_EXEC_PAGESIZE 4096 246#define ELF_EXEC_PAGESIZE 4096
247 247
248/* This is the location that an ET_DYN program is loaded if exec'ed. Typical 248/*
249 use of this is to invoke "./ld.so someprog" to test out a new version of 249 * This is the base location for PIE (ET_DYN with INTERP) loads. On
250 the loader. We need to make sure that it is out of the way of the program 250 * 64-bit, this is raised to 4GB to leave the entire 32-bit address
251 that it will "exec", and that there is sufficient room for the brk. */ 251 * space open for things that want to use the area for 32-bit pointers.
252 252 */
253#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2) 253#define ELF_ET_DYN_BASE (mmap_is_ia32() ? 0x000400000UL : \
254 0x100000000UL)
254 255
255/* This yields a mask that user programs can use to figure out what 256/* This yields a mask that user programs can use to figure out what
256 instruction set this CPU supports. This could be done in user space, 257 instruction set this CPU supports. This could be done in user space,
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 5075fd5c62c8..7465c3ea5dd5 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -927,17 +927,60 @@ static int load_elf_binary(struct linux_binprm *bprm)
927 elf_flags = MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE; 927 elf_flags = MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE;
928 928
929 vaddr = elf_ppnt->p_vaddr; 929 vaddr = elf_ppnt->p_vaddr;
930 /*
931 * If we are loading ET_EXEC or we have already performed
932 * the ET_DYN load_addr calculations, proceed normally.
933 */
930 if (loc->elf_ex.e_type == ET_EXEC || load_addr_set) { 934 if (loc->elf_ex.e_type == ET_EXEC || load_addr_set) {
931 elf_flags |= MAP_FIXED; 935 elf_flags |= MAP_FIXED;
932 } else if (loc->elf_ex.e_type == ET_DYN) { 936 } else if (loc->elf_ex.e_type == ET_DYN) {
933 /* Try and get dynamic programs out of the way of the 937 /*
934 * default mmap base, as well as whatever program they 938 * This logic is run once for the first LOAD Program
935 * might try to exec. This is because the brk will 939 * Header for ET_DYN binaries to calculate the
936 * follow the loader, and is not movable. */ 940 * randomization (load_bias) for all the LOAD
937 load_bias = ELF_ET_DYN_BASE - vaddr; 941 * Program Headers, and to calculate the entire
938 if (current->flags & PF_RANDOMIZE) 942 * size of the ELF mapping (total_size). (Note that
939 load_bias += arch_mmap_rnd(); 943 * load_addr_set is set to true later once the
940 load_bias = ELF_PAGESTART(load_bias); 944 * initial mapping is performed.)
945 *
946 * There are effectively two types of ET_DYN
947 * binaries: programs (i.e. PIE: ET_DYN with INTERP)
948 * and loaders (ET_DYN without INTERP, since they
949 * _are_ the ELF interpreter). The loaders must
950 * be loaded away from programs since the program
951 * may otherwise collide with the loader (especially
952 * for ET_EXEC which does not have a randomized
953 * position). For example to handle invocations of
954 * "./ld.so someprog" to test out a new version of
955 * the loader, the subsequent program that the
956 * loader loads must avoid the loader itself, so
957 * they cannot share the same load range. Sufficient
958 * room for the brk must be allocated with the
959 * loader as well, since brk must be available with
960 * the loader.
961 *
962 * Therefore, programs are loaded offset from
963 * ELF_ET_DYN_BASE and loaders are loaded into the
964 * independently randomized mmap region (0 load_bias
965 * without MAP_FIXED).
966 */
967 if (elf_interpreter) {
968 load_bias = ELF_ET_DYN_BASE;
969 if (current->flags & PF_RANDOMIZE)
970 load_bias += arch_mmap_rnd();
971 elf_flags |= MAP_FIXED;
972 } else
973 load_bias = 0;
974
975 /*
976 * Since load_bias is used for all subsequent loading
977 * calculations, we must lower it by the first vaddr
978 * so that the remaining calculations based on the
979 * ELF vaddrs will be correctly offset. The result
980 * is then page aligned.
981 */
982 load_bias = ELF_PAGESTART(load_bias - vaddr);
983
941 total_size = total_mapping_size(elf_phdata, 984 total_size = total_mapping_size(elf_phdata,
942 loc->elf_ex.e_phnum); 985 loc->elf_ex.e_phnum);
943 if (!total_size) { 986 if (!total_size) {