From a3a847a885b4df5980b17e7403eade4c22c37906 Mon Sep 17 00:00:00 2001 From: backslashxx <118538522+backslashxx@users.noreply.github.com> Date: Thu, 22 May 2025 23:32:58 +0800 Subject: [PATCH] kernel: core_hook: screw path_umount backport, call sys_umount directly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I am repasting here what I posted on the source code originally: /* * turns out path_umount backport is completely unneeded * we copy the trick used on strncpy_from_unsafe_user / strncpy_from_user_nofault * https://elixir.bootlin.com/linux/v4.4.302/source/mm/maccess.c#L184 * basically * * mm_segment_t old_fs = get_fs(); // remember original fs segment * set_fs(USER_DS); // or KERNEL_DS * * do_whatever_in_userspace(); * set_fs(old_fs); // restore fs segment * * * kernel -> user, KERNEL_DS, user -> kernel, USER_DS * * so yes, we can try to straight up call a syscall from kernel space * * NOTE: on newer kernels you can use force_uaccess_begin + force_uaccess_end * ref: https://elixir.bootlin.com/linux/v5.10.237/source/mm/maccess.c#L250 * */ path_umount backport now optional — neat trick, werks, what can I say. Backports? Nah, we’re good. Signed-off-by: backslashxx <118538522+backslashxx@users.noreply.github.com> --- kernel/core_hook.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/kernel/core_hook.c b/kernel/core_hook.c index e4e8bdad..3356bbde 100644 --- a/kernel/core_hook.c +++ b/kernel/core_hook.c @@ -25,6 +25,9 @@ #include #include +#ifndef KSU_HAS_PATH_UMOUNT +#include // sys_umount +#endif #ifdef MODULE #include @@ -538,6 +541,7 @@ static bool should_umount(struct path *path) return false; } +#ifdef KSU_HAS_PATH_UMOUNT static void ksu_umount_mnt(struct path *path, int flags) { int err = path_umount(path, flags); @@ -549,6 +553,18 @@ static void ksu_umount_mnt(struct path *path, int flags) path->dentry->d_iname); } } +#else +static void ksu_sys_umount(const char *mnt, int flags) +{ + char __user *usermnt = (char __user *)mnt; + + mm_segment_t old_fs = get_fs(); + set_fs(KERNEL_DS); + long ret = sys_umount(usermnt, flags); // cuz asmlinkage long sys##name + set_fs(old_fs); + pr_info("%s: path: %s code: %d \n", __func__, usermnt, ret); +} +#endif static void try_umount(const char *mnt, bool check_mnt, int flags) { @@ -568,7 +584,11 @@ static void try_umount(const char *mnt, bool check_mnt, int flags) return; } +#ifdef KSU_HAS_PATH_UMOUNT ksu_umount_mnt(&path, flags); +#else + ksu_sys_umount(mnt, flags); +#endif } int ksu_handle_setuid(struct cred *new, const struct cred *old)