diff --git a/jni/daemon/log_monitor.c b/jni/daemon/log_monitor.c index 1580e3fd1..05ad0fd22 100644 --- a/jni/daemon/log_monitor.c +++ b/jni/daemon/log_monitor.c @@ -20,8 +20,10 @@ static void *logger_thread(void *args) { // Disable buffering setbuf(logfile, NULL); // Start logcat - FILE *log_monitor = popen("logcat -s Magisk -v time", "r"); - while (fgets(buffer, sizeof(buffer), log_monitor)) { + char *const command[] = { "logcat", "-s", "Magisk", "-v", "time", NULL }; + int fd; + run_command(&fd, "/system/bin/logcat", command); + while (fdgets(buffer, sizeof(buffer), fd)) { fprintf(logfile, "%s", buffer); } return NULL; diff --git a/jni/daemon/post_fs_data.c b/jni/daemon/post_fs_data.c index 2d307f6e9..5f24c7dfc 100644 --- a/jni/daemon/post_fs_data.c +++ b/jni/daemon/post_fs_data.c @@ -37,7 +37,7 @@ static char *loopsetup(const char *img) { char *mount_image(const char *img, const char *target) { char *device = loopsetup(img); if (device) - mount(device, target, "ext4", 0, NULL); + xmount(device, target, "ext4", 0, NULL); return device; } diff --git a/jni/magiskhide/magiskhide.c b/jni/magiskhide/magiskhide.c index dc179ca96..27d287893 100644 --- a/jni/magiskhide/magiskhide.c +++ b/jni/magiskhide/magiskhide.c @@ -41,10 +41,8 @@ static void usage(char *arg0) { } void launch_magiskhide(int client) { - if (isEnabled) { - write_int(client, 0); - return; - } + if (isEnabled) + goto success; /* * The setns system call do not support multithread processes * We have to fork a new process, and communicate with pipe @@ -84,6 +82,7 @@ void launch_magiskhide(int client) { goto error; isEnabled = 1; +success: write_int(client, 0); close(client); return; @@ -107,12 +106,6 @@ void stop_magiskhide(int client) { LOGI("* Stopping MagiskHide\n"); - int kill = -1; - // Terminate hide daemon - write(sv[0], &kill, sizeof(kill)); - close(sv[0]); - waitpid(hide_pid, NULL, 0); - // Stop process monitor pthread_kill(proc_monitor_thread, SIGUSR1); pthread_join(proc_monitor_thread, NULL); diff --git a/jni/magiskhide/proc_monitor.c b/jni/magiskhide/proc_monitor.c index 1a1c1f25b..a857b2564 100644 --- a/jni/magiskhide/proc_monitor.c +++ b/jni/magiskhide/proc_monitor.c @@ -19,6 +19,7 @@ static int zygote_num = 0; static char init_ns[32], zygote_ns[2][32]; +static int log_pid = 0, log_fd; static void read_namespace(const int pid, char* target, const size_t size) { char path[32]; @@ -41,11 +42,24 @@ static void quit_pthread(int sig) { } hide_list = new_list = NULL; isEnabled = 0; + // Kill the logging if possible + if (log_pid) { + kill(log_pid, SIGTERM); + waitpid(log_pid, NULL, 0); + close(log_fd); + log_pid = 0; + } + int kill = -1; + // If process monitor dies, kill hide daemon too + write(sv[0], &kill, sizeof(kill)); + close(sv[0]); + waitpid(hide_pid, NULL, 0); LOGD("proc_monitor: terminating...\n"); pthread_exit(NULL); } static void store_zygote_ns(int pid) { + if (zygote_num == 2) return; do { usleep(500); read_namespace(pid, zygote_ns[zygote_num], 32); @@ -55,11 +69,6 @@ static void store_zygote_ns(int pid) { static void proc_monitor_err() { LOGD("proc_monitor: error occured, stopping magiskhide services\n"); - int kill = -1; - // If process monitor dies, kill hide daemon too - write(sv[0], &kill, sizeof(kill)); - close(sv[0]); - waitpid(hide_pid, NULL, 0); quit_pthread(SIGUSR1); } @@ -92,10 +101,12 @@ void *proc_monitor(void *args) { break; } - // Monitor am_proc_start (the command shall never end) - FILE *p = popen("while true; do logcat -b events -c; logcat -b events -v raw -s am_proc_start; sleep 1; done", "r"); + // Monitor am_proc_start + system("logcat -b events -c"); + char *const command[] = { "logcat", "-b", "events", "-v", "raw", "-s", "am_proc_start", NULL }; + log_pid = run_command(&log_fd, "/system/bin/logcat", command); - while(fgets(buffer, sizeof(buffer), p)) { + while(fdgets(buffer, sizeof(buffer), log_fd)) { int ret, comma = 0; char *pos = buffer, *line, processName[256]; struct vector *temp = NULL; @@ -167,7 +178,6 @@ void *proc_monitor(void *args) { } // Should never be here - pclose(p); - pthread_exit(NULL); + quit_pthread(SIGUSR1); return NULL; } diff --git a/jni/utils/misc.c b/jni/utils/misc.c index 479486a41..31aeee958 100644 --- a/jni/utils/misc.c +++ b/jni/utils/misc.c @@ -81,19 +81,16 @@ int isNum(const char *s) { } /* Read a whole line from file descriptor */ -ssize_t fdreadline(int fd, char *buf, size_t size) { +ssize_t fdgets(char *buf, const size_t size, int fd) { ssize_t read = 0; buf[0] = '\0'; - while (xread(fd, buf + read, 1)) { - if (buf[read] == '\n') + while (xread(fd, buf + read, 1) && read < size - 1) { + if (buf[read] == '\0' || buf[read++] == '\n') { buf[read] = '\0'; - if (buf[read++] == '\0') - break; - if (read == size) { - buf[read - 1] = '\0'; break; } } + buf[size - 1] = '\0'; return read; } @@ -121,11 +118,11 @@ static void proc_name_filter(int pid) { char buf[64]; snprintf(buf, sizeof(buf), "/proc/%d/cmdline", pid); int fd = xopen(buf, O_RDONLY); - if (fdreadline(fd, buf, sizeof(buf)) == 0) { + if (fdgets(buf, sizeof(buf), fd) == 0) { snprintf(buf, sizeof(buf), "/proc/%d/comm", pid); close(fd); fd = xopen(buf, O_RDONLY); - fdreadline(fd, buf, sizeof(buf)); + fdgets(buf, sizeof(buf), fd); } if (strstr(buf, ps_filter_pattern)) { // printf("%d: %s\n", pid, buf); @@ -189,14 +186,31 @@ void unblock_boot_process() { void setup_sighandlers(void (*handler)(int)) { struct sigaction act; - - // Install the termination handlers - // Note: we're assuming that none of these signal handlers are already trapped. - // If they are, we'll need to modify this code to save the previous handler and - // call it after we restore stdin to its previous state. memset(&act, 0, sizeof(act)); act.sa_handler = handler; for (int i = 0; quit_signals[i]; ++i) { sigaction(quit_signals[i], &act, NULL); } } + +int run_command(int *fd, const char *path, char *const argv[]) { + int sv[2]; + if (socketpair(AF_LOCAL, SOCK_STREAM, 0, sv) == -1) + return -1; + // We use sv[0], give them sv[1] for communication + *fd = sv[1]; + + int pid = fork(); + if (pid != 0) { + close(sv[0]); + return pid; + } + + close(sv[1]); + dup2(sv[0], STDIN_FILENO); + dup2(sv[0], STDOUT_FILENO); + dup2(sv[0], STDERR_FILENO); + execv(path, argv); + PLOGE("execv"); + return -1; +} diff --git a/jni/utils/utils.h b/jni/utils/utils.h index 889972a71..37f12fcf8 100644 --- a/jni/utils/utils.h +++ b/jni/utils/utils.h @@ -65,12 +65,13 @@ unsigned get_radio_uid(); int check_data(); void file_to_vector(struct vector *v, FILE *fp); int isNum(const char *s); -ssize_t fdreadline(int fd, char *buf, size_t size); +ssize_t fdgets(char *buf, size_t size, int fd); void ps(void (*func)(int)); void ps_filter_proc_name(const char *filter, void (*func)(int)); int create_links(const char *bin, const char *path); void unlock_blocks(); void unblock_boot_process(); void setup_sighandlers(void (*handler)(int)); +int run_command(int *fd, const char *path, char *const argv[]); #endif