kernel: expose umount list to ioctl interface (#2950)
This idea is borrowed from simonpunk's susfs4ksu. What we see here is that, yeah well, lets just have userspace send us what it wants unmounted, this is better than hardcoding everything. This also solves that issue where MNT_DETACH fails, as long as we send unmountables in proper order. A small anti-duplicate mechanism is also added. While in-kernel umount is a bit worse than zygisk-provider-based ones, this can still serve as a healthy alternative. --------- - Remove duplicate checks Signed-off-by: backslashxx <118538522+backslashxx@users.noreply.github.com> Co-authored-by: weishu <twsxtd@gmail.com> Co-authored-by: ShirkNeko <109797057+ShirkNeko@users.noreply.github.com>
This commit is contained in:
@@ -52,7 +52,6 @@ static const struct ksu_feature_handler kernel_umount_handler = {
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS
|
||||
extern bool susfs_is_mnt_devname_ksu(struct path *path);
|
||||
|
||||
#if defined(CONFIG_KSU_SUSFS_TRY_UMOUNT) && defined(CONFIG_KSU_SUSFS_ENABLE_LOG)
|
||||
extern bool susfs_is_log_enabled;
|
||||
#endif // #if defined(CONFIG_KSU_SUSFS_TRY_UMOUNT) && defined(CONFIG_KSU_SUSFS_ENABLE_LOG)
|
||||
@@ -61,27 +60,6 @@ extern void susfs_try_umount(void);
|
||||
#endif // #ifdef CONFIG_KSU_SUSFS_TRY_UMOUNT
|
||||
#endif // #ifdef CONFIG_KSU_SUSFS
|
||||
|
||||
static bool should_umount(struct path *path)
|
||||
{
|
||||
if (!path) {
|
||||
return false;
|
||||
}
|
||||
#ifdef CONFIG_KSU_SUSFS
|
||||
return susfs_is_mnt_devname_ksu(path);
|
||||
#else
|
||||
|
||||
if (current->nsproxy->mnt_ns == init_nsproxy.mnt_ns) {
|
||||
pr_info("ignore global mnt namespace process: %d\n", current_uid().val);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (path->mnt && path->mnt->mnt_sb && path->mnt->mnt_sb->s_type) {
|
||||
const char *fstype = path->mnt->mnt_sb->s_type->name;
|
||||
return strcmp(fstype, "overlay") == 0;
|
||||
}
|
||||
return false;
|
||||
#endif // #ifdef CONFIG_KSU_SUSFS
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0) || defined(KSU_HAS_PATH_UMOUNT)
|
||||
static int ksu_path_umount(struct path *path, int flags)
|
||||
@@ -119,9 +97,9 @@ static int ksu_sys_umount(const char *mnt, int flags)
|
||||
|
||||
#endif
|
||||
#ifdef CONFIG_KSU_SUSFS_TRY_UMOUNT
|
||||
void try_umount(const char *mnt, bool check_mnt, int flags)
|
||||
void try_umount(const char *mnt, int flags)
|
||||
#else
|
||||
static void try_umount(const char *mnt, bool check_mnt, int flags)
|
||||
static void try_umount(const char *mnt, int flags)
|
||||
#endif // #ifdef CONFIG_KSU_SUSFS_TRY_UMOUNT
|
||||
{
|
||||
struct path path;
|
||||
@@ -137,12 +115,6 @@ static void try_umount(const char *mnt, bool check_mnt, int flags)
|
||||
return;
|
||||
}
|
||||
|
||||
// we are only interest in some specific mounts
|
||||
if (check_mnt && !should_umount(&path)) {
|
||||
path_put(&path);
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_KSU_SUSFS_TRY_UMOUNT) && defined(CONFIG_KSU_SUSFS_ENABLE_LOG)
|
||||
if (susfs_is_log_enabled) {
|
||||
pr_info("susfs: umounting '%s'\n", mnt);
|
||||
@@ -184,16 +156,13 @@ static void umount_tw_func(struct callback_head *cb)
|
||||
saved = override_creds(tw->old_cred);
|
||||
}
|
||||
|
||||
// fixme: use `collect_mounts` and `iterate_mount` to iterate all mountpoint and
|
||||
// filter the mountpoint whose target is `/data/adb`
|
||||
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);
|
||||
struct mount_entry *entry;
|
||||
down_read(&mount_list_lock);
|
||||
list_for_each_entry(entry, &mount_list, list) {
|
||||
pr_info("%s: unmounting: %s flags 0x%x\n", __func__, entry->umountable, entry->flags);
|
||||
try_umount(entry->umountable, entry->flags);
|
||||
}
|
||||
up_read(&mount_list_lock);
|
||||
|
||||
if (saved)
|
||||
revert_creds(saved);
|
||||
|
||||
Reference in New Issue
Block a user