diff --git a/kernel/allowlist.h b/kernel/allowlist.h index 536afa51..d6066fd1 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); @@ -43,6 +45,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 60a87eeb..57faec8d 100644 --- a/kernel/kernel_umount.c +++ b/kernel/kernel_umount.c @@ -151,7 +151,7 @@ int ksu_handle_umount(uid_t old_uid, uid_t new_uid) struct umount_tw *tw; #if defined(CONFIG_KSU_SUSFS) || !defined(CONFIG_KSU_SUSFS_TRY_UMOUNT) - // 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; } @@ -160,18 +160,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)) { - return 0; - } + // 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)) { - return 0; - } + 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);