Maintain global daemon status

This commit is contained in:
topjohnwu 2020-05-18 05:18:49 -07:00
parent b27b9c1d18
commit 501d3e6c32
2 changed files with 83 additions and 55 deletions

View File

@ -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<intptr_t>(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<void*>(client));
handle_request(client);
}
}

View File

@ -6,7 +6,7 @@
#include <socket.hpp>
// 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<std::string> module_list;
#define APP_DATA_DIR (SDK_INT >= 24 ? "/data/user_de" : "/data/user")