]> Git Repo - linux.git/blobdiff - fs/binfmt_elf.c
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
[linux.git] / fs / binfmt_elf.c
index fa582748be412f7d132d96af01d79a51961e28cb..f8c7f26f1fbb3f987636d01295d0763ed9464c35 100644 (file)
@@ -156,7 +156,7 @@ static int padzero(unsigned long elf_bss)
 #define STACK_ADD(sp, items) ((elf_addr_t __user *)(sp) - (items))
 #define STACK_ROUND(sp, items) \
        (((unsigned long) (sp - items)) &~ 15UL)
-#define STACK_ALLOC(sp, len) ({ sp -= len ; sp; })
+#define STACK_ALLOC(sp, len) (sp -= len)
 #endif
 
 #ifndef ELF_BASE_PLATFORM
@@ -1074,20 +1074,26 @@ out_free_interp:
 
                vaddr = elf_ppnt->p_vaddr;
                /*
-                * If we are loading ET_EXEC or we have already performed
-                * the ET_DYN load_addr calculations, proceed normally.
+                * The first time through the loop, load_addr_set is false:
+                * layout will be calculated. Once set, use MAP_FIXED since
+                * we know we've already safely mapped the entire region with
+                * MAP_FIXED_NOREPLACE in the once-per-binary logic following.
                 */
-               if (elf_ex->e_type == ET_EXEC || load_addr_set) {
+               if (load_addr_set) {
                        elf_flags |= MAP_FIXED;
+               } else if (elf_ex->e_type == ET_EXEC) {
+                       /*
+                        * This logic is run once for the first LOAD Program
+                        * Header for ET_EXEC binaries. No special handling
+                        * is needed.
+                        */
+                       elf_flags |= MAP_FIXED_NOREPLACE;
                } else if (elf_ex->e_type == ET_DYN) {
                        /*
                         * This logic is run once for the first LOAD Program
                         * Header for ET_DYN binaries to calculate the
                         * randomization (load_bias) for all the LOAD
-                        * Program Headers, and to calculate the entire
-                        * size of the ELF mapping (total_size). (Note that
-                        * load_addr_set is set to true later once the
-                        * initial mapping is performed.)
+                        * Program Headers.
                         *
                         * There are effectively two types of ET_DYN
                         * binaries: programs (i.e. PIE: ET_DYN with INTERP)
@@ -1108,7 +1114,7 @@ out_free_interp:
                         * Therefore, programs are loaded offset from
                         * ELF_ET_DYN_BASE and loaders are loaded into the
                         * independently randomized mmap region (0 load_bias
-                        * without MAP_FIXED).
+                        * without MAP_FIXED nor MAP_FIXED_NOREPLACE).
                         */
                        if (interpreter) {
                                load_bias = ELF_ET_DYN_BASE;
@@ -1117,7 +1123,7 @@ out_free_interp:
                                alignment = maximum_alignment(elf_phdata, elf_ex->e_phnum);
                                if (alignment)
                                        load_bias &= ~(alignment - 1);
-                               elf_flags |= MAP_FIXED;
+                               elf_flags |= MAP_FIXED_NOREPLACE;
                        } else
                                load_bias = 0;
 
@@ -1129,7 +1135,14 @@ out_free_interp:
                         * is then page aligned.
                         */
                        load_bias = ELF_PAGESTART(load_bias - vaddr);
+               }
 
+               /*
+                * Calculate the entire size of the ELF mapping (total_size).
+                * (Note that load_addr_set is set to true later once the
+                * initial mapping is performed.)
+                */
+               if (!load_addr_set) {
                        total_size = total_mapping_size(elf_phdata,
                                                        elf_ex->e_phnum);
                        if (!total_size) {
This page took 0.03315 seconds and 4 git commands to generate.