mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-01-12 16:03:36 +00:00
Implement MagiskHide through code injection
This commit is contained in:
parent
d2acd59ea8
commit
9a28dd4f6e
@ -36,10 +36,20 @@ static bool verify_client(pid_t pid) {
|
|||||||
return !(stat(path, &st) || st.st_dev != self_st.st_dev || st.st_ino != self_st.st_ino);
|
return !(stat(path, &st) || st.st_dev != self_st.st_dev || st.st_ino != self_st.st_ino);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool check_zygote(pid_t pid) {
|
||||||
|
char buf[32];
|
||||||
|
sprintf(buf, "/proc/%d/attr/current", pid);
|
||||||
|
auto fp = open_file(buf, "r");
|
||||||
|
if (!fp)
|
||||||
|
return false;
|
||||||
|
fscanf(fp.get(), "%s", buf);
|
||||||
|
return buf == "u:r:zygote:s0"sv;
|
||||||
|
}
|
||||||
|
|
||||||
static void request_handler(int client, int req_code, ucred cred) {
|
static void request_handler(int client, int req_code, ucred cred) {
|
||||||
switch (req_code) {
|
switch (req_code) {
|
||||||
case MAGISKHIDE:
|
case MAGISKHIDE:
|
||||||
magiskhide_handler(client);
|
magiskhide_handler(client, &cred);
|
||||||
break;
|
break;
|
||||||
case SUPERUSER:
|
case SUPERUSER:
|
||||||
su_daemon_handler(client, &cred);
|
su_daemon_handler(client, &cred);
|
||||||
@ -74,7 +84,12 @@ static void handle_request(int client) {
|
|||||||
// Verify client credentials
|
// Verify client credentials
|
||||||
ucred cred;
|
ucred cred;
|
||||||
get_client_cred(client, &cred);
|
get_client_cred(client, &cred);
|
||||||
if (cred.uid != 0 && !verify_client(cred.pid))
|
|
||||||
|
bool is_root = cred.uid == 0;
|
||||||
|
bool is_zygote = check_zygote(cred.pid);
|
||||||
|
bool is_client = verify_client(cred.pid);
|
||||||
|
|
||||||
|
if (!is_root && !is_zygote && !is_client)
|
||||||
goto shortcut;
|
goto shortcut;
|
||||||
|
|
||||||
req_code = read_int(client);
|
req_code = read_int(client);
|
||||||
@ -83,13 +98,12 @@ static void handle_request(int client) {
|
|||||||
|
|
||||||
// Check client permissions
|
// Check client permissions
|
||||||
switch (req_code) {
|
switch (req_code) {
|
||||||
case MAGISKHIDE:
|
|
||||||
case POST_FS_DATA:
|
case POST_FS_DATA:
|
||||||
case LATE_START:
|
case LATE_START:
|
||||||
case BOOT_COMPLETE:
|
case BOOT_COMPLETE:
|
||||||
case SQLITE_CMD:
|
case SQLITE_CMD:
|
||||||
case GET_PATH:
|
case GET_PATH:
|
||||||
if (cred.uid != 0) {
|
if (!is_root) {
|
||||||
write_int(client, ROOT_REQUIRED);
|
write_int(client, ROOT_REQUIRED);
|
||||||
goto shortcut;
|
goto shortcut;
|
||||||
}
|
}
|
||||||
@ -100,6 +114,12 @@ static void handle_request(int client) {
|
|||||||
goto shortcut;
|
goto shortcut;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case MAGISKHIDE: // accept hide request from zygote
|
||||||
|
if (!is_root && !is_zygote) {
|
||||||
|
write_int(client, ROOT_REQUIRED);
|
||||||
|
goto shortcut;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Simple requests
|
// Simple requests
|
||||||
|
@ -44,9 +44,13 @@ int connect_daemon(bool create = false);
|
|||||||
void post_fs_data(int client);
|
void post_fs_data(int client);
|
||||||
void late_start(int client);
|
void late_start(int client);
|
||||||
void boot_complete(int client);
|
void boot_complete(int client);
|
||||||
void magiskhide_handler(int client);
|
void magiskhide_handler(int client, ucred *cred);
|
||||||
void su_daemon_handler(int client, ucred *credential);
|
void su_daemon_handler(int client, ucred *credential);
|
||||||
|
|
||||||
// MagiskHide
|
// MagiskHide
|
||||||
void auto_start_magiskhide(bool late_props);
|
void auto_start_magiskhide(bool late_props);
|
||||||
int stop_magiskhide();
|
int stop_magiskhide();
|
||||||
|
|
||||||
|
// For injected process to access daemon
|
||||||
|
int remote_check_hide(int uid, const char *process);
|
||||||
|
void remote_request_hide();
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include <xhook.h>
|
#include <xhook.h>
|
||||||
#include <utils.hpp>
|
#include <utils.hpp>
|
||||||
#include <flags.hpp>
|
#include <flags.hpp>
|
||||||
|
#include <daemon.hpp>
|
||||||
|
|
||||||
#include "inject.hpp"
|
#include "inject.hpp"
|
||||||
|
|
||||||
@ -17,18 +18,11 @@ using namespace std;
|
|||||||
extern const JNINativeMethod name##_methods[]; \
|
extern const JNINativeMethod name##_methods[]; \
|
||||||
extern const int name##_methods_num;
|
extern const int name##_methods_num;
|
||||||
|
|
||||||
// For some reason static vectors won't work, use pointers instead
|
|
||||||
static vector<tuple<const char *, const char *, void **>> *xhook_list;
|
|
||||||
static vector<JNINativeMethod> *jni_list;
|
|
||||||
|
|
||||||
static JavaVM *g_jvm;
|
|
||||||
static int prev_fork_pid = -1;
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
struct HookContext {
|
struct HookContext {
|
||||||
int pid;
|
int pid;
|
||||||
bool unload;
|
bool do_hide;
|
||||||
};
|
};
|
||||||
|
|
||||||
// JNI method declarations
|
// JNI method declarations
|
||||||
@ -38,6 +32,14 @@ DCL_JNI_FUNC(nativeForkSystemServer)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// For some reason static vectors won't work, use pointers instead
|
||||||
|
static vector<tuple<const char *, const char *, void **>> *xhook_list;
|
||||||
|
static vector<JNINativeMethod> *jni_list;
|
||||||
|
|
||||||
|
static JavaVM *g_jvm;
|
||||||
|
static int prev_fork_pid = -1;
|
||||||
|
static HookContext *current_ctx;
|
||||||
|
|
||||||
#define HOOK_JNI(method) \
|
#define HOOK_JNI(method) \
|
||||||
if (newMethods[i].name == #method##sv) { \
|
if (newMethods[i].name == #method##sv) { \
|
||||||
auto orig = new JNINativeMethod(); \
|
auto orig = new JNINativeMethod(); \
|
||||||
@ -90,6 +92,17 @@ DCL_HOOK_FUNC(int, fork) {
|
|||||||
return pid;
|
return pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DCL_HOOK_FUNC(int, selinux_android_setcontext,
|
||||||
|
uid_t uid, int isSystemServer, const char *seinfo, const char *pkgname) {
|
||||||
|
if (current_ctx && current_ctx->do_hide) {
|
||||||
|
// Ask magiskd to hide ourselves before switching context
|
||||||
|
// because magiskd socket is not accessible on Android 8.0+
|
||||||
|
remote_request_hide();
|
||||||
|
LOGD("hook: process successfully hidden\n");
|
||||||
|
}
|
||||||
|
return old_selinux_android_setcontext(uid, isSystemServer, seinfo, pkgname);
|
||||||
|
}
|
||||||
|
|
||||||
static int sigmask(int how, int signum) {
|
static int sigmask(int how, int signum) {
|
||||||
sigset_t set;
|
sigset_t set;
|
||||||
sigemptyset(&set);
|
sigemptyset(&set);
|
||||||
@ -106,10 +119,43 @@ static int pre_specialize_fork() {
|
|||||||
|
|
||||||
// -----------------------------------------------------------------
|
// -----------------------------------------------------------------
|
||||||
|
|
||||||
|
static void nativeSpecializeAppProcess_pre(HookContext *ctx,
|
||||||
|
JNIEnv *env, jclass clazz, jint &uid, jint &gid, jintArray &gids, jint &runtime_flags,
|
||||||
|
jobjectArray &rlimits, jint &mount_external, jstring &se_info, jstring &nice_name,
|
||||||
|
jboolean &is_child_zygote, jstring &instruction_set, jstring &app_data_dir,
|
||||||
|
jboolean &is_top_app, jobjectArray &pkg_data_info_list,
|
||||||
|
jobjectArray &whitelisted_data_info_list, jboolean &mount_data_dirs,
|
||||||
|
jboolean &mount_storage_dirs) {
|
||||||
|
|
||||||
|
current_ctx = ctx;
|
||||||
|
|
||||||
|
const char *process = env->GetStringUTFChars(nice_name, nullptr);
|
||||||
|
LOGD("hook: %s %s\n", __FUNCTION__, process);
|
||||||
|
|
||||||
|
if (mount_external != 0 /* TODO: Handle MOUNT_EXTERNAL_NONE cases */
|
||||||
|
&& remote_check_hide(uid, process)) {
|
||||||
|
ctx->do_hide = true;
|
||||||
|
LOGI("hook: [%s] should be hidden\n", process);
|
||||||
|
}
|
||||||
|
|
||||||
|
env->ReleaseStringUTFChars(nice_name, process);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void nativeSpecializeAppProcess_post(HookContext *ctx, JNIEnv *env, jclass clazz) {
|
||||||
|
LOGD("hook: %s\n", __FUNCTION__);
|
||||||
|
|
||||||
|
if (ctx->do_hide)
|
||||||
|
self_unload();
|
||||||
|
|
||||||
|
current_ctx = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------
|
||||||
|
|
||||||
static void nativeForkAndSpecialize_pre(HookContext *ctx,
|
static void nativeForkAndSpecialize_pre(HookContext *ctx,
|
||||||
JNIEnv *env, jclass clazz, jint &uid, jint &gid, jintArray &gids, jint &runtime_flags,
|
JNIEnv *env, jclass clazz, jint &uid, jint &gid, jintArray &gids, jint &runtime_flags,
|
||||||
jobjectArray &rlimits, jint &mount_external, jstring &se_info, jstring &nice_name,
|
jobjectArray &rlimits, jint &mount_external, jstring &se_info, jstring &nice_name,
|
||||||
jintArray &fds_to_close, jintArray &fds_to_ignore, /* These 2 arguments are unique to fork */
|
jintArray fds_to_close, jintArray fds_to_ignore, /* These 2 arguments are unique to fork */
|
||||||
jboolean &is_child_zygote, jstring &instruction_set, jstring &app_data_dir,
|
jboolean &is_child_zygote, jstring &instruction_set, jstring &app_data_dir,
|
||||||
jboolean &is_top_app, jobjectArray &pkg_data_info_list,
|
jboolean &is_top_app, jobjectArray &pkg_data_info_list,
|
||||||
jobjectArray &whitelisted_data_info_list, jboolean &mount_data_dirs,
|
jobjectArray &whitelisted_data_info_list, jboolean &mount_data_dirs,
|
||||||
@ -120,40 +166,19 @@ static void nativeForkAndSpecialize_pre(HookContext *ctx,
|
|||||||
if (ctx->pid != 0)
|
if (ctx->pid != 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// TODO: check if we need to do hiding
|
nativeSpecializeAppProcess_pre(
|
||||||
// Demonstrate self unload in child process
|
ctx, env, clazz, uid, gid, gids, runtime_flags, rlimits, mount_external, se_info,
|
||||||
ctx->unload = true;
|
nice_name, is_child_zygote, instruction_set, app_data_dir, is_top_app,
|
||||||
|
pkg_data_info_list, whitelisted_data_info_list, mount_data_dirs, mount_storage_dirs);
|
||||||
LOGD("hook: %s\n", __FUNCTION__);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void nativeForkAndSpecialize_post(HookContext *ctx, JNIEnv *env, jclass clazz) {
|
static void nativeForkAndSpecialize_post(HookContext *ctx, JNIEnv *env, jclass clazz) {
|
||||||
// Unblock SIGCHLD in case the original method didn't
|
// Unblock SIGCHLD in case the original method didn't
|
||||||
sigmask(SIG_UNBLOCK, SIGCHLD);
|
sigmask(SIG_UNBLOCK, SIGCHLD);
|
||||||
|
|
||||||
if (ctx->pid != 0)
|
if (ctx->pid != 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
LOGD("hook: %s\n", __FUNCTION__);
|
nativeSpecializeAppProcess_post(ctx, env, clazz);
|
||||||
|
|
||||||
if (ctx->unload)
|
|
||||||
self_unload();
|
|
||||||
}
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------
|
|
||||||
|
|
||||||
static void nativeSpecializeAppProcess_pre(HookContext *ctx,
|
|
||||||
JNIEnv *env, jclass clazz, jint &uid, jint &gid, jintArray &gids, jint &runtime_flags,
|
|
||||||
jobjectArray &rlimits, jint &mount_external, jstring &se_info, jstring &nice_name,
|
|
||||||
jboolean &is_child_zygote, jstring &instruction_set, jstring &app_data_dir,
|
|
||||||
jboolean &is_top_app, jobjectArray &pkg_data_info_list,
|
|
||||||
jobjectArray &whitelisted_data_info_list, jboolean &mount_data_dirs,
|
|
||||||
jboolean &mount_storage_dirs) {
|
|
||||||
LOGD("hook: %s\n", __FUNCTION__);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void nativeSpecializeAppProcess_post(HookContext *ctx, JNIEnv *env, jclass clazz) {
|
|
||||||
LOGD("hook: %s\n", __FUNCTION__);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------
|
// -----------------------------------------------------------------
|
||||||
@ -167,6 +192,7 @@ static void nativeForkSystemServer_pre(HookContext *ctx,
|
|||||||
if (ctx->pid != 0)
|
if (ctx->pid != 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
current_ctx = ctx;
|
||||||
LOGD("hook: %s\n", __FUNCTION__);
|
LOGD("hook: %s\n", __FUNCTION__);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -178,6 +204,7 @@ static void nativeForkSystemServer_post(HookContext *ctx, JNIEnv *env, jclass cl
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
LOGD("hook: %s\n", __FUNCTION__);
|
LOGD("hook: %s\n", __FUNCTION__);
|
||||||
|
current_ctx = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------
|
// -----------------------------------------------------------------
|
||||||
@ -216,6 +243,7 @@ void hook_functions() {
|
|||||||
|
|
||||||
XHOOK_REGISTER(".*\\libandroid_runtime.so$", jniRegisterNativeMethods);
|
XHOOK_REGISTER(".*\\libandroid_runtime.so$", jniRegisterNativeMethods);
|
||||||
XHOOK_REGISTER(".*\\libandroid_runtime.so$", fork);
|
XHOOK_REGISTER(".*\\libandroid_runtime.so$", fork);
|
||||||
|
XHOOK_REGISTER(".*\\libandroid_runtime.so$", selinux_android_setcontext);
|
||||||
hook_refresh();
|
hook_refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,7 +77,6 @@ static void lazy_unmount(const char* mountpoint) {
|
|||||||
LOGD("hide: Unmounted (%s)\n", mountpoint);
|
LOGD("hide: Unmounted (%s)\n", mountpoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if ENABLE_PTRACE_MONITOR
|
|
||||||
void hide_daemon(int pid) {
|
void hide_daemon(int pid) {
|
||||||
if (fork_dont_care() == 0) {
|
if (fork_dont_care() == 0) {
|
||||||
hide_unmount(pid);
|
hide_unmount(pid);
|
||||||
@ -86,7 +85,6 @@ void hide_daemon(int pid) {
|
|||||||
_exit(0);
|
_exit(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#define TMPFS_MNT(dir) (mentry->mnt_type == "tmpfs"sv && \
|
#define TMPFS_MNT(dir) (mentry->mnt_type == "tmpfs"sv && \
|
||||||
strncmp(mentry->mnt_dir, "/" #dir, sizeof("/" #dir) - 1) == 0)
|
strncmp(mentry->mnt_dir, "/" #dir, sizeof("/" #dir) - 1) == 0)
|
||||||
|
@ -274,7 +274,7 @@ int launch_magiskhide(bool late_props) {
|
|||||||
if (hide_state)
|
if (hide_state)
|
||||||
return HIDE_IS_ENABLED;
|
return HIDE_IS_ENABLED;
|
||||||
|
|
||||||
if (access("/proc/1/ns/mnt", F_OK) != 0)
|
if (access("/proc/self/ns/mnt", F_OK) != 0)
|
||||||
return HIDE_NO_NS;
|
return HIDE_NO_NS;
|
||||||
|
|
||||||
if (procfp == nullptr && (procfp = opendir("/proc")) == nullptr)
|
if (procfp == nullptr && (procfp = opendir("/proc")) == nullptr)
|
||||||
@ -344,3 +344,36 @@ void test_proc_monitor() {
|
|||||||
proc_monitor();
|
proc_monitor();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
int check_uid_map(int client) {
|
||||||
|
mutex_guard lock(hide_state_lock);
|
||||||
|
|
||||||
|
if (!hide_state)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
int uid = read_int(client);
|
||||||
|
string process = read_string(client);
|
||||||
|
|
||||||
|
if (uid % 100000 > 90000) {
|
||||||
|
// Isolated process
|
||||||
|
auto it = uid_proc_map.find(-1);
|
||||||
|
if (it == uid_proc_map.end())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for (auto &s : it->second) {
|
||||||
|
if (str_starts(process, s))
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
auto it = uid_proc_map.find(uid);
|
||||||
|
if (it == uid_proc_map.end())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for (auto &s : it->second) {
|
||||||
|
if (process == s)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@ -27,7 +27,7 @@ using namespace std;
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void magiskhide_handler(int client) {
|
void magiskhide_handler(int client, ucred *cred) {
|
||||||
int req = read_int(client);
|
int req = read_int(client);
|
||||||
int res = DAEMON_ERROR;
|
int res = DAEMON_ERROR;
|
||||||
|
|
||||||
@ -62,6 +62,15 @@ void magiskhide_handler(int client) {
|
|||||||
case HIDE_STATUS:
|
case HIDE_STATUS:
|
||||||
res = hide_enabled() ? HIDE_IS_ENABLED : HIDE_NOT_ENABLED;
|
res = hide_enabled() ? HIDE_IS_ENABLED : HIDE_NOT_ENABLED;
|
||||||
break;
|
break;
|
||||||
|
case REMOTE_CHECK_HIDE:
|
||||||
|
res = check_uid_map(client);
|
||||||
|
break;
|
||||||
|
case REMOTE_DO_HIDE:
|
||||||
|
kill(cred->pid, SIGSTOP);
|
||||||
|
write_int(client, 0);
|
||||||
|
hide_daemon(cred->pid);
|
||||||
|
close(client);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
write_int(client, res);
|
write_int(client, res);
|
||||||
@ -158,3 +167,26 @@ int magiskhide_main(int argc, char *argv[]) {
|
|||||||
return_code:
|
return_code:
|
||||||
return req == HIDE_STATUS ? (code == HIDE_IS_ENABLED ? 0 : 1) : code != DAEMON_SUCCESS;
|
return req == HIDE_STATUS ? (code == HIDE_IS_ENABLED ? 0 : 1) : code != DAEMON_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int remote_check_hide(int uid, const char *process) {
|
||||||
|
int fd = connect_daemon();
|
||||||
|
write_int(fd, MAGISKHIDE);
|
||||||
|
write_int(fd, REMOTE_CHECK_HIDE);
|
||||||
|
write_int(fd, uid);
|
||||||
|
write_string(fd, process);
|
||||||
|
int res = read_int(fd);
|
||||||
|
close(fd);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
void remote_request_hide() {
|
||||||
|
int fd = connect_daemon();
|
||||||
|
write_int(fd, MAGISKHIDE);
|
||||||
|
write_int(fd, REMOTE_DO_HIDE);
|
||||||
|
|
||||||
|
// Should receive SIGSTOP before reading anything
|
||||||
|
// During process stop, magiskd will cleanup our mount ns
|
||||||
|
read_int(fd);
|
||||||
|
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
#define ISOLATED_MAGIC "isolated"
|
#define ISOLATED_MAGIC "isolated"
|
||||||
|
|
||||||
// Global toggle for ptrace monitor
|
// Global toggle for ptrace monitor
|
||||||
#define ENABLE_PTRACE_MONITOR 1
|
#define ENABLE_PTRACE_MONITOR 0
|
||||||
|
|
||||||
// CLI entries
|
// CLI entries
|
||||||
int launch_magiskhide(bool late_props);
|
int launch_magiskhide(bool late_props);
|
||||||
@ -23,6 +23,7 @@ int stop_magiskhide();
|
|||||||
int add_list(int client);
|
int add_list(int client);
|
||||||
int rm_list(int client);
|
int rm_list(int client);
|
||||||
void ls_list(int client);
|
void ls_list(int client);
|
||||||
|
int check_uid_map(int client);
|
||||||
|
|
||||||
#if ENABLE_PTRACE_MONITOR
|
#if ENABLE_PTRACE_MONITOR
|
||||||
// Process monitoring
|
// Process monitoring
|
||||||
@ -52,6 +53,8 @@ enum {
|
|||||||
RM_HIDELIST,
|
RM_HIDELIST,
|
||||||
LS_HIDELIST,
|
LS_HIDELIST,
|
||||||
HIDE_STATUS,
|
HIDE_STATUS,
|
||||||
|
REMOTE_CHECK_HIDE,
|
||||||
|
REMOTE_DO_HIDE
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
@ -106,13 +106,14 @@ void sepolicy::magisk_rules() {
|
|||||||
// Don't allow pesky processes to monitor audit deny logs when poking magisk daemon socket
|
// Don't allow pesky processes to monitor audit deny logs when poking magisk daemon socket
|
||||||
dontaudit(ALL, SEPOL_PROC_DOMAIN, "unix_stream_socket", ALL);
|
dontaudit(ALL, SEPOL_PROC_DOMAIN, "unix_stream_socket", ALL);
|
||||||
|
|
||||||
// Only allow client processes to connect to magisk daemon socket
|
// Only allow client processes and zygote to connect to magisk daemon socket
|
||||||
allow(SEPOL_CLIENT_DOMAIN, SEPOL_PROC_DOMAIN, "unix_stream_socket", ALL);
|
allow(SEPOL_CLIENT_DOMAIN, SEPOL_PROC_DOMAIN, "unix_stream_socket", ALL);
|
||||||
|
allow("zygote", SEPOL_PROC_DOMAIN, "unix_stream_socket", ALL);
|
||||||
} else {
|
} else {
|
||||||
// Fallback to poking holes in sandbox as Android 4.3 to 7.1 set PR_SET_NO_NEW_PRIVS
|
// Fallback to poking holes in sandbox as Android 4.3 to 7.1 set PR_SET_NO_NEW_PRIVS
|
||||||
|
|
||||||
// Allow these processes to access MagiskSU
|
// Allow these processes to access MagiskSU
|
||||||
const char *clients[] { "init", "shell", "appdomain" };
|
const char *clients[] { "init", "shell", "appdomain", "zygote" };
|
||||||
for (auto type : clients) {
|
for (auto type : clients) {
|
||||||
if (!exists(type))
|
if (!exists(type))
|
||||||
continue;
|
continue;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user