[RFC PATCH 06/24] exec: expose execveat internals to process builders
From: Li Chen <hidden>
Date: 2026-07-16 14:36:21
Also in:
linux-api, linux-arch, linux-doc, linux-fsdevel, linux-kselftest, linux-mm, lkml
Subsystem:
exec & binfmt api, elf, filesystems (vfs and infrastructure), the rest · Maintainers:
Kees Cook, Alexander Viro, Christian Brauner, Linus Torvalds
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 <redacted> --- 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