kernel: core_hook: screw path_umount backport, call sys_umount directly
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>
This commit is contained in:
@@ -25,6 +25,9 @@
|
|||||||
|
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
#include <linux/namei.h>
|
#include <linux/namei.h>
|
||||||
|
#ifndef KSU_HAS_PATH_UMOUNT
|
||||||
|
#include <linux/syscalls.h> // sys_umount
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef MODULE
|
#ifdef MODULE
|
||||||
#include <linux/list.h>
|
#include <linux/list.h>
|
||||||
@@ -538,6 +541,7 @@ static bool should_umount(struct path *path)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef KSU_HAS_PATH_UMOUNT
|
||||||
static void ksu_umount_mnt(struct path *path, int flags)
|
static void ksu_umount_mnt(struct path *path, int flags)
|
||||||
{
|
{
|
||||||
int err = path_umount(path, 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);
|
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)
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef KSU_HAS_PATH_UMOUNT
|
||||||
ksu_umount_mnt(&path, flags);
|
ksu_umount_mnt(&path, flags);
|
||||||
|
#else
|
||||||
|
ksu_sys_umount(mnt, flags);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int ksu_handle_setuid(struct cred *new, const struct cred *old)
|
int ksu_handle_setuid(struct cred *new, const struct cred *old)
|
||||||
|
|||||||
Reference in New Issue
Block a user