]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
binfmt_elf: Calculate total_size earlier
authorKees Cook <kees@kernel.org>
Wed, 8 May 2024 17:31:47 +0000 (10:31 -0700)
committerKees Cook <kees@kernel.org>
Wed, 19 Jun 2024 19:44:57 +0000 (12:44 -0700)
In preparation to support PT_LOAD with large p_align values on
non-PT_INTERP ET_DYN executables (i.e. "static pie"), we'll need to use
the total_size details earlier. Move this separately now to make the
next patch more readable. As total_size and load_bias are currently
calculated separately, this has no behavioral impact.

Link: https://lore.kernel.org/r/20240508173149.677910-2-keescook@chromium.org
Signed-off-by: Kees Cook <kees@kernel.org>
fs/binfmt_elf.c

index a43897b03ce94017fade29e10f561b2b4e96add8..f59e23b29c3b9cd24f6921a584fb7a5f26786024 100644 (file)
@@ -1061,7 +1061,34 @@ out_free_interp:
                         * Header for ET_DYN binaries to calculate the
                         * randomization (load_bias) for all the LOAD
                         * Program Headers.
+                        */
+
+                       /*
+                        * Calculate the entire size of the ELF mapping
+                        * (total_size), used for the initial mapping,
+                        * due to load_addr_set which is set to true later
+                        * once the initial mapping is performed.
+                        *
+                        * Note that this is only sensible when the LOAD
+                        * segments are contiguous (or overlapping). If
+                        * used for LOADs that are far apart, this would
+                        * cause the holes between LOADs to be mapped,
+                        * running the risk of having the mapping fail,
+                        * as it would be larger than the ELF file itself.
                         *
+                        * As a result, only ET_DYN does this, since
+                        * some ET_EXEC (e.g. ia64) may have large virtual
+                        * memory holes between LOADs.
+                        *
+                        */
+                       total_size = total_mapping_size(elf_phdata,
+                                                       elf_ex->e_phnum);
+                       if (!total_size) {
+                               retval = -EINVAL;
+                               goto out_free_dentry;
+                       }
+
+                       /*
                         * There are effectively two types of ET_DYN
                         * binaries: programs (i.e. PIE: ET_DYN with INTERP)
                         * and loaders (ET_DYN without INTERP, since they
@@ -1102,31 +1129,6 @@ out_free_interp:
                         * is then page aligned.
                         */
                        load_bias = ELF_PAGESTART(load_bias - vaddr);
-
-                       /*
-                        * Calculate the entire size of the ELF mapping
-                        * (total_size), used for the initial mapping,
-                        * due to load_addr_set which is set to true later
-                        * once the initial mapping is performed.
-                        *
-                        * Note that this is only sensible when the LOAD
-                        * segments are contiguous (or overlapping). If
-                        * used for LOADs that are far apart, this would
-                        * cause the holes between LOADs to be mapped,
-                        * running the risk of having the mapping fail,
-                        * as it would be larger than the ELF file itself.
-                        *
-                        * As a result, only ET_DYN does this, since
-                        * some ET_EXEC (e.g. ia64) may have large virtual
-                        * memory holes between LOADs.
-                        *
-                        */
-                       total_size = total_mapping_size(elf_phdata,
-                                                       elf_ex->e_phnum);
-                       if (!total_size) {
-                               retval = -EINVAL;
-                               goto out_free_dentry;
-                       }
                }
 
                error = elf_load(bprm->file, load_bias + vaddr, elf_ppnt,