From ce892bc439272a0ec41498a5b46df143ca11f68b Mon Sep 17 00:00:00 2001 From: weishu Date: Thu, 19 Oct 2023 17:29:02 +0800 Subject: [PATCH] kernel: don't umount for non zygote child process. fixes #1054,#1049,#1045 --- kernel/core_hook.c | 12 +++++++++--- kernel/selinux/selinux.c | 18 +++++++++++++++++- kernel/selinux/selinux.h | 2 ++ 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/kernel/core_hook.c b/kernel/core_hook.c index 176a0239db0a..5a8ebc8dc4d9 100644 --- a/kernel/core_hook.c +++ b/kernel/core_hook.c @@ -531,8 +531,6 @@ int ksu_handle_setuid(struct cred *new, const struct cred *old) return 0; } - // todo: check old process's selinux context, if it is not zygote, ignore it! - if (!is_appuid(new_uid) || is_isolated_uid(new_uid.val)) { // pr_info("handle setuid ignore non application or isolated uid: %d\n", new_uid.val); return 0; @@ -551,8 +549,16 @@ int ksu_handle_setuid(struct cred *new, const struct cred *old) #endif } + // 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! + bool is_zygote_child = is_zygote(old->security); + if (!is_zygote_child) { + pr_info("handle umount ignore non zygote child: %d\n", current->pid); + return 0; + } // umount the target mnt - pr_info("handle umount for uid: %d\n", new_uid.val); + pr_info("handle umount for uid: %d, pid: %d\n", new_uid.val, current->pid); // fixme: use `collect_mounts` and `iterate_mount` to iterate all mountpoint and // filter the mountpoint whose target is `/data/adb` diff --git a/kernel/selinux/selinux.c b/kernel/selinux/selinux.c index 43935486ff78..0260fd570ed0 100644 --- a/kernel/selinux/selinux.c +++ b/kernel/selinux/selinux.c @@ -27,7 +27,8 @@ static int transive_to_domain(const char *domain) error = security_secctx_to_secid(domain, strlen(domain), &sid); if (error) { - pr_info("security_secctx_to_secid %s -> sid: %d, error: %d\n", domain, sid, error); + pr_info("security_secctx_to_secid %s -> sid: %d, error: %d\n", + domain, sid, error); } if (!error) { if (!ksu_sid) @@ -107,3 +108,18 @@ bool is_ksu_domain() { return ksu_sid && current_sid() == ksu_sid; } + +bool is_zygote(void *sec) +{ + struct task_security_struct *tsec = (struct task_security_struct *)sec; + if (!tsec) { + return false; + } + char *domain; + u32 seclen; + int err = security_secid_to_secctx(tsec->sid, &domain, &seclen); + if (err) { + return false; + } + return strncmp("u:r:zygote:s0", domain, seclen) == 0; +} \ No newline at end of file diff --git a/kernel/selinux/selinux.h b/kernel/selinux/selinux.h index 1ccc0d53ea3d..0c4978568af7 100644 --- a/kernel/selinux/selinux.h +++ b/kernel/selinux/selinux.h @@ -16,6 +16,8 @@ bool getenforce(); bool is_ksu_domain(); +bool is_zygote(void *cred); + void apply_kernelsu_rules(); #endif