Currently we try to read program properties from NT_GNU_PROPERTY_TYPE_0 ELF notes. However, we do this too late to either report failures cleanly or influence certain aspects of process setup such as the default mmap permissions for the new executable's pages (which will matter for arm64 for example). So, split parsing of the notes from use: rename arch_setup_property() to arch_parse_property() to make the intent clear, and hoist it before flush_old_exec() so that we can still bail out gracefully if needed. Also propagate arch_state into the call so that the arch backend has somewhere to stash information for later use. Signed-off-by: Dave Martin <Dave.Martin@xxxxxxx> --- fs/binfmt_elf.c | 26 +++++++++++++------------- include/linux/elf.h | 15 +++++++++++---- 2 files changed, 24 insertions(+), 17 deletions(-) diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 18015fc..32c9c13 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -851,6 +851,19 @@ static int load_elf_binary(struct linux_binprm *bprm) } } + if (interpreter) { + retval = arch_parse_property(&loc->interp_elf_ex, + interp_elf_phdata, + interpreter, true, &arch_state); + } else { + retval = arch_parse_property(&loc->elf_ex, + elf_phdata, + bprm->file, false, &arch_state); + } + + if (retval < 0) + goto out_free_dentry; + /* * Allow arch code to reject the ELF at this point, whilst it's * still possible to return an error to the code that invoked @@ -1080,19 +1093,6 @@ static int load_elf_binary(struct linux_binprm *bprm) } if (interpreter) { - retval = arch_setup_property(&loc->interp_elf_ex, - interp_elf_phdata, - interpreter, true); - } else { - retval = arch_setup_property(&loc->elf_ex, - elf_phdata, - bprm->file, false); - } - - if (retval < 0) - goto out_free_dentry; - - if (interpreter) { unsigned long interp_map_addr = 0; elf_entry = load_elf_interp(&loc->interp_elf_ex, diff --git a/include/linux/elf.h b/include/linux/elf.h index c15febe..cfcf154 100644 --- a/include/linux/elf.h +++ b/include/linux/elf.h @@ -57,14 +57,21 @@ extern int elf_coredump_extra_notes_size(void); extern int elf_coredump_extra_notes_write(struct coredump_params *cprm); #endif +struct arch_elf_state; + #ifdef CONFIG_ARCH_USE_GNU_PROPERTY -extern int arch_setup_property(void *ehdr, void *phdr, struct file *f, - bool interp); +extern int arch_parse_property(void *ehdr, void *phdr, struct file *f, + bool interp, struct arch_elf_state *arch_state); extern int get_gnu_property(void *ehdr_p, void *phdr_p, struct file *f, u32 pr_type, u32 *feature); #else -static inline int arch_setup_property(void *ehdr, void *phdr, struct file *f, - bool interp) { return 0; } +static inline int arch_parse_property(void *ehdr, void *phdr, struct file *f, + bool interp, + struct arch_elf_state *arch_state) +{ + return 0; +} + static inline int get_gnu_property(void *ehdr_p, void *phdr_p, struct file *f, u32 pr_type, u32 *feature) { return 0; } #endif -- 2.1.4