Move struct user_arg_ptr and its native and compat constructors to an fs-private header. Expose do_execveat_common() within fs so a process builder can enter the normal exec path without synthesizing a userspace execveat() syscall.
Assisted-by: Codex:gpt-5.6-sol Signed-off-by: Li Chen <[email protected]> --- MAINTAINERS | 1 + fs/exec.c | 28 ++++------------------------ fs/exec_internal.h | 40 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 24 deletions(-) create mode 100644 fs/exec_internal.h diff --git a/MAINTAINERS b/MAINTAINERS index 8d7f94f09f414..85b1306cb2ff3 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -9757,6 +9757,7 @@ F: Documentation/userspace-api/ELF.rst F: fs/*binfmt_*.c F: fs/Kconfig.binfmt F: fs/exec.c +F: fs/exec_internal.h F: fs/tests/binfmt_*_kunit.c F: fs/tests/exec_kunit.c F: include/linux/binfmts.h diff --git a/fs/exec.c b/fs/exec.c index d5993cedc829a..1a256ba26425e 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -76,6 +76,7 @@ #include <trace/events/task.h> #include "internal.h" +#include "exec_internal.h" #include <trace/events/sched.h> @@ -291,17 +292,6 @@ static int bprm_mm_init(struct linux_binprm *bprm) return err; } -struct user_arg_ptr { -#ifdef CONFIG_COMPAT - bool is_compat; -#endif - union { - const char __user *const __user *native; -#ifdef CONFIG_COMPAT - const compat_uptr_t __user *compat; -#endif - } ptr; -}; static const char __user *get_user_arg_ptr(struct user_arg_ptr argv, int nr) { @@ -1805,10 +1795,9 @@ static int bprm_execve(struct linux_binprm *bprm) return retval; } -static int do_execveat_common(int fd, struct filename *filename, - struct user_arg_ptr argv, - struct user_arg_ptr envp, - int flags) +int do_execveat_common(int fd, struct filename *filename, + struct user_arg_ptr argv, + struct user_arg_ptr envp, int flags) { int retval; @@ -1935,10 +1924,6 @@ void set_binfmt(struct linux_binfmt *new) } EXPORT_SYMBOL(set_binfmt); -static inline struct user_arg_ptr native_arg(const char __user *const __user *p) -{ - return (struct user_arg_ptr){.ptr.native = p}; -} SYSCALL_DEFINE3(execve, const char __user *, filename, @@ -1963,11 +1948,6 @@ SYSCALL_DEFINE5(execveat, #ifdef CONFIG_COMPAT -static inline struct user_arg_ptr compat_arg(const compat_uptr_t __user *p) -{ - return (struct user_arg_ptr){.is_compat = true, .ptr.compat = p}; -} - COMPAT_SYSCALL_DEFINE3(execve, const char __user *, filename, const compat_uptr_t __user *, argv, const compat_uptr_t __user *, envp) diff --git a/fs/exec_internal.h b/fs/exec_internal.h new file mode 100644 index 0000000000000..bf6a873e98426 --- /dev/null +++ b/fs/exec_internal.h @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef _FS_EXEC_INTERNAL_H +#define _FS_EXEC_INTERNAL_H + +#include <linux/compat.h> +#include <linux/compiler_types.h> +#include <linux/types.h> + +struct filename; + +struct user_arg_ptr { +#ifdef CONFIG_COMPAT + bool is_compat; +#endif + union { + const char __user *const __user *native; +#ifdef CONFIG_COMPAT + const compat_uptr_t __user *compat; +#endif + } ptr; +}; + +static inline struct user_arg_ptr +native_arg(const char __user *const __user *p) +{ + return (struct user_arg_ptr){.ptr.native = p}; +} + +#ifdef CONFIG_COMPAT +static inline struct user_arg_ptr compat_arg(const compat_uptr_t __user *p) +{ + return (struct user_arg_ptr){.is_compat = true, .ptr.compat = p}; +} +#endif + +int do_execveat_common(int fd, struct filename *filename, + struct user_arg_ptr argv, + struct user_arg_ptr envp, int flags); + +#endif /* _FS_EXEC_INTERNAL_H */ -- 2.52.0

