Implement workqueue for unmounting

umount schedules, so it cannot be used in kprobe context.
This commit is contained in:
Wang Han
2025-11-01 19:54:52 +08:00
committed by ShirkNeko
parent 7e446efac4
commit 5c96f951b5

View File

@@ -23,6 +23,7 @@
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <linux/uidgid.h> #include <linux/uidgid.h>
#include <linux/version.h> #include <linux/version.h>
#include <linux/workqueue.h>
#include <linux/binfmts.h> #include <linux/binfmts.h>
#include <linux/tty.h> #include <linux/tty.h>
@@ -48,6 +49,8 @@
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
@@ -513,6 +516,20 @@ static void try_umount(const char *mnt, bool check_mnt, int flags)
ksu_umount_mnt(&path, flags); ksu_umount_mnt(&path, flags);
} }
static void do_umount_work(struct work_struct *work)
{
try_umount("/odm", true, 0);
try_umount("/system", true, 0);
try_umount("/vendor", true, 0);
try_umount("/product", true, 0);
try_umount("/system_ext", true, 0);
try_umount("/data/adb/modules", false, MNT_DETACH);
// try umount ksu temp path
try_umount("/debug_ramdisk", false, MNT_DETACH);
kfree(work);
}
int ksu_handle_setuid(struct cred *new, const struct cred *old) int ksu_handle_setuid(struct cred *new, const struct cred *old)
{ {
if (!new || !old) { if (!new || !old) {
@@ -584,14 +601,14 @@ 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`
try_umount("/system", true, 0); struct work_struct *work = kmalloc(sizeof(struct work_struct), GFP_ATOMIC);
try_umount("/vendor", true, 0); if (!work) {
try_umount("/product", true, 0); pr_err("Failed to allocate work\n");
try_umount("/system_ext", true, 0); return 0;
try_umount("/data/adb/modules", false, MNT_DETACH); }
// try umount ksu temp path INIT_WORK(work, do_umount_work);
try_umount("/debug_ramdisk", false, MNT_DETACH); queue_work(ksu_workqueue, work);
get_task_struct(current); // delay fix get_task_struct(current); // delay fix
ksu_set_current_proc_umounted(); ksu_set_current_proc_umounted();
@@ -808,6 +825,10 @@ __maybe_unused int ksu_kprobe_exit(void)
void __init ksu_core_init(void) void __init ksu_core_init(void)
{ {
ksu_workqueue = alloc_workqueue("ksu_umount", WQ_UNBOUND, 0);
if (!ksu_workqueue) {
pr_err("Failed to create ksu workqueue\n");
}
#ifdef CONFIG_KPROBES #ifdef CONFIG_KPROBES
int rc = ksu_kprobe_init(); int rc = ksu_kprobe_init();
if (rc) { if (rc) {
@@ -827,4 +848,8 @@ void ksu_core_exit(void)
pr_info("ksu_core_exit\n"); pr_info("ksu_core_exit\n");
ksu_kprobe_exit(); ksu_kprobe_exit();
#endif #endif
} if (ksu_workqueue) {
flush_workqueue(ksu_workqueue);
destroy_workqueue(ksu_workqueue);
}
}