Minor reorganization of daemons

This commit is contained in:
topjohnwu 2018-10-12 00:50:47 -04:00
parent 619d48c97a
commit acf7c0c665
7 changed files with 117 additions and 131 deletions

View File

@ -492,7 +492,7 @@ static void *start_magisk_hide(void *args) {
} }
static void auto_start_magiskhide() { static void auto_start_magiskhide() {
if (!check_and_start_logger()) if (!start_log_daemon())
return; return;
char *hide_prop = getprop2(MAGISKHIDE_PROP, 1); char *hide_prop = getprop2(MAGISKHIDE_PROP, 1);
if (hide_prop == NULL || strcmp(hide_prop, "0") != 0) { if (hide_prop == NULL || strcmp(hide_prop, "0") != 0) {
@ -728,6 +728,9 @@ void post_fs_data(int client) {
xmount(NULL, "/", NULL, MS_REMOUNT | MS_RDONLY, NULL); xmount(NULL, "/", NULL, MS_REMOUNT | MS_RDONLY, NULL);
// Start log_daemon
start_log_daemon();
LOGI("** post-fs-data mode running\n"); LOGI("** post-fs-data mode running\n");
// Allocate buffer // Allocate buffer

View File

@ -96,7 +96,7 @@ static void *request_handler(void *args) {
return NULL; return NULL;
} }
void main_daemon() { static void main_daemon() {
android_logging(); android_logging();
#ifndef MAGISK_DEBUG #ifndef MAGISK_DEBUG
log_cb.d = nop_log; log_cb.d = nop_log;
@ -111,11 +111,8 @@ void main_daemon() {
xdup2(fd, STDIN_FILENO); xdup2(fd, STDIN_FILENO);
close(fd); close(fd);
// Start the log monitor
check_and_start_logger();
struct sockaddr_un sun; struct sockaddr_un sun;
socklen_t len = setup_sockaddr(&sun, MAIN_DAEMON); socklen_t len = setup_sockaddr(&sun, MAIN_SOCKET);
fd = xsocket(AF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0); fd = xsocket(AF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0);
if (xbind(fd, (struct sockaddr*) &sun, len)) if (xbind(fd, (struct sockaddr*) &sun, len))
exit(1); exit(1);
@ -149,39 +146,24 @@ void main_daemon() {
} }
} }
/* Connect the daemon, set sockfd, and return if new daemon is spawned */ int connect_daemon() {
int connect_daemon2(daemon_t d, int *sockfd) {
struct sockaddr_un sun; struct sockaddr_un sun;
socklen_t len = setup_sockaddr(&sun, d); socklen_t len = setup_sockaddr(&sun, MAIN_SOCKET);
*sockfd = xsocket(AF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0); int fd = xsocket(AF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0);
if (connect(*sockfd, (struct sockaddr*) &sun, len)) { if (connect(fd, (struct sockaddr*) &sun, len)) {
if (getuid() != UID_ROOT || getgid() != UID_ROOT) { if (getuid() != UID_ROOT || getgid() != UID_ROOT) {
fprintf(stderr, "No daemon is currently running!\n"); fprintf(stderr, "No daemon is currently running!\n");
exit(1); exit(1);
} }
LOGD("client: launching new main daemon process\n");
if (fork_dont_care() == 0) { if (fork_dont_care() == 0) {
LOGD("client: connect fail, try launching new daemon process\n"); close(fd);
close(*sockfd); main_daemon();
switch (d) {
case MAIN_DAEMON:
main_daemon();
break;
case LOG_DAEMON:
log_daemon();
break;
}
} }
while (connect(*sockfd, (struct sockaddr*) &sun, len)) while (connect(fd, (struct sockaddr*) &sun, len))
usleep(10000); usleep(10000);
return 1;
} }
return 0;
}
int connect_daemon() {
int fd;
connect_daemon2(MAIN_DAEMON, &fd);
return fd; return fd;
} }

View File

@ -18,7 +18,7 @@
#include "daemon.h" #include "daemon.h"
#include "flags.h" #include "flags.h"
static int loggable = 0; int log_daemon_started = 0;
static struct vector log_cmd, clear_cmd; static struct vector log_cmd, clear_cmd;
static int sockfd; static int sockfd;
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
@ -109,24 +109,10 @@ static void *logcat_thread(void *args) {
} }
} }
int check_and_start_logger() { static void log_daemon() {
if (!loggable) {
int fd;
loggable = exec_command_sync("/system/bin/logcat", "-d", "-f", "/dev/null", NULL) == 0;
chmod("/dev/null", 0666);
if (loggable) {
connect_daemon2(LOG_DAEMON, &fd);
write_int(fd, HANDSHAKE);
close(fd);
}
}
return loggable;
}
void log_daemon() {
setsid(); setsid();
struct sockaddr_un sun; struct sockaddr_un sun;
socklen_t len = setup_sockaddr(&sun, LOG_DAEMON); socklen_t len = setup_sockaddr(&sun, LOG_SOCKET);
sockfd = xsocket(AF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0); sockfd = xsocket(AF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0);
if (xbind(sockfd, (struct sockaddr*) &sun, len)) if (xbind(sockfd, (struct sockaddr*) &sun, len))
exit(1); exit(1);
@ -179,10 +165,36 @@ void log_daemon() {
events[HIDE_EVENT].fd = fd; events[HIDE_EVENT].fd = fd;
pthread_mutex_unlock(&lock); pthread_mutex_unlock(&lock);
break; break;
case HANDSHAKE:
default: default:
close(fd); close(fd);
break; break;
} }
} }
} }
int start_log_daemon() {
if (!log_daemon_started) {
if (exec_command_sync("/system/bin/logcat", "-d", "-f", "/dev/null", NULL) == 0) {
if (fork_dont_care() == 0)
log_daemon();
// Wait till we can connect to log_daemon
int fd = connect_log_daemon();
write_int(fd, HANDSHAKE);
close(fd);
log_daemon_started = 1;
}
chmod("/dev/null", 0666);
}
return log_daemon_started;
}
int connect_log_daemon() {
if (!log_daemon_started)
return -1;
struct sockaddr_un sun;
socklen_t len = setup_sockaddr(&sun, LOG_SOCKET);
int fd = xsocket(AF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0);
while (connect(fd, (struct sockaddr*) &sun, len))
usleep(10000);
return fd;
}

View File

@ -13,18 +13,9 @@
#define ABS_SOCKET_LEN(sun) (sizeof(sun->sun_family) + strlen(sun->sun_path + 1) + 1) #define ABS_SOCKET_LEN(sun) (sizeof(sun->sun_family) + strlen(sun->sun_path + 1) + 1)
socklen_t setup_sockaddr(struct sockaddr_un *sun, daemon_t d) { socklen_t setup_sockaddr(struct sockaddr_un *sun, const char *name) {
memset(sun, 0, sizeof(*sun)); memset(sun, 0, sizeof(*sun));
sun->sun_family = AF_LOCAL; sun->sun_family = AF_LOCAL;
const char *name;
switch (d) {
case MAIN_DAEMON:
name = MAIN_SOCKET;
break;
case LOG_DAEMON:
name = LOG_SOCKET;
break;
}
strcpy(sun->sun_path + 1, name); strcpy(sun->sun_path + 1, name);
return ABS_SOCKET_LEN(sun); return ABS_SOCKET_LEN(sun);
} }

View File

@ -48,18 +48,17 @@ typedef enum {
// daemon.c // daemon.c
void main_daemon();
int connect_daemon(); int connect_daemon();
int connect_daemon2(daemon_t d, int *sockfd);
// log_monitor.c // log_monitor.c
void log_daemon(); extern int log_daemon_started;
int check_and_start_logger(); int connect_log_daemon();
int start_log_daemon();
// socket.c // socket.c
socklen_t setup_sockaddr(struct sockaddr_un *sun, daemon_t d); socklen_t setup_sockaddr(struct sockaddr_un *sun, const char *name);
int create_rand_socket(struct sockaddr_un *sun); int create_rand_socket(struct sockaddr_un *sun);
int socket_accept(int sockfd, int timeout); int socket_accept(int sockfd, int timeout);
int recv_fd(int sockfd); int recv_fd(int sockfd);

View File

@ -45,7 +45,7 @@ void launch_magiskhide(int client) {
return; return;
} }
if (!check_and_start_logger()) { if (!log_daemon_started) {
if (client > 0) { if (client > 0) {
write_int(client, LOGCAT_DISABLED); write_int(client, LOGCAT_DISABLED);
close(client); close(client);

View File

@ -125,83 +125,82 @@ void proc_monitor() {
term_thread(TERM_THREAD); term_thread(TERM_THREAD);
} }
while(1) { // Connect to the log daemon
// Connect to the log daemon sockfd = connect_log_daemon();
connect_daemon2(LOG_DAEMON, &sockfd); if (sockfd < 0)
write_int(sockfd, HIDE_CONNECT); return;
write_int(sockfd, HIDE_CONNECT);
FILE *log_in = fdopen(sockfd, "r"); FILE *log_in = fdopen(sockfd, "r");
char buf[4096]; char buf[4096];
while (fgets(buf, sizeof(buf), log_in)) { while (fgets(buf, sizeof(buf), log_in)) {
char *ss = strchr(buf, '['); char *ss = strchr(buf, '[');
int pid, ppid, num = 0; int pid, ppid, num = 0;
char *pos = ss, proc[256]; char *pos = ss, proc[256];
struct stat ns, pns; struct stat ns, pns;
while(1) { while(1) {
pos = strchr(pos, ','); pos = strchr(pos, ',');
if(pos == NULL) if(pos == NULL)
break; break;
pos[0] = ' '; pos[0] = ' ';
++num; ++num;
}
if(sscanf(ss, num == 6 ? "[%*d %d %*d %*d %256s" : "[%*d %d %*d %256s", &pid, proc) != 2)
continue;
// Make sure our target is alive
if (kill(pid, 0))
continue;
// Allow hiding sub-services of applications
char *colon = strchr(proc, ':');
if (colon)
*colon = '\0';
int hide = 0;
pthread_mutex_lock(&hide_lock);
char *line;
vec_for_each(hide_list, line) {
if (strcmp(proc, line) == 0) {
hide = 1;
break;
} }
}
pthread_mutex_unlock(&hide_lock);
if (!hide)
continue;
if(sscanf(ss, num == 6 ? "[%*d %d %*d %*d %256s" : "[%*d %d %*d %256s", &pid, proc) != 2) ppid = parse_ppid(pid);
continue; read_ns(ppid, &pns);
do {
read_ns(pid, &ns);
if (ns.st_dev == pns.st_dev && ns.st_ino == pns.st_ino)
usleep(50);
else
break;
} while (1);
// Make sure our target is alive // Send pause signal ASAP
if (kill(pid, 0)) if (kill(pid, SIGSTOP) == -1)
continue; continue;
// Allow hiding sub-services of applications // Restore the colon so we can log the actual process name
char *colon = strchr(proc, ':'); if (colon)
if (colon) *colon = ':';
*colon = '\0';
int hide = 0;
pthread_mutex_lock(&hide_lock);
char *line;
vec_for_each(hide_list, line) {
if (strcmp(proc, line) == 0) {
hide = 1;
break;
}
}
pthread_mutex_unlock(&hide_lock);
if (!hide)
continue;
ppid = parse_ppid(pid);
read_ns(ppid, &pns);
do {
read_ns(pid, &ns);
if (ns.st_dev == pns.st_dev && ns.st_ino == pns.st_ino)
usleep(50);
else
break;
} while (1);
// Send pause signal ASAP
if (kill(pid, SIGSTOP) == -1)
continue;
// Restore the colon so we can log the actual process name
if (colon)
*colon = ':';
#ifdef MAGISK_DEBUG #ifdef MAGISK_DEBUG
LOGI("proc_monitor: %s (PID=[%d] ns=%llu)(PPID=[%d] ns=%llu)\n", LOGI("proc_monitor: %s (PID=[%d] ns=%llu)(PPID=[%d] ns=%llu)\n",
proc, pid, ns.st_ino, ppid, pns.st_ino); proc, pid, ns.st_ino, ppid, pns.st_ino);
#else #else
LOGI("proc_monitor: %s\n", proc); LOGI("proc_monitor: %s\n", proc);
#endif #endif
/* /*
* The setns system call do not support multithread processes * The setns system call do not support multithread processes
* We have to fork a new process, setns, then do the unmounts * We have to fork a new process, setns, then do the unmounts
*/ */
if (fork_dont_care() == 0) if (fork_dont_care() == 0)
hide_daemon(pid); hide_daemon(pid);
}
// The other end EOF, restart the connection
} }
} }