Skip to content

Commit

Permalink
Improve DenyList function for LineageOS (#13)
Browse files Browse the repository at this point in the history
From user bug reports, we see that many app processes in LineageOS are created using `nativeForkAndSpecialize`.
Hence, we end up cleaning the Zygote process for multiple times.
Current commit fixes this problem. Additionally, it improves the logging of daemon.

Note that for KernelSU, if `unmount by default` is on, then we won't see log entries of update_mount_namespace.
  • Loading branch information
JingMatrix authored Jan 19, 2025
1 parent 067c683 commit 3321d91
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 9 deletions.
28 changes: 22 additions & 6 deletions loader/src/injector/module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -324,16 +324,21 @@ void ZygiskContext::run_modules_post() {
}

void ZygiskContext::app_specialize_pre() {
flags |= APP_SPECIALIZE;
if (!(flags & APP_FORK_AND_SPECIALIZE)) {
// Avoid fetching process flags twice
info_flags = zygiskd::GetProcessFlags(args.app->uid);
}

info_flags = zygiskd::GetProcessFlags(g_ctx->args.app->uid);
if (info_flags & IS_FIRST_PROCESS) {
if ((info_flags & IS_FIRST_PROCESS) && !g_hook->zygote_unmounted) {
zygiskd::CacheMountNamespace(getpid());
}

if ((info_flags & UNMOUNT_MASK) == UNMOUNT_MASK) {
LOGI("[%s] is on the denylist\n", process);
flags |= DO_REVERT_UNMOUNT;
}

flags |= APP_SPECIALIZE;
run_modules_pre();
}

Expand All @@ -342,7 +347,7 @@ void ZygiskContext::app_specialize_post() {

if ((info_flags & (PROCESS_IS_MANAGER | PROCESS_ROOT_IS_MAGISK)) ==
(PROCESS_IS_MANAGER | PROCESS_ROOT_IS_MAGISK)) {
LOGI("current uid %d is manager!", g_ctx->args.app->uid);
LOGI("current uid %d is manager!", args.app->uid);
setenv("ZYGISK_ENABLED", "1", 1);
}

Expand Down Expand Up @@ -396,8 +401,19 @@ void ZygiskContext::nativeForkAndSpecialize_pre() {
LOGV("pre forkAndSpecialize [%s]\n", process);
flags |= APP_FORK_AND_SPECIALIZE;

// unmount the root implementation for Zygote
update_mount_namespace(zygiskd::MountNamespace::Clean);
info_flags = zygiskd::GetProcessFlags(args.app->uid);

if (!g_hook->zygote_unmounted) {
// Cache mount profiles if not done
if (info_flags & IS_FIRST_PROCESS) {
zygiskd::CacheMountNamespace(getpid());
}

// Unmount the root implementation for Zygote
update_mount_namespace(zygiskd::MountNamespace::Clean);
g_hook->zygote_unmounted = true;
LOGV("zygote process mounting points cleared");
}

fork_pre();
if (is_child()) {
Expand Down
1 change: 1 addition & 0 deletions loader/src/injector/module.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,7 @@ struct HookContext {
void *start_addr = nullptr;
size_t block_size = 0;
bool should_unmap = false;
bool zygote_unmounted = false;
jint MODIFIER_NATIVE = 0;
jmethodID member_getModifiers = nullptr;
std::vector<lsplt::MapInfo> cached_map_infos = {};
Expand Down
6 changes: 3 additions & 3 deletions zygiskd/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ pub fn save_mount_namespace(pid: i32, namespace_type: MountNamespace) -> Result<
if !is_initialized {
if pid == -1 {
bail!(
"mount profiles not fully cached: {}, {}, {}",
"Caching not finished [Clean, Root, Module]: [{}, {}, {}]",
CLEAN_MNT_NS_FD.initiated(),
ROOT_MNT_NS_FD.initiated(),
MODULE_MNT_NS_FD.initiated()
Expand Down Expand Up @@ -179,9 +179,9 @@ pub fn save_mount_namespace(pid: i32, namespace_type: MountNamespace) -> Result<
}
child if child > 0 => {
// Parent process
trace!("waiting {child} to update mount namespace");
trace!("waiting {child} to cache mount namespace");
if read_int(reader)? == 0 {
trace!("{child} finished updating mount namespace");
trace!("{child} finished caching mount namespace");
}
let ns_path = format!("/proc/{}/ns/mnt", child);
let ns_file = fs::OpenOptions::new().read(true).open(&ns_path)?;
Expand Down

0 comments on commit 3321d91

Please sign in to comment.