From 01097231875ed4fc97e2bb809123582107e6f8da Mon Sep 17 00:00:00 2001 From: Wang Han <416810799@qq.com> Date: Sun, 24 Aug 2025 07:01:18 +0800 Subject: [PATCH] kernel: Unmount all isolated process which forks from zygote Kernel has few information about which isolated process belongs to which application, so there is actually no good choice if we don't implement a userspace daemon. One choice is to access cmdline memory from kernel, but cmdline is __user, and it is likely to trigger detections. Before we have more good ideas, use this. --- kernel/allowlist.h | 8 ++++++++ kernel/kernel_umount.c | 14 ++++++++++---- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/kernel/allowlist.h b/kernel/allowlist.h index 4bac8c32..05e1572a 100644 --- a/kernel/allowlist.h +++ b/kernel/allowlist.h @@ -8,6 +8,8 @@ #define PER_USER_RANGE 100000 #define FIRST_APPLICATION_UID 10000 #define LAST_APPLICATION_UID 19999 +#define FIRST_ISOLATED_UID 99000 +#define LAST_ISOLATED_UID 99999 void ksu_allowlist_init(void); @@ -41,6 +43,12 @@ static inline bool is_appuid(uid_t uid) return appid >= FIRST_APPLICATION_UID && appid <= LAST_APPLICATION_UID; } +static inline bool is_isolated_process(uid_t uid) +{ + uid_t appid = uid % PER_USER_RANGE; + return appid >= FIRST_ISOLATED_UID && appid <= LAST_ISOLATED_UID; +} + #ifdef CONFIG_KSU_MANUAL_SU bool ksu_temp_grant_root_once(uid_t uid); void ksu_temp_revoke_root_once(uid_t uid); diff --git a/kernel/kernel_umount.c b/kernel/kernel_umount.c index 40860570..48639a07 100644 --- a/kernel/kernel_umount.c +++ b/kernel/kernel_umount.c @@ -106,7 +106,7 @@ int ksu_handle_umount(uid_t old_uid, uid_t new_uid) { struct umount_tw *tw; - // this hook is used for umounting overlayfs for some uid, if there isn't any module mounted, just ignore it! + // if there isn't any module mounted, just ignore it! if (!ksu_module_mounted) { return 0; } @@ -115,18 +115,24 @@ int ksu_handle_umount(uid_t old_uid, uid_t new_uid) return 0; } - // FIXME: isolated process which directly forks from zygote is not handled - if (!is_appuid(new_uid)) { + // There are 5 scenarios: + // 1. Normal app: zygote -> appuid + // 2. Isolated process forked from zygote: zygote -> isolated_process + // 3. App zygote forked from zygote: zygote -> appuid + // 4. Isolated process froked from app zygote: appuid -> isolated_process (already handled by 3) + // 5. Isolated process froked from webview zygote (no need to handle, app cannot run custom code) + if (!is_appuid(new_uid) && !is_isolated_process(new_uid)) { return 0; } - if (!ksu_uid_should_umount(new_uid)) { + if (!ksu_uid_should_umount(new_uid) && !is_isolated_process(new_uid)) { return 0; } // check old process's selinux context, if it is not zygote, ignore it! // because some su apps may setuid to untrusted_app but they are in global mount namespace // when we umount for such process, that is a disaster! + // also handle case 4 and 5 bool is_zygote_child = is_zygote(get_current_cred()); if (!is_zygote_child) { pr_info("handle umount ignore non zygote child: %d\n", current->pid);