Commit 501d3e6c authored by topjohnwu's avatar topjohnwu

Maintain global daemon status

parent b27b9c1d
...@@ -20,94 +20,113 @@ using namespace std; ...@@ -20,94 +20,113 @@ using namespace std;
int SDK_INT = -1; int SDK_INT = -1;
bool RECOVERY_MODE = false; bool RECOVERY_MODE = false;
string MAGISKTMP; string MAGISKTMP;
int daemon_state = STATE_UNKNOWN;
static struct stat self_st; 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 // Verify caller is the same as server
char path[32]; char path[32];
sprintf(path, "/proc/%d/exe", pid); sprintf(path, "/proc/%d/exe", pid);
struct stat st; struct stat st;
if (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 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, &cred);
break;
case POST_FS_DATA:
post_fs_data(client);
break;
case LATE_START:
late_start(client);
break;
case BOOT_COMPLETE:
boot_complete(client);
break;
case SQLITE_CMD:
exec_sql(client);
break;
case REMOVE_MODULES:
foreach_modules("remove");
write_int(client, 0);
close(client); close(client);
pthread_exit(nullptr); reboot();
break;
default:
close(client);
break;
} }
} }
static void *request_handler(void *args) { static void handle_request(int client) {
int client = reinterpret_cast<intptr_t>(args); int req_code;
struct ucred credential; // Verify client credentials
get_client_cred(client, &credential); ucred cred;
if (credential.uid != 0) get_client_cred(client, &cred);
verify_client(client, credential.pid); if (cred.uid != 0 && !verify_client(client, cred.pid))
goto shortcut;
int req = read_int(client); // Check client permissions
switch (req) { req_code = read_int(client);
switch (req_code) {
case MAGISKHIDE: 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 (credential.uid != 0) { if (cred.uid != 0) {
write_int(client, ROOT_REQUIRED); write_int(client, ROOT_REQUIRED);
close(client); goto shortcut;
return nullptr;
} }
break; break;
case REMOVE_MODULES: case REMOVE_MODULES:
if (credential.uid != UID_SHELL && credential.uid != UID_ROOT) { if (cred.uid != UID_SHELL && cred.uid != UID_ROOT) {
write_int(client, 1); write_int(client, 1);
close(client); goto shortcut;
return nullptr;
} }
break; break;
default:
break;
} }
switch (req) { switch (req_code) {
case MAGISKHIDE: // In case of init trigger launches, set the corresponding states
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);
break;
case POST_FS_DATA: case POST_FS_DATA:
post_fs_data(client); daemon_state = STATE_POST_FS_DATA;
break; break;
case LATE_START: case LATE_START:
late_start(client); daemon_state = STATE_LATE_START;
break; break;
case BOOT_COMPLETE: case BOOT_COMPLETE:
boot_complete(client); daemon_state = STATE_BOOT_COMPLETE;
break;
case SQLITE_CMD:
exec_sql(client);
break;
case REMOVE_MODULES:
foreach_modules("remove");
write_int(client, 0);
close(client);
reboot();
break; 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: case GET_PATH:
write_string(client, MAGISKTMP.data()); write_string(client, MAGISKTMP.data());
close(client); goto shortcut;
break; case DO_NOTHING:
default: goto shortcut;
close(client);
break;
} }
return nullptr;
// 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() { static void android_logging() {
...@@ -207,7 +226,7 @@ static void daemon_entry(int ppid) { ...@@ -207,7 +226,7 @@ static void daemon_entry(int ppid) {
// Loop forever to listen for requests // Loop forever to listen for requests
for (;;) { for (;;) {
int client = xaccept4(fd, nullptr, nullptr, SOCK_CLOEXEC); int client = xaccept4(fd, nullptr, nullptr, SOCK_CLOEXEC);
new_daemon_thread(request_handler, reinterpret_cast<void*>(client)); handle_request(client);
} }
} }
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
#include <socket.hpp> #include <socket.hpp>
// Commands require connecting to daemon // Daemon command codes
enum { enum {
DO_NOTHING = 0, DO_NOTHING = 0,
SUPERUSER, SUPERUSER,
...@@ -29,8 +29,17 @@ enum { ...@@ -29,8 +29,17 @@ enum {
DAEMON_LAST DAEMON_LAST
}; };
// Daemon state
enum {
STATE_POST_FS_DATA,
STATE_LATE_START,
STATE_BOOT_COMPLETE,
STATE_UNKNOWN
};
extern int SDK_INT; extern int SDK_INT;
extern bool RECOVERY_MODE; extern bool RECOVERY_MODE;
extern int daemon_state;
extern bool pfs_done; extern bool pfs_done;
extern std::vector<std::string> module_list; extern std::vector<std::string> module_list;
#define APP_DATA_DIR (SDK_INT >= 24 ? "/data/user_de" : "/data/user") #define APP_DATA_DIR (SDK_INT >= 24 ? "/data/user_de" : "/data/user")
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment