diff --git a/kernel/core_hook.c b/kernel/core_hook.c index 430352a3..470bb54b 100644 --- a/kernel/core_hook.c +++ b/kernel/core_hook.c @@ -1,3 +1,4 @@ +#include "linux/slab.h" #include #include #include @@ -49,8 +50,6 @@ bool ksu_module_mounted = false; -static struct workqueue_struct *ksu_workqueue; - #ifdef CONFIG_COMPAT bool ksu_is_compat __read_mostly = false; #endif @@ -72,6 +71,13 @@ static void ksu_try_escalate_for_uid(uid_t uid) } #endif +static struct workqueue_struct *ksu_workqueue; + +struct ksu_umount_work { + struct work_struct work; + struct mnt_namespace *mnt_ns; +}; + static inline bool is_allow_su() { if (is_manager()) { @@ -518,6 +524,11 @@ static void try_umount(const char *mnt, bool check_mnt, int flags) static void do_umount_work(struct work_struct *work) { + struct ksu_umount_work *umount_work = container_of(work, struct ksu_umount_work, work); + struct mnt_namespace *old_mnt_ns = current->nsproxy->mnt_ns; + + current->nsproxy->mnt_ns = umount_work->mnt_ns; + try_umount("/odm", true, 0); try_umount("/system", true, 0); try_umount("/vendor", true, 0); @@ -527,7 +538,11 @@ static void do_umount_work(struct work_struct *work) // try umount ksu temp path try_umount("/debug_ramdisk", false, MNT_DETACH); - kfree(work); + + current->nsproxy->mnt_ns = old_mnt_ns; + put_mnt_ns(umount_work->mnt_ns); + + kfree(umount_work); } int ksu_handle_setuid(struct cred *new, const struct cred *old) @@ -601,14 +616,18 @@ int ksu_handle_setuid(struct cred *new, const struct cred *old) // fixme: use `collect_mounts` and `iterate_mount` to iterate all mountpoint and // filter the mountpoint whose target is `/data/adb` - struct work_struct *work = kmalloc(sizeof(struct work_struct), GFP_ATOMIC); - if (!work) { - pr_err("Failed to allocate work\n"); + struct ksu_umount_work *umount_work = kmalloc(sizeof(struct ksu_umount_work), GFP_ATOMIC); + if (!umount_work) { + pr_err("Failed to allocate umount_work\n"); return 0; } - INIT_WORK(work, do_umount_work); - queue_work(ksu_workqueue, work); + umount_work->mnt_ns = current->nsproxy->mnt_ns; + get_mnt_ns(umount_work->mnt_ns); + + INIT_WORK(&umount_work->work, do_umount_work); + + queue_work(ksu_workqueue, &umount_work->work); get_task_struct(current); // delay fix ksu_set_current_proc_umounted();