Cleaner daemon handlers

This commit is contained in:
topjohnwu 2021-08-11 22:57:08 -07:00
parent 3ea10b7cf9
commit 20860da4b4
2 changed files with 55 additions and 41 deletions

View File

@ -39,15 +39,16 @@ static bool verify_client(pid_t pid) {
static bool check_zygote(pid_t pid) { static bool check_zygote(pid_t pid) {
char buf[32]; char buf[32];
sprintf(buf, "/proc/%d/attr/current", pid); sprintf(buf, "/proc/%d/attr/current", pid);
auto fp = open_file(buf, "r"); if (auto fp = open_file(buf, "r")) {
if (!fp) fscanf(fp.get(), "%s", buf);
return buf == "u:r:zygote:s0"sv;
} else {
return false; 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 handle_request_async(int client, int code, ucred cred) {
switch (req_code) { switch (code) {
case MAGISKHIDE: case MAGISKHIDE:
magiskhide_handler(client, &cred); magiskhide_handler(client, &cred);
break; break;
@ -78,26 +79,43 @@ static void request_handler(int client, int req_code, ucred cred) {
} }
} }
static void handle_request_sync(int client, int code) {
switch (code) {
case CHECK_VERSION:
write_string(client, MAGISK_VERSION ":MAGISK");
break;
case CHECK_VERSION_CODE:
write_int(client, MAGISK_VER_CODE);
break;
case GET_PATH:
write_string(client, MAGISKTMP.data());
break;
case START_DAEMON:
setup_logfile(true);
break;
}
}
static void handle_request(int client) { static void handle_request(int client) {
int req_code; int code;
// Verify client credentials // Verify client credentials
ucred cred; ucred cred;
get_client_cred(client, &cred); get_client_cred(client, &cred);
bool is_root = cred.uid == 0; bool is_root = cred.uid == 0;
bool is_zygote = check_zygote(cred.pid);
bool is_client = verify_client(cred.pid); bool is_client = verify_client(cred.pid);
bool is_zygote = !is_client && check_zygote(cred.pid);
if (!is_root && !is_zygote && !is_client) if (!is_root && !is_zygote && !is_client)
goto shortcut; goto done;
req_code = read_int(client); code = read_int(client);
if (req_code < 0 || req_code >= DAEMON_CODE_END) if (code < 0 || (code & DAEMON_CODE_MASK) >= DAEMON_CODE_END)
goto shortcut; goto done;
// Check client permissions // Check client permissions
switch (req_code) { switch (code) {
case POST_FS_DATA: case POST_FS_DATA:
case LATE_START: case LATE_START:
case BOOT_COMPLETE: case BOOT_COMPLETE:
@ -105,44 +123,33 @@ static void handle_request(int client) {
case GET_PATH: case GET_PATH:
if (!is_root) { if (!is_root) {
write_int(client, ROOT_REQUIRED); write_int(client, ROOT_REQUIRED);
goto shortcut; goto done;
} }
break; break;
case REMOVE_MODULES: case REMOVE_MODULES:
if (cred.uid != UID_SHELL && cred.uid != UID_ROOT) { if (!is_root && cred.uid != UID_SHELL) {
write_int(client, 1); write_int(client, 1);
goto shortcut; goto done;
} }
break; break;
case MAGISKHIDE: // accept hide request from zygote case MAGISKHIDE: // accept hide request from zygote
if (!is_root && !is_zygote) { if (!is_root && !is_zygote) {
write_int(client, ROOT_REQUIRED); write_int(client, ROOT_REQUIRED);
goto shortcut; goto done;
} }
break; break;
} }
// Simple requests if (code & SYNC_FLAG) {
switch (req_code) { handle_request_sync(client, code);
case CHECK_VERSION: goto done;
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 START_DAEMON:
setup_logfile(true);
goto shortcut;
} }
// Create new thread to handle complex requests // Create new thread to handle complex requests
new_daemon_thread([=] { return request_handler(client, req_code, cred); }); new_daemon_thread([=] { handle_request_async(client, code, cred); });
return; return;
shortcut: done:
close(client); close(client);
} }

View File

@ -2,27 +2,34 @@
#include <pthread.h> #include <pthread.h>
#include <string> #include <string>
#include <limits>
#include <socket.hpp> #include <socket.hpp>
// Daemon command code flags/masks
enum : int {
SYNC_FLAG = (1 << 30),
DAEMON_CODE_MASK = std::numeric_limits<int>::max() >> 1
};
// Daemon command codes // Daemon command codes
enum { enum : int {
START_DAEMON, START_DAEMON = SYNC_FLAG | 0,
SUPERUSER, CHECK_VERSION = SYNC_FLAG | 1,
CHECK_VERSION, CHECK_VERSION_CODE = SYNC_FLAG | 2,
CHECK_VERSION_CODE, GET_PATH = SYNC_FLAG | 3,
SUPERUSER = 4,
POST_FS_DATA, POST_FS_DATA,
LATE_START, LATE_START,
BOOT_COMPLETE, BOOT_COMPLETE,
MAGISKHIDE, MAGISKHIDE,
SQLITE_CMD, SQLITE_CMD,
REMOVE_MODULES, REMOVE_MODULES,
GET_PATH,
DAEMON_CODE_END, DAEMON_CODE_END,
}; };
// Return codes for daemon // Return codes for daemon
enum { enum : int {
DAEMON_ERROR = -1, DAEMON_ERROR = -1,
DAEMON_SUCCESS = 0, DAEMON_SUCCESS = 0,
ROOT_REQUIRED, ROOT_REQUIRED,
@ -30,7 +37,7 @@ enum {
}; };
// Daemon state // Daemon state
enum { enum : int {
STATE_NONE, STATE_NONE,
STATE_POST_FS_DATA, STATE_POST_FS_DATA,
STATE_POST_FS_DATA_DONE, STATE_POST_FS_DATA_DONE,