From 501d3e6c32c3ce9f78b6c741ce420d4388348fdd Mon Sep 17 00:00:00 2001 From: topjohnwu Date: Mon, 18 May 2020 05:18:49 -0700 Subject: [PATCH] Maintain global daemon status --- native/jni/core/daemon.cpp | 127 +++++++++++++++++++--------------- native/jni/include/daemon.hpp | 11 ++- 2 files changed, 83 insertions(+), 55 deletions(-) diff --git a/native/jni/core/daemon.cpp b/native/jni/core/daemon.cpp index 7818bf76a..b6eb48c06 100644 --- a/native/jni/core/daemon.cpp +++ b/native/jni/core/daemon.cpp @@ -20,66 +20,25 @@ using namespace std; int SDK_INT = -1; bool RECOVERY_MODE = false; string MAGISKTMP; +int daemon_state = STATE_UNKNOWN; + static struct stat self_st; -static void verify_client(int client, pid_t pid) { +static bool verify_client(int client, pid_t pid) { // Verify caller is the same as server char path[32]; sprintf(path, "/proc/%d/exe", pid); struct stat st; - if (stat(path, &st) || st.st_dev != self_st.st_dev || st.st_ino != self_st.st_ino) { - close(client); - pthread_exit(nullptr); - } + return !(stat(path, &st) || st.st_dev != self_st.st_dev || st.st_ino != self_st.st_ino); } -static void *request_handler(void *args) { - int client = reinterpret_cast(args); - - struct ucred credential; - get_client_cred(client, &credential); - if (credential.uid != 0) - verify_client(client, credential.pid); - - int req = read_int(client); - switch (req) { - case MAGISKHIDE: - case POST_FS_DATA: - case LATE_START: - case BOOT_COMPLETE: - case SQLITE_CMD: - case GET_PATH: - if (credential.uid != 0) { - write_int(client, ROOT_REQUIRED); - close(client); - return nullptr; - } - break; - case REMOVE_MODULES: - if (credential.uid != UID_SHELL && credential.uid != UID_ROOT) { - write_int(client, 1); - close(client); - return nullptr; - } - break; - default: - break; - } - - switch (req) { +static void request_handler(int client, int req_code, ucred cred) { + switch (req_code) { case MAGISKHIDE: magiskhide_handler(client); break; case SUPERUSER: - su_daemon_handler(client, &credential); - break; - case CHECK_VERSION: - write_string(client, MAGISK_VERSION ":MAGISK"); - close(client); - break; - case CHECK_VERSION_CODE: - write_int(client, MAGISK_VER_CODE); - close(client); + su_daemon_handler(client, &cred); break; case POST_FS_DATA: post_fs_data(client); @@ -99,15 +58,75 @@ static void *request_handler(void *args) { close(client); reboot(); break; - case GET_PATH: - write_string(client, MAGISKTMP.data()); - close(client); - break; default: close(client); break; } - return nullptr; +} + +static void handle_request(int client) { + int req_code; + + // Verify client credentials + ucred cred; + get_client_cred(client, &cred); + if (cred.uid != 0 && !verify_client(client, cred.pid)) + goto shortcut; + + // Check client permissions + req_code = read_int(client); + switch (req_code) { + case MAGISKHIDE: + case POST_FS_DATA: + case LATE_START: + case BOOT_COMPLETE: + case SQLITE_CMD: + case GET_PATH: + if (cred.uid != 0) { + write_int(client, ROOT_REQUIRED); + goto shortcut; + } + break; + case REMOVE_MODULES: + if (cred.uid != UID_SHELL && cred.uid != UID_ROOT) { + write_int(client, 1); + goto shortcut; + } + break; + } + + switch (req_code) { + // In case of init trigger launches, set the corresponding states + case POST_FS_DATA: + daemon_state = STATE_POST_FS_DATA; + break; + case LATE_START: + daemon_state = STATE_LATE_START; + break; + case BOOT_COMPLETE: + daemon_state = STATE_BOOT_COMPLETE; + break; + + // Simple requests to query daemon info + case CHECK_VERSION: + write_string(client, MAGISK_VERSION ":MAGISK"); + goto shortcut; + case CHECK_VERSION_CODE: + write_int(client, MAGISK_VER_CODE); + goto shortcut; + case GET_PATH: + write_string(client, MAGISKTMP.data()); + goto shortcut; + case DO_NOTHING: + goto shortcut; + } + + // Create new thread to handle complex requests + new_daemon_thread(std::bind(&request_handler, client, req_code, cred)); + return; + +shortcut: + close(client); } static void android_logging() { @@ -207,7 +226,7 @@ static void daemon_entry(int ppid) { // Loop forever to listen for requests for (;;) { int client = xaccept4(fd, nullptr, nullptr, SOCK_CLOEXEC); - new_daemon_thread(request_handler, reinterpret_cast(client)); + handle_request(client); } } diff --git a/native/jni/include/daemon.hpp b/native/jni/include/daemon.hpp index f187cc376..6c29f8629 100644 --- a/native/jni/include/daemon.hpp +++ b/native/jni/include/daemon.hpp @@ -6,7 +6,7 @@ #include -// Commands require connecting to daemon +// Daemon command codes enum { DO_NOTHING = 0, SUPERUSER, @@ -29,8 +29,17 @@ enum { DAEMON_LAST }; +// Daemon state +enum { + STATE_POST_FS_DATA, + STATE_LATE_START, + STATE_BOOT_COMPLETE, + STATE_UNKNOWN +}; + extern int SDK_INT; extern bool RECOVERY_MODE; +extern int daemon_state; extern bool pfs_done; extern std::vector module_list; #define APP_DATA_DIR (SDK_INT >= 24 ? "/data/user_de" : "/data/user")