C++/Rust 2 way binding for MagiskD

This commit is contained in:
topjohnwu
2023-11-17 13:35:50 -08:00
parent 6c0966b795
commit 8d5b9e5329
11 changed files with 234 additions and 176 deletions
+52 -39
View File
@@ -128,8 +128,20 @@ static void poll_ctrl_handler(pollfd *pfd) {
}
}
const MagiskD &MagiskD::get() {
return *reinterpret_cast<const MagiskD*>(&rust::get_magiskd());
}
const rust::MagiskD &MagiskD::as_rust() const {
return *reinterpret_cast<const rust::MagiskD*>(this);
}
void MagiskD::boot_stage_handler(int client, int code) const {
as_rust().boot_stage_handler(client, code);
}
void MagiskD::reboot() const {
if (is_recovery())
if (as_rust().is_recovery())
exec_command_sync("/system/bin/reboot", "recovery");
else
exec_command_sync("/system/bin/reboot");
@@ -137,34 +149,33 @@ void MagiskD::reboot() const {
static void handle_request_async(int client, int code, const sock_cred &cred) {
switch (code) {
case MainRequest::DENYLIST:
case +RequestCode::DENYLIST:
denylist_handler(client, &cred);
break;
case MainRequest::SUPERUSER:
case +RequestCode::SUPERUSER:
su_daemon_handler(client, &cred);
break;
case MainRequest::ZYGOTE_RESTART:
case +RequestCode::ZYGOTE_RESTART:
LOGI("** zygote restarted\n");
pkg_xml_ino = 0;
prune_su_access();
reset_zygisk(false);
close(client);
break;
case MainRequest::SQLITE_CMD:
case +RequestCode::SQLITE_CMD:
exec_sql(client);
break;
case MainRequest::REMOVE_MODULES: {
case +RequestCode::REMOVE_MODULES: {
int do_reboot = read_int(client);
remove_modules();
write_int(client, 0);
close(client);
if (do_reboot) {
MagiskD daemon;
daemon.reboot();
MagiskD::get().reboot();
}
break;
}
case MainRequest::ZYGISK:
case +RequestCode::ZYGISK:
zygisk_handler(client, &cred);
break;
default:
@@ -174,20 +185,20 @@ static void handle_request_async(int client, int code, const sock_cred &cred) {
static void handle_request_sync(int client, int code) {
switch (code) {
case MainRequest::CHECK_VERSION:
case +RequestCode::CHECK_VERSION:
#if MAGISK_DEBUG
write_string(client, MAGISK_VERSION ":MAGISK:D");
#else
write_string(client, MAGISK_VERSION ":MAGISK:R");
#endif
break;
case MainRequest::CHECK_VERSION_CODE:
case +RequestCode::CHECK_VERSION_CODE:
write_int(client, MAGISK_VER_CODE);
break;
case MainRequest::START_DAEMON:
case +RequestCode::START_DAEMON:
rust::get_magiskd().setup_logfile();
break;
case MainRequest::STOP_DAEMON: {
case +RequestCode::STOP_DAEMON: {
// Unmount all overlays
denylist_handler(-1, nullptr);
@@ -236,42 +247,42 @@ static void handle_request(pollfd *pfd) {
if (!is_root && !is_zygote && !is_client(cred.pid)) {
// Unsupported client state
write_int(client, MainResponse::ACCESS_DENIED);
write_int(client, +RespondCode::ACCESS_DENIED);
return;
}
code = read_int(client);
if (code < 0 || code >= MainRequest::END ||
code == MainRequest::_SYNC_BARRIER_ ||
code == MainRequest::_STAGE_BARRIER_) {
if (code < 0 || code >= +RequestCode::END ||
code == +RequestCode::_SYNC_BARRIER_ ||
code == +RequestCode::_STAGE_BARRIER_) {
// Unknown request code
return;
}
// Check client permissions
switch (code) {
case MainRequest::POST_FS_DATA:
case MainRequest::LATE_START:
case MainRequest::BOOT_COMPLETE:
case MainRequest::ZYGOTE_RESTART:
case MainRequest::SQLITE_CMD:
case MainRequest::DENYLIST:
case MainRequest::STOP_DAEMON:
case +RequestCode::POST_FS_DATA:
case +RequestCode::LATE_START:
case +RequestCode::BOOT_COMPLETE:
case +RequestCode::ZYGOTE_RESTART:
case +RequestCode::SQLITE_CMD:
case +RequestCode::DENYLIST:
case +RequestCode::STOP_DAEMON:
if (!is_root) {
write_int(client, MainResponse::ROOT_REQUIRED);
write_int(client, +RespondCode::ROOT_REQUIRED);
return;
}
break;
case MainRequest::REMOVE_MODULES:
case +RequestCode::REMOVE_MODULES:
if (!is_root && cred.uid != AID_SHELL) {
write_int(client, MainResponse::ACCESS_DENIED);
write_int(client, +RespondCode::ACCESS_DENIED);
return;
}
break;
case MainRequest::ZYGISK:
case +RequestCode::ZYGISK:
if (!is_zygote) {
// Invalid client context
write_int(client, MainResponse::ACCESS_DENIED);
write_int(client, +RespondCode::ACCESS_DENIED);
return;
}
break;
@@ -279,14 +290,16 @@ static void handle_request(pollfd *pfd) {
break;
}
write_int(client, MainResponse::OK);
write_int(client, +RespondCode::OK);
if (code < MainRequest::_SYNC_BARRIER_) {
if (code < +RequestCode::_SYNC_BARRIER_) {
handle_request_sync(client, code);
} else if (code < MainRequest::_STAGE_BARRIER_) {
} else if (code < +RequestCode::_STAGE_BARRIER_) {
exec_task([=, fd = client.release()] { handle_request_async(fd, code, cred); });
} else {
exec_task([=, fd = client.release()] { boot_stage_handler(fd, code); });
exec_task([=, fd = client.release()] {
MagiskD::get().boot_stage_handler(fd, code);
});
}
}
@@ -460,20 +473,20 @@ int connect_daemon(int req, bool create) {
}
write_int(fd, req);
int res = read_int(fd);
if (res < MainResponse::ERROR || res >= MainResponse::END)
res = MainResponse::ERROR;
if (res < +RespondCode::ERROR || res >= +RespondCode::END)
res = +RespondCode::ERROR;
switch (res) {
case MainResponse::OK:
case +RespondCode::OK:
break;
case MainResponse::ERROR:
case +RespondCode::ERROR:
LOGE("Daemon error\n");
close(fd);
return -1;
case MainResponse::ROOT_REQUIRED:
case +RespondCode::ROOT_REQUIRED:
LOGE("Root is required for this operation\n");
close(fd);
return -1;
case MainResponse::ACCESS_DENIED:
case +RespondCode::ACCESS_DENIED:
LOGE("Access denied\n");
close(fd);
return -1;