[PATCH v5 06/15] fs,fork,exit: export symbols necessary for KUnit UAPI support

Thomas Weißschuh posted 15 patches 5 months ago
[PATCH v5 06/15] fs,fork,exit: export symbols necessary for KUnit UAPI support
Posted by Thomas Weißschuh 5 months ago
The KUnit UAPI infrastructure starts userspace processes.
As it should be able to be built as a module, export the necessary symbols.

Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>

---
For details on how these are used, see patch 12:
"kunit: Introduce UAPI testing framework".
Any ideas on how to make this work without new exports are very welcome.
---
 fs/exec.c        | 2 ++
 fs/file.c        | 1 +
 fs/filesystems.c | 2 ++
 fs/fs_struct.c   | 1 +
 fs/pipe.c        | 2 ++
 kernel/exit.c    | 3 +++
 kernel/fork.c    | 2 ++
 7 files changed, 13 insertions(+)

diff --git a/fs/exec.c b/fs/exec.c
index 1f5fdd2e096e392b342f122d35aba4cf035441c7..13f7f27641942eddcb179bdd93d99b799d155813 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -68,6 +68,7 @@
 #include <linux/user_events.h>
 #include <linux/rseq.h>
 #include <linux/ksm.h>
+#include <linux/export.h>
 
 #include <linux/uaccess.h>
 #include <asm/mmu_context.h>
@@ -1919,6 +1920,7 @@ int kernel_execve(const char *kernel_filename,
 	putname(filename);
 	return retval;
 }
+EXPORT_SYMBOL_GPL_FOR_MODULES(kernel_execve, "kunit-uapi");
 
 static int do_execve(struct filename *filename,
 	const char __user *const __user *__argv,
diff --git a/fs/file.c b/fs/file.c
index 3a3146664cf37115624e12f7f06826d48827e9d7..89d07feb9c328337451ce40cb0f368b6cb986c2c 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -1317,6 +1317,7 @@ int replace_fd(unsigned fd, struct file *file, unsigned flags)
 	spin_unlock(&files->file_lock);
 	return err;
 }
+EXPORT_SYMBOL_GPL_FOR_MODULES(replace_fd, "kunit-uapi");
 
 /**
  * receive_fd() - Install received file into file descriptor table
diff --git a/fs/filesystems.c b/fs/filesystems.c
index 95e5256821a53494d88f496193305a2e50e04444..a3a588f387bbd8268246d1026389deaadf265d0b 100644
--- a/fs/filesystems.c
+++ b/fs/filesystems.c
@@ -17,6 +17,7 @@
 #include <linux/slab.h>
 #include <linux/uaccess.h>
 #include <linux/fs_parser.h>
+#include <linux/export.h>
 
 /*
  * Handling of filesystem drivers list.
@@ -45,6 +46,7 @@ void put_filesystem(struct file_system_type *fs)
 {
 	module_put(fs->owner);
 }
+EXPORT_SYMBOL_GPL_FOR_MODULES(put_filesystem, "kunit-uapi");
 
 static struct file_system_type **find_filesystem(const char *name, unsigned len)
 {
diff --git a/fs/fs_struct.c b/fs/fs_struct.c
index 64c2d0814ed6889cc12603410e6e9dc44089586f..26340d225deba3f2ec30252293fdf417235a6a4a 100644
--- a/fs/fs_struct.c
+++ b/fs/fs_struct.c
@@ -46,6 +46,7 @@ void set_fs_pwd(struct fs_struct *fs, const struct path *path)
 	if (old_pwd.dentry)
 		path_put(&old_pwd);
 }
+EXPORT_SYMBOL_GPL_FOR_MODULES(set_fs_pwd, "kunit-uapi");
 
 static inline int replace_path(struct path *p, const struct path *old, const struct path *new)
 {
diff --git a/fs/pipe.c b/fs/pipe.c
index 45077c37bad154ef146b047834d35d489fcc4d8d..d6cb743d2cfc041f08b498a5a764e9a96dc34069 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -27,6 +27,7 @@
 #include <linux/watch_queue.h>
 #include <linux/sysctl.h>
 #include <linux/sort.h>
+#include <linux/export.h>
 
 #include <linux/uaccess.h>
 #include <asm/ioctls.h>
@@ -971,6 +972,7 @@ int create_pipe_files(struct file **res, int flags)
 	file_set_fsnotify_mode(res[1], FMODE_NONOTIFY_PERM);
 	return 0;
 }
+EXPORT_SYMBOL_GPL_FOR_MODULES(create_pipe_files, "kunit-uapi");
 
 static int __do_pipe_flags(int *fd, struct file **files, int flags)
 {
diff --git a/kernel/exit.c b/kernel/exit.c
index bd743900354ca5fc6c550f80e30393a632eb9a4e..610dffb1276ac60b475708587ca053f315fea9c3 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -70,6 +70,7 @@
 #include <linux/user_events.h>
 #include <linux/uaccess.h>
 #include <linux/pidfs.h>
+#include <linux/export.h>
 
 #include <uapi/linux/wait.h>
 
@@ -1005,6 +1006,7 @@ void __noreturn do_exit(long code)
 	lockdep_free_task(tsk);
 	do_task_dead();
 }
+EXPORT_SYMBOL_GPL_FOR_MODULES(do_exit, "kunit-uapi");
 
 void __noreturn make_task_dead(int signr)
 {
@@ -1887,6 +1889,7 @@ int kernel_wait(pid_t pid, int *stat)
 	put_pid(wo.wo_pid);
 	return ret;
 }
+EXPORT_SYMBOL_GPL_FOR_MODULES(kernel_wait, "kunit-uapi");
 
 SYSCALL_DEFINE4(wait4, pid_t, upid, int __user *, stat_addr,
 		int, options, struct rusage __user *, ru)
diff --git a/kernel/fork.c b/kernel/fork.c
index 1ee8eb11f38bae1d2eb6de9494aea94b7a19e6c3..5de7a9bc005ade6dcfbdfe1a63cadbef8782658c 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -105,6 +105,7 @@
 #include <uapi/linux/pidfd.h>
 #include <linux/pidfs.h>
 #include <linux/tick.h>
+#include <linux/export.h>
 
 #include <asm/pgalloc.h>
 #include <linux/uaccess.h>
@@ -2676,6 +2677,7 @@ pid_t user_mode_thread(int (*fn)(void *), void *arg, unsigned long flags)
 
 	return kernel_clone(&args);
 }
+EXPORT_SYMBOL_GPL_FOR_MODULES(user_mode_thread, "kunit-uapi");
 
 #ifdef __ARCH_WANT_SYS_FORK
 SYSCALL_DEFINE0(fork)

-- 
2.50.0

Re: [PATCH v5 06/15] fs,fork,exit: export symbols necessary for KUnit UAPI support
Posted by Al Viro 4 months, 4 weeks ago
On Thu, Jul 17, 2025 at 10:48:08AM +0200, Thomas Weißschuh wrote:
> The KUnit UAPI infrastructure starts userspace processes.
> As it should be able to be built as a module, export the necessary symbols.
> 
> Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>

No.  This is just plain wrong.  This is way too low-level; teach kernel/umh.c
to provide what you need, but do *not* add more kernel_execve() callers.
And the situation with ramfs needs cleaning up, but "export put_filesystem()"
is not a solution.
Re: [PATCH v5 06/15] fs,fork,exit: export symbols necessary for KUnit UAPI support
Posted by Thomas Weißschuh 4 months, 3 weeks ago
On Fri, Jul 18, 2025 at 05:44:12PM +0100, Al Viro wrote:
> On Thu, Jul 17, 2025 at 10:48:08AM +0200, Thomas Weißschuh wrote:
> > The KUnit UAPI infrastructure starts userspace processes.
> > As it should be able to be built as a module, export the necessary symbols.
> > 
> > Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
> 
> No.  This is just plain wrong.  This is way too low-level; teach kernel/umh.c
> to provide what you need, but do *not* add more kernel_execve() callers.

Sounds good.

> And the situation with ramfs needs cleaning up, but "export put_filesystem()"
> is not a solution.

Cleaning up would mean to stop calling put_filesystem(), as it is a no-op
here anyways, right?


This would still leave the exports for replace_fd(), create_pipe_files()
and set_fs_pwd(). Instead of using kernel/umh.c, I can also extend
kernel/usermode_driver.c to provide these in a way that works for me.
But kernel/usermode_driver.c is dead code, unused since commit
98e20e5e13d2 ("bpfilter: remove bpfilter")
Would it be fine to export those symbols? And delete usermode_driver.c,
as carrying around an unused generic framework seems pointless.


Thomas
Re: [PATCH v5 06/15] fs,fork,exit: export symbols necessary for KUnit UAPI support
Posted by Christoph Hellwig 4 months, 3 weeks ago
On Mon, Jul 21, 2025 at 08:42:40AM +0200, Thomas Weißschuh wrote:
> This would still leave the exports for replace_fd(), create_pipe_files()
> and set_fs_pwd(). Instead of using kernel/umh.c,

Please look into a way to just run your userspace tests from userspace.

It's not that hard, people have done this novel concept for at least
a few decades if you look into it.

> I can also extend
> kernel/usermode_driver.c to provide these in a way that works for me.
> But kernel/usermode_driver.c is dead code, unused since commit
> 98e20e5e13d2 ("bpfilter: remove bpfilter")
> Would it be fine to export those symbols? And delete usermode_driver.c,
> as carrying around an unused generic framework seems pointless.

Unused code should always go away.  Weirdly enough USERMODE_DRIVER is
selected by BPF_PRELOAD despite that not really using any code from
it, though.