switch ns umount

This commit is contained in:
Ylarod
2025-11-02 11:29:06 +08:00
committed by ShirkNeko
parent 5c96f951b5
commit 97ec718fea

View File

@@ -1,3 +1,4 @@
#include "linux/slab.h"
#include <linux/seccomp.h> #include <linux/seccomp.h>
#include <linux/bpf.h> #include <linux/bpf.h>
#include <linux/capability.h> #include <linux/capability.h>
@@ -49,8 +50,6 @@
bool ksu_module_mounted = false; bool ksu_module_mounted = false;
static struct workqueue_struct *ksu_workqueue;
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
bool ksu_is_compat __read_mostly = false; bool ksu_is_compat __read_mostly = false;
#endif #endif
@@ -72,6 +71,13 @@ static void ksu_try_escalate_for_uid(uid_t uid)
} }
#endif #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() static inline bool is_allow_su()
{ {
if (is_manager()) { 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) 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("/odm", true, 0);
try_umount("/system", true, 0); try_umount("/system", true, 0);
try_umount("/vendor", 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 ksu temp path
try_umount("/debug_ramdisk", false, MNT_DETACH); 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) 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 // fixme: use `collect_mounts` and `iterate_mount` to iterate all mountpoint and
// filter the mountpoint whose target is `/data/adb` // filter the mountpoint whose target is `/data/adb`
struct work_struct *work = kmalloc(sizeof(struct work_struct), GFP_ATOMIC); struct ksu_umount_work *umount_work = kmalloc(sizeof(struct ksu_umount_work), GFP_ATOMIC);
if (!work) { if (!umount_work) {
pr_err("Failed to allocate work\n"); pr_err("Failed to allocate umount_work\n");
return 0; return 0;
} }
INIT_WORK(work, do_umount_work); umount_work->mnt_ns = current->nsproxy->mnt_ns;
queue_work(ksu_workqueue, work); 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 get_task_struct(current); // delay fix
ksu_set_current_proc_umounted(); ksu_set_current_proc_umounted();