On 02/09/2022 11:45, Sherwin da Cruz wrote:
The START_THREAD arch hook called in binfmt_elf is modified to return a value which the elf loader returns as the final result. This maintains similar behaviour as before but allows any arch specialising this macro to either 1. Abort execution of an elf binary from within start_thread() by returning a negative value or 2. Place a positive value in the first result register for the executing program to access by returning the positive value.
You are also making another change in this patch, which is that the 4th argument of START_THREAD() is now bprm instead of start_stack, good to call it out here as it's not particularly obvious otherwise. You should also say that this interface change is acceptable because no arch is currently overriding this hook.
Some explanation here about the change to kernel_execve() would be nice too as it's not so obvious why we need it.
Kevin
Signed-off-by: Sherwin da Cruz sherwin.dacruz@arm.com
fs/binfmt_elf.c | 3 +-- fs/compat_binfmt_elf.c | 6 +++++- fs/exec.c | 4 ++-- include/linux/elf.h | 7 +++++-- 4 files changed, 13 insertions(+), 7 deletions(-)
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index dcbb2fc83f14..e7f87bf3ff13 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -1441,8 +1441,7 @@ static int load_elf_binary(struct linux_binprm *bprm) #endif finalize_exec(bprm);
- START_THREAD(elf_ex, regs, elf_entry, bprm->p);
- retval = 0;
- retval = START_THREAD(elf_ex, regs, elf_entry, bprm); out: return retval;
diff --git a/fs/compat_binfmt_elf.c b/fs/compat_binfmt_elf.c index 413922b85be6..247b9ebd8fbb 100644 --- a/fs/compat_binfmt_elf.c +++ b/fs/compat_binfmt_elf.c @@ -127,7 +127,11 @@ #ifdef COMPAT_START_THREAD #undef START_THREAD -#define START_THREAD COMPAT_START_THREAD +#define START_THREAD(elf_ex, regs, elf_entry, bprm) \ +({ \
- COMPAT_START_THREAD(elf_ex, regs, elf_entry, bprm->p); \
- 0; /* binfmt_elf return value */ \
+}) #endif #ifdef compat_arch_setup_additional_pages diff --git a/fs/exec.c b/fs/exec.c index c177f8cc3e00..3edd9601ae9a 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -1793,7 +1793,7 @@ static int exec_binprm(struct linux_binprm *bprm) trace_sched_process_exec(current, old_pid, bprm); ptrace_event(PTRACE_EVENT_EXEC, old_vpid); proc_exec_connector(current);
- return 0;
- return ret; }
/* @@ -2003,7 +2003,7 @@ int kernel_execve(const char *kernel_filename, free_bprm(bprm); out_ret: putname(filename);
- return retval;
- return retval < 0 ? retval : 0; }
static int do_execve(struct filename *filename, diff --git a/include/linux/elf.h b/include/linux/elf.h index 50ca9e34763c..039ad1867045 100644 --- a/include/linux/elf.h +++ b/include/linux/elf.h @@ -23,8 +23,11 @@ #endif #ifndef START_THREAD -#define START_THREAD(elf_ex, regs, elf_entry, start_stack) \
- start_thread(regs, elf_entry, start_stack)
+#define START_THREAD(elf_ex, regs, elf_entry, bprm) \ +({ \
- start_thread(regs, elf_entry, bprm->p); \
- 0; /* binfmt_elf return value */ \
+}) #endif #if defined(ARCH_HAS_SETUP_ADDITIONAL_PAGES) && !defined(ARCH_SETUP_ADDITIONAL_PAGES)