diff --git a/native/jni/core/bootstages.cpp b/native/jni/core/bootstages.cpp index 67fb5e9d2..3f0ea7890 100644 --- a/native/jni/core/bootstages.cpp +++ b/native/jni/core/bootstages.cpp @@ -645,11 +645,23 @@ static void dump_logs() { if (test != 0) return; rename(LOGFILE, LOGFILE ".bak"); - int fd = xopen(LOGFILE, O_WRONLY | O_APPEND | O_CREAT | O_CLOEXEC, 0644); - exec_t exec { .fd = fd }; - exec_command(exec, "/system/bin/logcat", "-s", "Magisk"); log_dump = true; - close(fd); + // Start a daemon thread and wait indefinitely + new_daemon_thread([](auto) -> void* { + int fd = xopen(LOGFILE, O_WRONLY | O_APPEND | O_CREAT | O_CLOEXEC, 0644); + exec_t exec { + .fd = fd, + .fork = fork_no_zombie + }; + int pid = exec_command(exec, "/system/bin/logcat", "-s", "Magisk"); + close(fd); + if (pid < 0) { + log_dump = false; + return nullptr; + } + waitpid(pid, nullptr, 0); + return nullptr; + }); } /**************** diff --git a/native/jni/core/daemon.cpp b/native/jni/core/daemon.cpp index a54125e68..7144d701e 100644 --- a/native/jni/core/daemon.cpp +++ b/native/jni/core/daemon.cpp @@ -140,20 +140,17 @@ static void main_daemon() { pthread_sigmask(SIG_SETMASK, &block_set, nullptr); // Loop forever to listen for requests - while(true) { + for (;;) { int *client = new int; *client = xaccept4(fd, nullptr, nullptr, SOCK_CLOEXEC); - pthread_t thread; - xpthread_create(&thread, nullptr, request_handler, client); - // Detach the thread, we will never join it - pthread_detach(thread); + new_daemon_thread(request_handler, client); } } int switch_mnt_ns(int pid) { char mnt[32]; snprintf(mnt, sizeof(mnt), "/proc/%d/ns/mnt", pid); - if(access(mnt, R_OK) == -1) return 1; // Maybe process died.. + if (access(mnt, R_OK) == -1) return 1; // Maybe process died.. int fd, ret; fd = xopen(mnt, O_RDONLY); diff --git a/native/jni/magiskhide/hide_utils.cpp b/native/jni/magiskhide/hide_utils.cpp index 9b8a7a587..4082fc9ab 100644 --- a/native/jni/magiskhide/hide_utils.cpp +++ b/native/jni/magiskhide/hide_utils.cpp @@ -366,11 +366,9 @@ void auto_start_magiskhide() { db_settings dbs; get_db_settings(&dbs, HIDE_CONFIG); if (dbs[HIDE_CONFIG]) { - pthread_t thread; - xpthread_create(&thread, nullptr, [](void*) -> void* { + new_daemon_thread([](auto) -> void* { launch_magiskhide(-1); return nullptr; - }, nullptr); - pthread_detach(thread); + }); } } diff --git a/native/jni/utils/include/utils.h b/native/jni/utils/include/utils.h index 32d773e6e..11e56d36a 100644 --- a/native/jni/utils/include/utils.h +++ b/native/jni/utils/include/utils.h @@ -82,6 +82,7 @@ unsigned get_shell_uid(); unsigned get_system_uid(); unsigned get_radio_uid(); int fork_dont_care(); +int fork_no_zombie(); void gen_rand_str(char *buf, int len); int strend(const char *s1, const char *s2); @@ -147,6 +148,9 @@ std::vector file_to_vector(const char *filename); // misc.cpp +int new_daemon_thread(void *(*start_routine) (void *), void *arg = nullptr, + const pthread_attr_t *attr = nullptr); + struct exec_t { bool err = false; int fd = -2; diff --git a/native/jni/utils/misc.cpp b/native/jni/utils/misc.cpp index 3c3891655..95d41e56f 100644 --- a/native/jni/utils/misc.cpp +++ b/native/jni/utils/misc.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -50,6 +51,20 @@ int fork_dont_care() { return 0; } +int fork_no_zombie() { + int pid = xfork(); + if (pid) + return pid; + // Unblock all signals + sigset_t block_set; + sigfillset(&block_set); + pthread_sigmask(SIG_UNBLOCK, &block_set, nullptr); + prctl(PR_SET_PDEATHSIG, SIGTERM); + if (getppid() == 1) + exit(1); + return 0; +} + void gen_rand_str(char *buf, int len) { const char base[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; int urandom; @@ -201,3 +216,11 @@ int exec_command_sync(exec_t &exec) { return WEXITSTATUS(status); } +int new_daemon_thread(void *(*start_routine) (void *), void *arg, const pthread_attr_t *attr) { + pthread_t thread; + int ret = xpthread_create(&thread, attr, start_routine, arg); + if (ret == 0) + pthread_detach(thread); + return ret; +} +