diff options
author | Kees Cook <kees@kernel.org> | 2024-05-08 19:31:47 +0200 |
---|---|---|
committer | Kees Cook <kees@kernel.org> | 2024-06-19 21:44:57 +0200 |
commit | 2d4cf7b190bbfadd4986bf5c34da17c1a88adf8e (patch) | |
tree | 5dc6f287f7631d6aa5732fdfae7f8d1a4ca0c947 /fs/binfmt_elf.c | |
parent | selftests/exec: Build both static and non-static load_address tests (diff) | |
download | linux-2d4cf7b190bbfadd4986bf5c34da17c1a88adf8e.tar.xz linux-2d4cf7b190bbfadd4986bf5c34da17c1a88adf8e.zip |
binfmt_elf: Calculate total_size earlier
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>
Diffstat (limited to 'fs/binfmt_elf.c')
-rw-r--r-- | fs/binfmt_elf.c | 52 |
1 files changed, 27 insertions, 25 deletions
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index a43897b03ce9..f59e23b29c3b 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -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, |