Separate logging into its own daemon
This commit is contained in:
parent
7243b9e72f
commit
a8030c39b1
@ -84,6 +84,7 @@ static void *request_handler(void *args) {
|
||||
late_start(client);
|
||||
break;
|
||||
default:
|
||||
close(client);
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
@ -105,14 +106,16 @@ void auto_start_magiskhide() {
|
||||
free(hide_prop);
|
||||
}
|
||||
|
||||
void start_daemon() {
|
||||
void main_daemon() {
|
||||
setsid();
|
||||
setcon("u:r:"SEPOL_PROC_DOMAIN":s0");
|
||||
int fd = xopen("/dev/null", O_RDWR | O_CLOEXEC);
|
||||
xdup2(fd, STDIN_FILENO);
|
||||
xdup2(fd, STDOUT_FILENO);
|
||||
xdup2(fd, STDERR_FILENO);
|
||||
close(fd);
|
||||
fd = xopen("/dev/zero", O_RDWR | O_CLOEXEC);
|
||||
xdup2(fd, STDIN_FILENO);
|
||||
close(fd);
|
||||
|
||||
// Block user signals
|
||||
sigset_t block_set;
|
||||
@ -121,16 +124,15 @@ void start_daemon() {
|
||||
sigaddset(&block_set, SIGUSR2);
|
||||
pthread_sigmask(SIG_SETMASK, &block_set, NULL);
|
||||
|
||||
// Start the log monitor
|
||||
monitor_logs();
|
||||
|
||||
struct sockaddr_un sun;
|
||||
fd = setup_socket(&sun);
|
||||
fd = setup_socket(&sun, MAIN_DAEMON);
|
||||
|
||||
if (xbind(fd, (struct sockaddr*) &sun, sizeof(sun)))
|
||||
exit(1);
|
||||
xlisten(fd, 10);
|
||||
|
||||
// Start the log monitor
|
||||
monitor_logs();
|
||||
|
||||
LOGI("Magisk v" xstr(MAGISK_VERSION) "(" xstr(MAGISK_VER_CODE) ") daemon started\n");
|
||||
|
||||
// Change process name
|
||||
@ -147,13 +149,11 @@ void start_daemon() {
|
||||
}
|
||||
}
|
||||
|
||||
/* Connect the daemon, and return a socketfd */
|
||||
int connect_daemon() {
|
||||
/* Connect the daemon, set sockfd, and return if new daemon is spawned */
|
||||
int connect_daemon2(daemon_t d, int *sockfd) {
|
||||
struct sockaddr_un sun;
|
||||
int fd = setup_socket(&sun);
|
||||
if (connect(fd, (struct sockaddr*) &sun, sizeof(sun))) {
|
||||
// If we cannot access the daemon, we start a daemon in the child process if possible
|
||||
|
||||
*sockfd = setup_socket(&sun, d);
|
||||
if (connect(*sockfd, (struct sockaddr*) &sun, sizeof(sun))) {
|
||||
if (getuid() != UID_ROOT || getgid() != UID_ROOT) {
|
||||
fprintf(stderr, "No daemon is currently running!\n");
|
||||
exit(1);
|
||||
@ -161,12 +161,26 @@ int connect_daemon() {
|
||||
|
||||
if (fork_dont_care() == 0) {
|
||||
LOGD("client: connect fail, try launching new daemon process\n");
|
||||
close(fd);
|
||||
start_daemon();
|
||||
close(*sockfd);
|
||||
switch (d) {
|
||||
case MAIN_DAEMON:
|
||||
main_daemon();
|
||||
break;
|
||||
case LOG_DAEMON:
|
||||
log_daemon();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
while (connect(fd, (struct sockaddr*) &sun, sizeof(sun)))
|
||||
while (connect(*sockfd, (struct sockaddr*) &sun, sizeof(sun)))
|
||||
usleep(10000);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int connect_daemon() {
|
||||
int fd;
|
||||
connect_daemon2(MAIN_DAEMON, &fd);
|
||||
return fd;
|
||||
}
|
||||
|
@ -13,9 +13,23 @@
|
||||
|
||||
#include "magisk.h"
|
||||
#include "utils.h"
|
||||
#include "resetprop.h"
|
||||
#include "daemon.h"
|
||||
|
||||
int loggable = 1;
|
||||
static int sockfd;
|
||||
static pthread_t thread = -1;
|
||||
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
enum {
|
||||
HIDE_EVENT,
|
||||
LOG_EVENT,
|
||||
DEBUG_EVENT
|
||||
};
|
||||
|
||||
struct log_listener {
|
||||
int fd;
|
||||
int (*filter) (const char*);
|
||||
};
|
||||
|
||||
static int am_proc_start_filter(const char *log) {
|
||||
return strstr(log, "am_proc_start") != NULL;
|
||||
@ -30,7 +44,7 @@ static int magisk_debug_log_filter(const char *log) {
|
||||
return strstr(log, "am_proc_start") == NULL;
|
||||
}
|
||||
|
||||
struct log_listener log_events[] = {
|
||||
static struct log_listener log_events[] = {
|
||||
{ /* HIDE_EVENT */
|
||||
.fd = -1,
|
||||
.filter = am_proc_start_filter
|
||||
@ -58,12 +72,55 @@ static void test_logcat() {
|
||||
waitpid(log_pid, NULL, 0);
|
||||
}
|
||||
|
||||
static void *logger_thread(void *args) {
|
||||
static void sigpipe_handler(int sig) {
|
||||
close(log_events[HIDE_EVENT].fd);
|
||||
log_events[HIDE_EVENT].fd = -1;
|
||||
}
|
||||
|
||||
static void *socket_thread(void *args) {
|
||||
/* This would block, so separate thread */
|
||||
while(1) {
|
||||
int fd = accept4(sockfd, NULL, NULL, SOCK_CLOEXEC);
|
||||
switch(read_int(fd)) {
|
||||
case HIDE_CONNECT:
|
||||
pthread_mutex_lock(&lock);
|
||||
log_events[HIDE_EVENT].fd = fd;
|
||||
pthread_mutex_unlock(&lock);
|
||||
thread = -1;
|
||||
return NULL;
|
||||
default:
|
||||
close(fd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void log_daemon() {
|
||||
setsid();
|
||||
strcpy(argv0, "magisklogd");
|
||||
|
||||
struct sockaddr_un sun;
|
||||
sockfd = setup_socket(&sun, LOG_DAEMON);
|
||||
if (xbind(sockfd, (struct sockaddr*) &sun, sizeof(sun)))
|
||||
exit(1);
|
||||
xlisten(sockfd, 1);
|
||||
LOGI("Magisk v" xstr(MAGISK_VERSION) "(" xstr(MAGISK_VER_CODE) ") logger started\n");
|
||||
|
||||
struct sigaction act;
|
||||
memset(&act, 0, sizeof(act));
|
||||
act.sa_handler = sigpipe_handler;
|
||||
sigaction(SIGPIPE, &act, NULL);
|
||||
|
||||
// Setup log dumps
|
||||
rename(LOGFILE, LOGFILE ".bak");
|
||||
log_events[LOG_EVENT].fd = xopen(LOGFILE, O_CREAT | O_WRONLY | O_TRUNC | O_CLOEXEC, 0644);
|
||||
#ifdef MAGISK_DEBUG
|
||||
log_events[DEBUG_EVENT].fd = xopen(DEBUG_LOG, O_CREAT | O_WRONLY | O_TRUNC | O_CLOEXEC, 0644);
|
||||
#endif
|
||||
|
||||
int log_fd = -1, log_pid;
|
||||
char line[PIPE_BUF];
|
||||
|
||||
LOGD("log_monitor: logger start");
|
||||
|
||||
while (1) {
|
||||
if (!loggable) {
|
||||
// Disable all services
|
||||
@ -71,7 +128,7 @@ static void *logger_thread(void *args) {
|
||||
close(log_events[i].fd);
|
||||
log_events[i].fd = -1;
|
||||
}
|
||||
return NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
// Start logcat
|
||||
@ -86,10 +143,17 @@ static void *logger_thread(void *args) {
|
||||
if (line[0] == '-')
|
||||
continue;
|
||||
size_t len = strlen(line);
|
||||
pthread_mutex_lock(&lock);
|
||||
for (int i = 0; i < EVENT_NUM; ++i) {
|
||||
if (log_events[i].fd > 0 && log_events[i].filter(line))
|
||||
xwrite(log_events[i].fd, line, len);
|
||||
write(log_events[i].fd, line, len);
|
||||
}
|
||||
if (thread < 0 && log_events[HIDE_EVENT].fd < 0) {
|
||||
// New thread to handle connection to main daemon
|
||||
xpthread_create(&thread, NULL, socket_thread, NULL);
|
||||
pthread_detach(thread);
|
||||
}
|
||||
pthread_mutex_unlock(&lock);
|
||||
if (kill(log_pid, 0))
|
||||
break;
|
||||
}
|
||||
@ -101,26 +165,15 @@ static void *logger_thread(void *args) {
|
||||
waitpid(log_pid, NULL, 0);
|
||||
test_logcat();
|
||||
}
|
||||
|
||||
// Should never be here, but well...
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Start new threads to monitor logcat and dump to logfile */
|
||||
void monitor_logs() {
|
||||
pthread_t thread;
|
||||
|
||||
test_logcat();
|
||||
|
||||
if (loggable) {
|
||||
rename(LOGFILE, LOGFILE ".bak");
|
||||
log_events[LOG_EVENT].fd = creat(LOGFILE, 0644);
|
||||
#ifdef MAGISK_DEBUG
|
||||
log_events[DEBUG_EVENT].fd = creat(DEBUG_LOG, 0644);
|
||||
#endif
|
||||
|
||||
// Start logcat monitor
|
||||
xpthread_create(&thread, NULL, logger_thread, NULL);
|
||||
pthread_detach(thread);
|
||||
int fd;
|
||||
connect_daemon2(LOG_DAEMON, &fd);
|
||||
write_int(fd, DO_NOTHING);
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
|
@ -98,7 +98,7 @@ int magisk_main(int argc, char *argv[]) {
|
||||
return 0;
|
||||
} else if (strcmp(argv[1], "--daemon") == 0) {
|
||||
int fd = connect_daemon();
|
||||
close(fd);
|
||||
write_int(fd, DO_NOTHING);
|
||||
return 0;
|
||||
} else if (strcmp(argv[1], "--startup") == 0) {
|
||||
startup();
|
||||
|
@ -57,8 +57,6 @@
|
||||
|
||||
extern policydb_t *policydb;
|
||||
int (*init_applet_main[]) (int, char *[]) = { magiskpolicy_main, magiskpolicy_main, NULL };
|
||||
static char RAND_SOCKET_NAME[sizeof(SOCKET_NAME)];
|
||||
static int SOCKET_OFF = -1;
|
||||
|
||||
struct cmdline {
|
||||
char skip_initramfs;
|
||||
@ -345,18 +343,21 @@ static int dump_magiskrc(const char *path, mode_t mode) {
|
||||
|
||||
static void patch_socket_name(const char *path) {
|
||||
void *buf;
|
||||
char name[sizeof(MAIN_SOCKET)];
|
||||
size_t size;
|
||||
mmap_rw(path, &buf, &size);
|
||||
if (SOCKET_OFF < 0) {
|
||||
for (int i = 0; i < size; ++i) {
|
||||
if (memcmp(buf + i, SOCKET_NAME, sizeof(SOCKET_NAME)) == 0) {
|
||||
SOCKET_OFF = i;
|
||||
break;
|
||||
}
|
||||
for (int i = 0; i < size; ++i) {
|
||||
if (memcmp(buf + i, MAIN_SOCKET, sizeof(MAIN_SOCKET)) == 0) {
|
||||
gen_rand_str(name, sizeof(name));
|
||||
memcpy(buf + i, name, sizeof(name));
|
||||
i += sizeof(name);
|
||||
}
|
||||
if (memcmp(buf + i, LOG_SOCKET, sizeof(LOG_SOCKET)) == 0) {
|
||||
gen_rand_str(name, sizeof(name));
|
||||
memcpy(buf + i, name, sizeof(name));
|
||||
i += sizeof(name);
|
||||
}
|
||||
}
|
||||
gen_rand_str(RAND_SOCKET_NAME, sizeof(SOCKET_NAME));
|
||||
memcpy(buf + SOCKET_OFF, RAND_SOCKET_NAME, sizeof(SOCKET_NAME));
|
||||
munmap(buf, size);
|
||||
}
|
||||
|
||||
|
@ -8,19 +8,25 @@
|
||||
#include "utils.h"
|
||||
#include "magisk.h"
|
||||
|
||||
static char socket_name[] = SOCKET_NAME; /* Workaround compiler bug pre NDK r13 */
|
||||
|
||||
/* Setup the address and return socket fd */
|
||||
int setup_socket(struct sockaddr_un *sun) {
|
||||
int setup_socket(struct sockaddr_un *sun, daemon_t d) {
|
||||
int fd = xsocket(AF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0);
|
||||
memset(sun, 0, sizeof(*sun));
|
||||
sun->sun_family = AF_LOCAL;
|
||||
sun->sun_path[0] = '\0';
|
||||
memcpy(sun->sun_path + 1, socket_name, sizeof(SOCKET_NAME));
|
||||
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);
|
||||
return fd;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Receive a file descriptor from a Unix socket.
|
||||
* Contributed by @mkasick
|
||||
|
@ -24,7 +24,8 @@ enum {
|
||||
STOP_MAGISKHIDE,
|
||||
ADD_HIDELIST,
|
||||
RM_HIDELIST,
|
||||
LS_HIDELIST
|
||||
LS_HIDELIST,
|
||||
HIDE_CONNECT
|
||||
};
|
||||
|
||||
// Return codes for daemon
|
||||
@ -39,15 +40,25 @@ enum {
|
||||
HIDE_ITEM_NOT_EXIST,
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
MAIN_DAEMON,
|
||||
LOG_DAEMON
|
||||
} daemon_t;
|
||||
|
||||
// daemon.c
|
||||
|
||||
void start_daemon();
|
||||
void main_daemon();
|
||||
int connect_daemon();
|
||||
int connect_daemon2(daemon_t d, int *sockfd);
|
||||
void auto_start_magiskhide();
|
||||
|
||||
// log_monitor.c
|
||||
|
||||
void log_daemon();
|
||||
|
||||
// socket.c
|
||||
|
||||
int setup_socket(struct sockaddr_un *sun);
|
||||
int setup_socket(struct sockaddr_un *sun, daemon_t d);
|
||||
int recv_fd(int sockfd);
|
||||
void send_fd(int sockfd, int fd);
|
||||
int read_int(int fd);
|
||||
|
@ -46,18 +46,6 @@
|
||||
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
|
||||
#define PLOGE(fmt, args...) LOGE(fmt " failed with %d: %s", ##args, errno, strerror(errno))
|
||||
|
||||
enum {
|
||||
HIDE_EVENT,
|
||||
LOG_EVENT,
|
||||
DEBUG_EVENT
|
||||
};
|
||||
|
||||
struct log_listener {
|
||||
int fd;
|
||||
int (*filter) (const char*);
|
||||
};
|
||||
|
||||
extern struct log_listener log_events[];
|
||||
extern int loggable;
|
||||
|
||||
void monitor_logs();
|
||||
|
@ -7,7 +7,8 @@
|
||||
#include "logging.h"
|
||||
|
||||
#define MAGISK_VER_STR xstr(MAGISK_VERSION) ":MAGISK"
|
||||
#define SOCKET_NAME "d30138f2310a9fb9c54a3e0c21f58591"
|
||||
#define MAIN_SOCKET "d30138f2310a9fb9c54a3e0c21f58591"
|
||||
#define LOG_SOCKET "5864cd77f2f8c59b3882e2d35dbf51e4"
|
||||
#define JAVA_PACKAGE_NAME "com.topjohnwu.magisk"
|
||||
|
||||
#ifndef ARG_MAX
|
||||
|
@ -16,21 +16,19 @@
|
||||
#include <sys/mount.h>
|
||||
|
||||
#include "magisk.h"
|
||||
#include "daemon.h"
|
||||
#include "utils.h"
|
||||
#include "magiskhide.h"
|
||||
|
||||
static int pipefd[2] = { -1, -1 };
|
||||
static int sockfd = -1;
|
||||
|
||||
// Workaround for the lack of pthread_cancel
|
||||
static void term_thread(int sig) {
|
||||
LOGD("proc_monitor: running cleanup\n");
|
||||
destroy_list();
|
||||
hideEnabled = 0;
|
||||
// Unregister listener
|
||||
log_events[HIDE_EVENT].fd = -1;
|
||||
close(pipefd[0]);
|
||||
close(pipefd[1]);
|
||||
pipefd[0] = pipefd[1] = -1;
|
||||
close(sockfd);
|
||||
sockfd = -1;
|
||||
pthread_mutex_destroy(&hide_lock);
|
||||
pthread_mutex_destroy(&file_lock);
|
||||
LOGD("proc_monitor: terminating...\n");
|
||||
@ -128,12 +126,12 @@ void proc_monitor() {
|
||||
term_thread(TERM_THREAD);
|
||||
}
|
||||
|
||||
// Register our listener to logcat monitor
|
||||
xpipe2(pipefd, O_CLOEXEC);
|
||||
log_events[HIDE_EVENT].fd = pipefd[1];
|
||||
// Connect to the log daemon
|
||||
connect_daemon2(LOG_DAEMON, &sockfd);
|
||||
write_int(sockfd, HIDE_CONNECT);
|
||||
|
||||
FILE *logs = fdopen(pipefd[0], "r");
|
||||
char log[PIPE_BUF], *line;
|
||||
FILE *logs = fdopen(sockfd, "r");
|
||||
char log[4096], *line;
|
||||
while (1) {
|
||||
/* It might be interrupted */
|
||||
if (fgets(log, sizeof(log), logs) == NULL)
|
||||
|
Loading…
Reference in New Issue
Block a user