Propagate Zygisk state to Magisk app

This commit is contained in:
topjohnwu
2021-09-18 02:38:53 -07:00
parent 7b25e74418
commit db590091b3
11 changed files with 99 additions and 85 deletions

View File

@ -376,6 +376,13 @@ bool get_manager(string *pkg) {
return get_manager(0, pkg, &st);
}
int get_manager_app_id() {
struct stat st;
if (get_manager(0, nullptr, &st))
return to_app_id(st.st_uid);
return -1;
}
void exec_sql(int client) {
run_finally f([=]{ close(client); });
string sql = read_string(client);

View File

@ -128,6 +128,7 @@ int get_db_strings(db_strings &str, int key = -1);
int get_uid_policy(su_access &su, int uid);
bool get_manager(int user_id, std::string *pkg, struct stat *st);
bool get_manager(std::string *pkg = nullptr);
int get_manager_app_id();
void exec_sql(int client);
char *db_exec(const char *sql);
char *db_exec(const char *sql, const db_row_cb &fn);

View File

@ -8,6 +8,7 @@
#include <utils.hpp>
#include <daemon.hpp>
#include <magisk.hpp>
#include <db.hpp>
#include "inject.hpp"
#include "../deny/deny.hpp"
@ -205,21 +206,17 @@ static int zygisk_log(int prio, const char *fmt, va_list ap) {
return ret;
}
bool remote_check_denylist(int uid, const char *process) {
void remote_get_app_info(int uid, const char *process, AppInfo *info) {
if (int fd = connect_daemon(); fd >= 0) {
write_int(fd, ZYGISK_REQUEST);
write_int(fd, ZYGISK_CHECK_DENYLIST);
write_int(fd, ZYGISK_GET_APPINFO);
write_int(fd, uid);
write_string(fd, process);
xxread(fd, info, sizeof(*info));
int ret = -1;
if (read_int(fd) == 0) {
write_int(fd, uid);
write_string(fd, process);
ret = read_int(fd);
}
close(fd);
return ret >= 0 && ret;
}
return false;
}
int remote_request_unmount() {
@ -254,15 +251,16 @@ static void setup_files(int client, ucred *cred) {
write_string(client, path);
}
static void check_denylist(int client) {
if (!denylist_enabled) {
write_int(client, DENY_NOT_ENFORCED);
return;
}
write_int(client, 0);
static void get_app_info(int client) {
AppInfo info{};
int uid = read_int(client);
string process = read_string(client);
write_int(client, is_deny_target(uid, process));
if (to_app_id(uid) == get_manager_app_id()) {
info.is_magisk_app = true;
} else if (denylist_enabled) {
info.on_denylist = is_deny_target(uid, process);
}
xwrite(client, &info, sizeof(info));
}
static void do_unmount(int client, ucred *cred) {
@ -290,8 +288,8 @@ void zygisk_handler(int client, ucred *cred) {
case ZYGISK_SETUP:
setup_files(client, cred);
break;
case ZYGISK_CHECK_DENYLIST:
check_denylist(client);
case ZYGISK_GET_APPINFO:
get_app_info(client);
break;
case ZYGISK_UNMOUNT:
do_unmount(client, cred);

View File

@ -43,8 +43,9 @@ struct HookContext {
const char *process;
int pid;
bitset<FLAG_MAX> flags;
AppInfo info;
HookContext() : pid(-1) {}
HookContext() : pid(-1), info{} {}
static void close_fds();
@ -139,7 +140,7 @@ DCL_HOOK_FUNC(int, fork) {
// This is the latest point where we can still connect to the magiskd main socket
DCL_HOOK_FUNC(int, selinux_android_setcontext,
uid_t uid, int isSystemServer, const char *seinfo, const char *pkgname) {
if (g_ctx && g_ctx->flags[DENY_FLAG]) {
if (g_ctx && g_ctx->info.on_denylist) {
if (remote_request_unmount() == 0) {
LOGD("zygisk: mount namespace cleaned up\n");
}
@ -241,9 +242,10 @@ void HookContext::nativeSpecializeAppProcess_pre() {
VLOG("zygisk: pre specialize [%s]\n", process);
}
remote_get_app_info(args->uid, process, &info);
/* TODO: Handle MOUNT_EXTERNAL_NONE */
if (args->mount_external != 0 && remote_check_denylist(args->uid, process)) {
flags[DENY_FLAG] = true;
if (args->mount_external != 0 && info.on_denylist) {
LOGI("zygisk: [%s] is on the denylist\n", process);
} else {
run_modules_pre();
@ -258,11 +260,14 @@ void HookContext::nativeSpecializeAppProcess_post() {
}
env->ReleaseStringUTFChars(args->nice_name, process);
if (flags[DENY_FLAG]) {
if (info.on_denylist) {
self_unload();
} else {
run_modules_post();
}
if (info.is_magisk_app) {
setenv("ZYGISK_ENABLED", "1", 1);
}
g_ctx = nullptr;
}

View File

@ -8,7 +8,7 @@
enum : int {
ZYGISK_SETUP,
ZYGISK_CHECK_DENYLIST,
ZYGISK_GET_APPINFO,
ZYGISK_UNMOUNT,
ZYGISK_GET_LOG_PIPE,
};
@ -22,8 +22,13 @@ uintptr_t get_function_off(int pid, uintptr_t addr, char *lib);
// Get function address, given library name + offset
uintptr_t get_function_addr(int pid, const char *lib, uintptr_t off);
struct AppInfo {
bool is_magisk_app;
bool on_denylist;
};
void self_unload();
void hook_functions();
bool unhook_functions();
bool remote_check_denylist(int uid, const char *process);
void remote_get_app_info(int uid, const char *process, AppInfo *info);
int remote_request_unmount();