Skip to content

Commit

Permalink
improve: re-order mount IDs
Browse files Browse the repository at this point in the history
This commit focuses in porting JingMatrix/NeoZygisk@2814712#diff-e00e4b92e648c073b9ee1644fba5f7948b2d0b77fcfcdc26b7a4144290e321a3R379 to ReZygisk. Further explanation is given in NeoZygisk commit.
  • Loading branch information
ThePedroo committed Dec 29, 2024
1 parent 4e12e32 commit ab27ffe
Show file tree
Hide file tree
Showing 11 changed files with 463 additions and 31 deletions.
27 changes: 27 additions & 0 deletions loader/src/common/daemon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -260,4 +260,31 @@ namespace zygiskd {
close(fd);
} else info->running = false;
}

std::string GetCleanNamespace() {
int fd = Connect(1);
if (fd == -1) {
PLOGE("GetCleanNamespace");

return "";
}

socket_utils::write_u8(fd, (uint8_t) SocketAction::GetCleanNamespace);
socket_utils::write_u32(fd, getpid());

uint32_t target_pid = socket_utils::read_u32(fd);
int target_fd = 0;

if (target_pid == 0) goto error;

target_fd = (int)socket_utils::read_u32(fd);
if (target_fd == 0) goto error;

return "/proc/" + std::to_string(target_pid) + "/fd/" + std::to_string(target_fd);

error:
close(fd);

return "";
}
}
9 changes: 7 additions & 2 deletions loader/src/common/dl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,14 @@ void* DlopenExt(const char* path, int flags) {
}

void* DlopenMem(int fd, int flags) {
auto info = android_dlextinfo{
auto info = android_dlextinfo {
.flags = ANDROID_DLEXT_USE_LIBRARY_FD,
.library_fd = fd
.reserved_addr = NULL,
.reserved_size = 0,
.relro_fd = 0,
.library_fd = fd,
.library_fd_offset = 0,
.library_namespace = NULL
};

auto* handle = android_dlopen_ext("/jit-cache-zygisk", flags, &info);
Expand Down
3 changes: 3 additions & 0 deletions loader/src/include/daemon.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ namespace zygiskd {
GetModuleDir,
ZygoteRestart,
SystemServerStarted,
GetCleanNamespace
};

void Init(const char *path);
Expand All @@ -103,4 +104,6 @@ namespace zygiskd {
void SystemServerStarted();

void GetInfo(struct zygote_info *info);

std::string GetCleanNamespace();
}
63 changes: 47 additions & 16 deletions loader/src/injector/hook.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,18 +138,52 @@ DCL_HOOK_FUNC(int, fork) {
return (g_ctx && g_ctx->pid >= 0) ? g_ctx->pid : old_fork();
}

void clean_mnt_ns() {
std::string path = zygiskd::GetCleanNamespace();
LOGI("Switching to clean namespace: %s", path.data());

if (path.empty()) {
LOGE("Failed to get clean namespace path");

return;
}

int nsfd = open(path.data(), O_RDONLY | O_CLOEXEC);
if (nsfd == -1) {
LOGE("Failed to open clean namespace: %s", strerror(errno));

return;
}

if (setns(nsfd, CLONE_NEWNS) == -1) {
LOGE("Failed to setns clean namespace: %s", strerror(errno));

close(nsfd);

return;
}

close(nsfd);

LOGD("Switched to clean namespace");

return;
}

// Unmount stuffs in the process's private mount namespace
DCL_HOOK_FUNC(int, unshare, int flags) {
int res = old_unshare(flags);
if (g_ctx && (flags & CLONE_NEWNS) != 0 && res == 0 &&
// For some unknown reason, unmounting app_process in SysUI can break.
// This is reproducible on the official AVD running API 26 and 27.
// Simply avoid doing any unmounts for SysUI to avoid potential issues.
(g_ctx->info_flags & PROCESS_IS_SYS_UI) == 0) {
if (g_ctx->flags[DO_REVERT_UNMOUNT] && !cached_map_infos.empty())
(g_ctx->info_flags & PROCESS_IS_FIRST_STARTED) == 0) {
if (g_ctx->flags[DO_REVERT_UNMOUNT]) clean_mnt_ns();
else if (!(g_ctx->info_flags & (PROCESS_IS_MANAGER | PROCESS_GRANTED_ROOT)))
do_umount(cached_mountinfo);

/* Zygisksu changed: No umount app_process */
old_unshare(CLONE_NEWNS);

// Restore errno back to 0
errno = 0;
Expand Down Expand Up @@ -596,7 +630,17 @@ void ZygiskContext::run_modules_post() {
/* Zygisksu changed: Load module fds */
void ZygiskContext::app_specialize_pre() {
flags[APP_SPECIALIZE] = true;
info_flags = zygiskd::GetProcessFlags(g_ctx->args.app->uid);

info_flags = zygiskd::GetProcessFlags(getpid());
if (info_flags & PROCESS_ON_DENYLIST) {
if (info_flags & PROCESS_ROOT_IS_KSU) {
cached_mountinfo = fill_ksu_umount_paths();
} else if (info_flags & PROCESS_ROOT_IS_APATCH){
cached_mountinfo = fill_apatch_umount_paths();
} else if (info_flags & PROCESS_ROOT_IS_MAGISK) {
cached_mountinfo = fill_magisk_umount_paths();
}
}

if ((info_flags & PROCESS_ON_DENYLIST) == PROCESS_ON_DENYLIST) {
flags[DO_REVERT_UNMOUNT] = true;
Expand Down Expand Up @@ -798,19 +842,6 @@ void hook_functions() {
}
}

uint32_t flags = zygiskd::GetProcessFlags(getpid());
if (flags & PROCESS_ON_DENYLIST) {
LOGD("Process is on denylist, reverting unmounts");

if (flags & PROCESS_ROOT_IS_KSU) {
cached_mountinfo = fill_ksu_umount_paths();
} else if (flags & PROCESS_ROOT_IS_APATCH){
cached_mountinfo = fill_apatch_umount_paths();
} else if (flags & PROCESS_ROOT_IS_MAGISK) {
cached_mountinfo = fill_magisk_umount_paths();
}
}

PLT_HOOK_REGISTER(android_runtime_dev, android_runtime_inode, fork);
PLT_HOOK_REGISTER(android_runtime_dev, android_runtime_inode, unshare);
PLT_HOOK_REGISTER(android_runtime_dev, android_runtime_inode, strdup);
Expand Down
4 changes: 2 additions & 2 deletions loader/src/injector/module.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,9 +130,9 @@ namespace {
PROCESS_ROOT_IS_APATCH = (1u << 27),
PROCESS_ROOT_IS_KSU = (1u << 29),
PROCESS_ROOT_IS_MAGISK = (1u << 30),
PROCESS_IS_SYS_UI = (1u << 31),
PROCESS_IS_FIRST_STARTED = (1u << 31),

PRIVATE_MASK = PROCESS_IS_SYS_UI
PRIVATE_MASK = PROCESS_IS_FIRST_STARTED
};

struct api_abi_base {
Expand Down
6 changes: 3 additions & 3 deletions zygiskd/src/constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ enum DaemonSocketAction {
RequestCompanionSocket = 5,
GetModuleDir = 6,
ZygoteRestart = 7,
SystemServerStarted = 8
SystemServerStarted = 8,
GetCleanNamespace = 9
};

enum ProcessFlags: uint32_t {
Expand All @@ -43,8 +44,7 @@ enum ProcessFlags: uint32_t {
PROCESS_ROOT_IS_APATCH = (1u << 27),
PROCESS_ROOT_IS_KSU = (1u << 29),
PROCESS_ROOT_IS_MAGISK = (1u << 30),
PROCESS_IS_SYS_UI = (1u << 31),
PROCESS_IS_SYSUI = (1u << 31)
PROCESS_IS_FIRST_STARTED = (1u << 31)
};

enum RootImplState {
Expand Down
17 changes: 17 additions & 0 deletions zygiskd/src/root_impl/common.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#include <stdio.h>
#include <string.h>
#include <errno.h>

#include <sys/types.h>
#include <sys/stat.h>

#include "../utils.h"
#include "kernelsu.h"
Expand Down Expand Up @@ -124,3 +127,17 @@ bool uid_is_manager(uid_t uid) {
}
}
}

bool uid_is_systemui(uid_t uid) {
struct stat s;
if (stat("/data/user_de/0/com.android.systemui", &s) == -1) {
if (errno != ENOENT) {
LOGE("Failed to stat SystemUI data directory: %s\n", strerror(errno));
}
errno = 0;

return false;
}

return s.st_uid == uid;
}
2 changes: 2 additions & 0 deletions zygiskd/src/root_impl/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,6 @@ bool uid_should_umount(uid_t uid);

bool uid_is_manager(uid_t uid);

bool uid_is_systemui(uid_t uid);

#endif /* COMMON_H */
Loading

0 comments on commit ab27ffe

Please sign in to comment.