From 7c2e93d266583c5121317c766a3b9a3ab6cf9bc4 Mon Sep 17 00:00:00 2001 From: topjohnwu Date: Wed, 15 Nov 2023 13:58:51 -0800 Subject: [PATCH] Introduce owned_fd --- native/src/base/misc.hpp | 19 +++++++++++++++++-- native/src/core/daemon.cpp | 23 +++++++++-------------- 2 files changed, 26 insertions(+), 16 deletions(-) diff --git a/native/src/base/misc.hpp b/native/src/base/misc.hpp index 476395fe9..038dd1bd5 100644 --- a/native/src/base/misc.hpp +++ b/native/src/base/misc.hpp @@ -11,11 +11,10 @@ #include "xwrap.hpp" #define DISALLOW_COPY_AND_MOVE(clazz) \ -clazz(const clazz &) = delete; \ +clazz(const clazz&) = delete; \ clazz(clazz &&) = delete; #define ALLOW_MOVE_ONLY(clazz) \ -clazz() = default; \ clazz(const clazz&) = delete; \ clazz(clazz &&o) { swap(o); } \ clazz& operator=(clazz &&o) { swap(o); return *this; } @@ -211,6 +210,7 @@ class byte_channel; struct heap_data : public byte_data { ALLOW_MOVE_ONLY(heap_data) + heap_data() = default; explicit heap_data(size_t sz) : byte_data(calloc(sz, 1), sz) {} ~heap_data() { free(_buf); } @@ -218,6 +218,21 @@ struct heap_data : public byte_data { friend byte_channel; }; +struct owned_fd { + ALLOW_MOVE_ONLY(owned_fd) + + owned_fd() : fd(-1) {} + owned_fd(int fd) : fd(fd) {} + ~owned_fd() { close(fd); fd = -1; } + + operator int() { return fd; } + int release() { int f = fd; fd = -1; return f; } + void swap(owned_fd &owned) { std::swap(fd, owned.fd); } + +private: + int fd; +}; + rust::Vec mut_u8_patch( rust::Slice buf, rust::Slice from, diff --git a/native/src/core/daemon.cpp b/native/src/core/daemon.cpp index 3404e5deb..cab9b6431 100644 --- a/native/src/core/daemon.cpp +++ b/native/src/core/daemon.cpp @@ -211,7 +211,7 @@ static bool is_client(pid_t pid) { } static void handle_request(pollfd *pfd) { - int client = xaccept4(pfd->fd, nullptr, nullptr, SOCK_CLOEXEC); + owned_fd client = xaccept4(pfd->fd, nullptr, nullptr, SOCK_CLOEXEC); // Verify client credentials sock_cred cred; @@ -221,7 +221,7 @@ static void handle_request(pollfd *pfd) { if (!get_client_cred(client, &cred)) { // Client died - goto done; + return; } is_root = cred.uid == AID_ROOT; is_zygote = cred.context == "u:r:zygote:s0"; @@ -229,7 +229,7 @@ static void handle_request(pollfd *pfd) { if (!is_root && !is_zygote && !is_client(cred.pid)) { // Unsupported client state write_int(client, MainResponse::ACCESS_DENIED); - goto done; + return; } code = read_int(client); @@ -237,7 +237,7 @@ static void handle_request(pollfd *pfd) { code == MainRequest::_SYNC_BARRIER_ || code == MainRequest::_STAGE_BARRIER_) { // Unknown request code - goto done; + return; } // Check client permissions @@ -251,20 +251,20 @@ static void handle_request(pollfd *pfd) { case MainRequest::STOP_DAEMON: if (!is_root) { write_int(client, MainResponse::ROOT_REQUIRED); - goto done; + return; } break; case MainRequest::REMOVE_MODULES: if (!is_root && cred.uid != AID_SHELL) { write_int(client, MainResponse::ACCESS_DENIED); - goto done; + return; } break; case MainRequest::ZYGISK: if (!is_zygote) { // Invalid client context write_int(client, MainResponse::ACCESS_DENIED); - goto done; + return; } break; default: @@ -275,16 +275,11 @@ static void handle_request(pollfd *pfd) { if (code < MainRequest::_SYNC_BARRIER_) { handle_request_sync(client, code); - goto done; } else if (code < MainRequest::_STAGE_BARRIER_) { - exec_task([=] { handle_request_async(client, code, cred); }); + exec_task([=, fd = client.release()] { handle_request_async(fd, code, cred); }); } else { - exec_task([=] { boot_stage_handler(client, code); }); + exec_task([=, fd = client.release()] { boot_stage_handler(fd, code); }); } - return; - -done: - close(client); } static void switch_cgroup(const char *cgroup, int pid) {