From 351f0269ae7bee0065692ea0f9f1d99ec3052488 Mon Sep 17 00:00:00 2001 From: topjohnwu Date: Thu, 19 May 2022 22:54:49 -0700 Subject: [PATCH] Install stub if necessary --- build.py | 8 +++---- native/jni/core/bootstages.cpp | 22 +++--------------- native/jni/core/package.cpp | 41 ++++++++++++++++++++++++++++------ native/jni/include/daemon.hpp | 3 ++- native/jni/su/su_daemon.cpp | 2 +- scripts/avd_magisk.sh | 2 ++ 6 files changed, 46 insertions(+), 32 deletions(-) diff --git a/build.py b/build.py index 62355e81c..98ef2376c 100755 --- a/build.py +++ b/build.py @@ -445,8 +445,8 @@ def setup_ndk(args): def setup_avd(args): if not args.skip: - build_binary(args) - build_app(args) + args.release = False + build_all(args) header('* Setting up emulator') @@ -463,8 +463,8 @@ def setup_avd(args): def patch_avd_ramdisk(args): if not args.skip: - build_binary(args) - build_app(args) + args.release = False + build_all(args) header('* Patching emulator ramdisk.img') diff --git a/native/jni/core/bootstages.cpp b/native/jni/core/bootstages.cpp index e9179d703..077c0695b 100644 --- a/native/jni/core/bootstages.cpp +++ b/native/jni/core/bootstages.cpp @@ -18,7 +18,6 @@ using namespace std; static bool safe_mode = false; -static int stub_fd = -1; bool zygisk_enabled = false; /********* @@ -123,10 +122,7 @@ static bool magisk_env() { LOGI("* Initializing Magisk environment\n"); - string stub_path = MAGISKTMP + "/stub.apk"; - stub_fd = xopen(stub_path.data(), O_RDONLY | O_CLOEXEC); - unlink(stub_path.data()); - + preserve_stub_apk(); string pkg; get_manager(0, &pkg); @@ -375,18 +371,6 @@ void boot_complete(int client) { if (access(SECURE_DIR, F_OK) != 0) xmkdir(SECURE_DIR, 0700); - if (stub_fd > 0) { - if (get_manager() < 0) { - // Install stub - struct stat st{}; - fstat(stub_fd, &st); - char apk[] = "/data/stub.apk"; - int dfd = xopen(apk, O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, 0600); - xsendfile(dfd, stub_fd, nullptr, st.st_size); - close(dfd); - install_apk(apk); - } - close(stub_fd); - stub_fd = -1; - } + // Ensure manager exists + get_manager(0, nullptr, true); } diff --git a/native/jni/core/package.cpp b/native/jni/core/package.cpp index 417702ad1..82a91b4cd 100644 --- a/native/jni/core/package.cpp +++ b/native/jni/core/package.cpp @@ -3,6 +3,8 @@ #include #include +#include "core.hpp" + using namespace std; // These functions will be called on every single zygote process specialization and su request, @@ -10,11 +12,13 @@ using namespace std; // or simply skipped unless necessary. static atomic pkg_xml_ino = 0; +static atomic_flag skip_check; -// pkg_lock protects mgr_app_id and mgr_pkg static pthread_mutex_t pkg_lock = PTHREAD_MUTEX_INITIALIZER; +// pkg_lock protects all following variables static int mgr_app_id = -1; static string *mgr_pkg; +static int stub_apk_fd = -1; bool need_pkg_refresh() { struct stat st{}; @@ -24,8 +28,7 @@ bool need_pkg_refresh() { // Packages have not changed return false; } else { - mutex_guard g(pkg_lock); - mgr_app_id = -1; + skip_check.clear(); return true; } } @@ -62,7 +65,27 @@ vector get_app_no_list() { return list; } -int get_manager(int user_id, string *pkg) { +void preserve_stub_apk() { + mutex_guard g(pkg_lock); + string stub_path = MAGISKTMP + "/stub.apk"; + stub_apk_fd = xopen(stub_path.data(), O_RDONLY | O_CLOEXEC); + unlink(stub_path.data()); +} + +static void install_stub() { + if (stub_apk_fd < 0) + return; + struct stat st{}; + fstat(stub_apk_fd, &st); + char apk[] = "/data/stub.apk"; + int dfd = xopen(apk, O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, 0600); + xsendfile(dfd, stub_apk_fd, nullptr, st.st_size); + lseek(stub_apk_fd, 0, SEEK_SET); + close(dfd); + install_apk(apk); +} + +int get_manager(int user_id, string *pkg, bool install) { mutex_guard g(pkg_lock); char app_path[128]; @@ -70,14 +93,16 @@ int get_manager(int user_id, string *pkg) { if (mgr_pkg == nullptr) default_new(mgr_pkg); - int app_id = mgr_app_id; - if (app_id > 0) { + if (skip_check.test_and_set()) { + if (mgr_app_id < 0) { + goto not_found; + } // Just need to check whether the app is installed in the user const char *name = mgr_pkg->empty() ? JAVA_PACKAGE_NAME : mgr_pkg->data(); snprintf(app_path, sizeof(app_path), "%s/%d/%s", APP_DATA_DIR, user_id, name); if (access(app_path, F_OK) == 0) { if (pkg) *pkg = name; - return user_id * AID_USER_OFFSET + app_id; + return user_id * AID_USER_OFFSET + mgr_app_id; } else { goto not_found; } @@ -166,6 +191,8 @@ int get_manager(int user_id, string *pkg) { // No manager app is found, clear all cached value mgr_app_id = -1; mgr_pkg->clear(); + if (install) + install_stub(); } not_found: diff --git a/native/jni/include/daemon.hpp b/native/jni/include/daemon.hpp index 1be549bf3..9ba91896c 100644 --- a/native/jni/include/daemon.hpp +++ b/native/jni/include/daemon.hpp @@ -86,9 +86,10 @@ void su_daemon_handler(int client, const sock_cred *cred); void zygisk_handler(int client, const sock_cred *cred); // Package +void preserve_stub_apk(); bool need_pkg_refresh(); std::vector get_app_no_list(); -int get_manager(int user_id = 0, std::string *pkg = nullptr); +int get_manager(int user_id = 0, std::string *pkg = nullptr, bool install = false); // Denylist void initialize_denylist(); diff --git a/native/jni/su/su_daemon.cpp b/native/jni/su/su_daemon.cpp index e4c968465..f163af33e 100644 --- a/native/jni/su/su_daemon.cpp +++ b/native/jni/su/su_daemon.cpp @@ -82,7 +82,7 @@ void su_info::check_db() { // We need to check our manager if (access.log || access.notify) - mgr_uid = get_manager(to_user_id(eval_uid), &mgr_pkg); + mgr_uid = get_manager(to_user_id(eval_uid), &mgr_pkg, true); } bool uid_granted_root(int uid) { diff --git a/scripts/avd_magisk.sh b/scripts/avd_magisk.sh index fed93d761..454b9dae7 100755 --- a/scripts/avd_magisk.sh +++ b/scripts/avd_magisk.sh @@ -139,6 +139,8 @@ ln -s ./magisk $MAGISKTMP/resetprop ln -s ./magisk $MAGISKTMP/magiskhide ln -s ./magiskpolicy $MAGISKTMP/supolicy +./magiskinit -x manager $MAGISKTMP/stub.apk + mkdir -p $MAGISKTMP/.magisk/mirror mkdir $MAGISKTMP/.magisk/block touch $MAGISKTMP/.magisk/config