DenyList unmount without magiskd

This commit is contained in:
topjohnwu 2021-10-27 03:54:48 -07:00
parent 983b74be77
commit 8bd6aca0dd
5 changed files with 13 additions and 69 deletions

View File

@ -20,9 +20,7 @@ void ls_list(int client);
// Utility functions
bool is_deny_target(int uid, std::string_view process);
// Revert
void revert_daemon(int pid, int client);
void revert_unmount(int pid = -1);
void revert_unmount();
extern std::atomic<bool> denylist_enabled;
extern int cached_manager_app_id;

View File

@ -2,8 +2,6 @@
#include <magisk.hpp>
#include <utils.hpp>
#include <selinux.hpp>
#include <resetprop.hpp>
#include "deny.hpp"
@ -14,23 +12,9 @@ static void lazy_unmount(const char* mountpoint) {
LOGD("denylist: Unmounted (%s)\n", mountpoint);
}
void revert_daemon(int pid, int client) {
if (fork_dont_care() == 0) {
revert_unmount(pid);
write_int(client, 0);
_exit(0);
}
}
#define TMPFS_MNT(dir) (mentry->mnt_type == "tmpfs"sv && str_starts(mentry->mnt_dir, "/" #dir))
void revert_unmount(int pid) {
if (pid > 0) {
if (switch_mnt_ns(pid))
return;
LOGD("denylist: handling PID=[%d]\n", pid);
}
void revert_unmount() {
vector<string> targets;
// Unmount dummy skeletons and MAGISKTMP

View File

@ -202,17 +202,6 @@ std::vector<int> remote_get_info(int uid, const char *process, AppInfo *info) {
return fds;
}
int remote_request_unmount() {
if (int fd = connect_daemon(); fd >= 0) {
write_int(fd, ZYGISK_REQUEST);
write_int(fd, ZYGISK_UNMOUNT);
int ret = read_int(fd);
close(fd);
return ret;
}
return DAEMON_ERROR;
}
// The following code runs in magiskd
static bool get_exe(int pid, char *buf, size_t sz) {
@ -373,15 +362,6 @@ static void get_process_info(int client, const sock_cred *cred) {
}
}
static void do_unmount(int client, const sock_cred *cred) {
if (denylist_enabled) {
LOGD("zygisk: cleanup mount namespace for pid=[%d]\n", cred->pid);
revert_daemon(cred->pid, client);
} else {
write_int(client, DENY_NOT_ENFORCED);
}
}
static void send_log_pipe(int fd) {
// There is race condition here, but we can't really do much about it...
if (logd_fd >= 0) {
@ -405,9 +385,6 @@ void zygisk_handler(int client, const sock_cred *cred) {
case ZYGISK_GET_INFO:
get_process_info(client, cred);
break;
case ZYGISK_UNMOUNT:
do_unmount(client, cred);
break;
case ZYGISK_GET_LOG_PIPE:
send_log_pipe(client);
break;

View File

@ -10,6 +10,7 @@
#include "zygisk.hpp"
#include "memory.hpp"
#include "module.hpp"
#include "deny/deny.hpp"
using namespace std;
using jni_hook::hash_map;
@ -50,7 +51,6 @@ struct HookContext {
HookContext() : pid(-1), info{} {}
static void close_fds();
void toggle_unmount();
DCL_PRE_POST(fork)
void run_modules_pre(const vector<int> &fds);
@ -144,25 +144,18 @@ DCL_HOOK_FUNC(int, fork) {
return (g_ctx && g_ctx->pid >= 0) ? g_ctx->pid : old_fork();
}
// Unmount app_process overlays in the process's private mount namespace
// Unmount stuffs in the process's private mount namespace
DCL_HOOK_FUNC(int, unshare, int flags) {
int res = old_unshare(flags);
if (g_ctx && res == 0) {
umount2("/system/bin/app_process64", MNT_DETACH);
umount2("/system/bin/app_process32", MNT_DETACH);
}
return res;
}
// 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[UNMOUNT_FLAG]) {
if (remote_request_unmount() == 0) {
ZLOGD("mount namespace cleaned up\n");
if (g_ctx->flags[UNMOUNT_FLAG]) {
revert_unmount();
} else {
umount2("/system/bin/app_process64", MNT_DETACH);
umount2("/system/bin/app_process32", MNT_DETACH);
}
}
return old_selinux_android_setcontext(uid, isSystemServer, seinfo, pkgname);
return res;
}
// A place to clean things up before calling into zygote::ForkCommon/SpecializeCommon
@ -313,7 +306,7 @@ void ZygiskModule::setOption(zygisk::Option opt) {
return;
switch (opt) {
case zygisk::FORCE_DENYLIST_UNMOUNT:
g_ctx->toggle_unmount();
g_ctx->flags[UNMOUNT_FLAG] = true;
break;
case zygisk::DLCLOSE_MODULE_LIBRARY:
unload = true;
@ -362,13 +355,6 @@ void HookContext::close_fds() {
close(logd_fd.exchange(-1));
}
void HookContext::toggle_unmount() {
if (flags[APP_SPECIALIZE]) {
// TODO: Handle MOUNT_EXTERNAL_NONE
flags[UNMOUNT_FLAG] = args->mount_external != 0;
}
}
// -----------------------------------------------------------------
void HookContext::nativeSpecializeAppProcess_pre() {
@ -383,8 +369,9 @@ void HookContext::nativeSpecializeAppProcess_pre() {
auto module_fds = remote_get_info(args->uid, process, &info);
if (info.on_denylist) {
// TODO: Handle MOUNT_EXTERNAL_NONE on older platforms
ZLOGI("[%s] is on the denylist\n", process);
toggle_unmount();
flags[UNMOUNT_FLAG] = true;
} else {
run_modules_pre(module_fds);
}
@ -513,7 +500,6 @@ void hook_functions() {
XHOOK_REGISTER(ANDROID_RUNTIME, fork);
XHOOK_REGISTER(ANDROID_RUNTIME, unshare);
XHOOK_REGISTER(ANDROID_RUNTIME, selinux_android_setcontext);
XHOOK_REGISTER(ANDROID_RUNTIME, jniRegisterNativeMethods);
XHOOK_REGISTER_SYM(ANDROID_RUNTIME, "__android_log_close", android_log_close);
hook_refresh();

View File

@ -10,7 +10,6 @@
enum : int {
ZYGISK_SETUP,
ZYGISK_GET_INFO,
ZYGISK_UNMOUNT,
ZYGISK_GET_LOG_PIPE,
ZYGISK_CONNECT_COMPANION,
};