mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-11-30 21:45:27 +00:00
Test the log buffers before running command
This commit is contained in:
parent
c3a6179a21
commit
5d5ec08566
@ -16,6 +16,7 @@
|
|||||||
#include "daemon.h"
|
#include "daemon.h"
|
||||||
|
|
||||||
int loggable = 1;
|
int loggable = 1;
|
||||||
|
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;
|
||||||
|
|
||||||
@ -49,18 +50,6 @@ static struct log_listener events[] = {
|
|||||||
};
|
};
|
||||||
#define EVENT_NUM (sizeof(events) / sizeof(struct log_listener))
|
#define EVENT_NUM (sizeof(events) / sizeof(struct log_listener))
|
||||||
|
|
||||||
static void test_logcat() {
|
|
||||||
int log_fd = -1, log_pid;
|
|
||||||
char buf[1];
|
|
||||||
log_pid = exec_command(0, &log_fd, NULL, "logcat", NULL);
|
|
||||||
if (read(log_fd, buf, sizeof(buf)) != sizeof(buf)) {
|
|
||||||
loggable = 0;
|
|
||||||
LOGD("magisklogd: cannot read from logcat, disable logging");
|
|
||||||
}
|
|
||||||
kill(log_pid, SIGTERM);
|
|
||||||
waitpid(log_pid, NULL, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void sigpipe_handler(int sig) {
|
static void sigpipe_handler(int sig) {
|
||||||
close(events[HIDE_EVENT].fd);
|
close(events[HIDE_EVENT].fd);
|
||||||
events[HIDE_EVENT].fd = -1;
|
events[HIDE_EVENT].fd = -1;
|
||||||
@ -93,12 +82,12 @@ static void *monitor_thread(void *args) {
|
|||||||
// Give the main daemon some time before we monitor it
|
// Give the main daemon some time before we monitor it
|
||||||
sleep(5);
|
sleep(5);
|
||||||
int fd;
|
int fd;
|
||||||
char b[1];
|
char b;
|
||||||
do {
|
do {
|
||||||
fd = connect_daemon();
|
fd = connect_daemon();
|
||||||
write_int(fd, MONITOR);
|
write_int(fd, MONITOR);
|
||||||
// This should hold unless the daemon is killed
|
// This should hold unless the daemon is killed
|
||||||
read(fd, b, sizeof(b));
|
read(fd, &b, sizeof(b));
|
||||||
// The main daemon crashed, spawn a new one
|
// The main daemon crashed, spawn a new one
|
||||||
close(fd);
|
close(fd);
|
||||||
} while (1);
|
} while (1);
|
||||||
@ -131,17 +120,27 @@ void log_daemon() {
|
|||||||
rename(LOGFILE, LOGFILE ".bak");
|
rename(LOGFILE, LOGFILE ".bak");
|
||||||
events[LOG_EVENT].fd = xopen(LOGFILE, O_CREAT | O_WRONLY | O_TRUNC | O_CLOEXEC | O_APPEND, 0644);
|
events[LOG_EVENT].fd = xopen(LOGFILE, O_CREAT | O_WRONLY | O_TRUNC | O_CLOEXEC | O_APPEND, 0644);
|
||||||
|
|
||||||
|
// Construct cmdline
|
||||||
|
vec_init(&log_cmd);
|
||||||
|
vec_push_back(&log_cmd, "/system/bin/logcat");
|
||||||
|
// Test whether these buffers actually works
|
||||||
|
const char* b[] = { "main", "events", "crash" };
|
||||||
|
for (int i = 0; i < 3; ++i) {
|
||||||
|
if (exec_command_sync("/system/bin/logcat", "-b", b[i], "-d", "-f", "/dev/null", NULL) == 0)
|
||||||
|
vec_push_back_all(&log_cmd, "-b", b[i], NULL);
|
||||||
|
}
|
||||||
|
vec_dup(&log_cmd, &clear_cmd);
|
||||||
|
vec_push_back_all(&log_cmd, "-v", "threadtime", "-s", "am_proc_start", "Magisk", "*:F", NULL);
|
||||||
|
vec_push_back(&log_cmd, NULL);
|
||||||
|
vec_push_back(&clear_cmd, "-c");
|
||||||
|
vec_push_back(&clear_cmd, NULL);
|
||||||
|
|
||||||
int log_fd = -1, log_pid;
|
int log_fd = -1, log_pid;
|
||||||
char line[PIPE_BUF];
|
char line[PIPE_BUF];
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
// Start logcat
|
// Start logcat
|
||||||
log_pid = exec_command(0, &log_fd, NULL,
|
log_pid = exec_array(0, &log_fd, NULL, (char **) vec_entry(&log_cmd));
|
||||||
"/system/bin/logcat",
|
|
||||||
"-b", "events", "-b", "main", "-b", "crash",
|
|
||||||
"-v", "threadtime",
|
|
||||||
"-s", "am_proc_start", "Magisk", "*:F",
|
|
||||||
NULL);
|
|
||||||
FILE *logs = fdopen(log_fd, "r");
|
FILE *logs = fdopen(log_fd, "r");
|
||||||
while (fgets(line, sizeof(line), logs)) {
|
while (fgets(line, sizeof(line), logs)) {
|
||||||
if (line[0] == '-')
|
if (line[0] == '-')
|
||||||
@ -162,13 +161,14 @@ void log_daemon() {
|
|||||||
|
|
||||||
LOGI("magisklogd: logcat output EOF");
|
LOGI("magisklogd: logcat output EOF");
|
||||||
// Clear buffer
|
// Clear buffer
|
||||||
exec_command_sync("logcat", "-b", "events", "-b", "main", "-b", "crash", "-c", NULL);
|
log_pid = exec_array(0, NULL, NULL, (char **) vec_entry(&clear_cmd));
|
||||||
|
waitpid(log_pid, NULL, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Start new threads to monitor logcat and dump to logfile */
|
/* Start new threads to monitor logcat and dump to logfile */
|
||||||
void monitor_logs() {
|
void monitor_logs() {
|
||||||
test_logcat();
|
loggable = exec_command_sync("/system/bin/logcat", "-d", "-f", "/dev/null", NULL) == 0;
|
||||||
if (loggable) {
|
if (loggable) {
|
||||||
int fd;
|
int fd;
|
||||||
connect_daemon2(LOG_DAEMON, &fd);
|
connect_daemon2(LOG_DAEMON, &fd);
|
||||||
|
@ -83,7 +83,8 @@ void ps(void (*func)(int));
|
|||||||
void ps_filter_proc_name(const char *filter, void (*func)(int));
|
void ps_filter_proc_name(const char *filter, void (*func)(int));
|
||||||
void unlock_blocks();
|
void unlock_blocks();
|
||||||
void setup_sighandlers(void (*handler)(int));
|
void setup_sighandlers(void (*handler)(int));
|
||||||
int exec_command(int err, int *fd, void (*setupenv)(struct vector*), const char *argv0, ...);
|
int exec_array(int err, int *fd, void (*setenv)(struct vector *), char *const *argv);
|
||||||
|
int exec_command(int err, int *fd, void (*setenv)(struct vector*), const char *argv0, ...);
|
||||||
int exec_command_sync(char *const argv0, ...);
|
int exec_command_sync(char *const argv0, ...);
|
||||||
int bind_mount(const char *from, const char *to);
|
int bind_mount(const char *from, const char *to);
|
||||||
void get_client_cred(int fd, struct ucred *cred);
|
void get_client_cred(int fd, struct ucred *cred);
|
||||||
|
@ -14,11 +14,12 @@ struct vector {
|
|||||||
|
|
||||||
void vec_init(struct vector *v);
|
void vec_init(struct vector *v);
|
||||||
void vec_push_back(struct vector *v, void *p);
|
void vec_push_back(struct vector *v, void *p);
|
||||||
|
void vec_push_back_all(struct vector *v, void *p, ...);
|
||||||
void *vec_pop_back(struct vector *v);
|
void *vec_pop_back(struct vector *v);
|
||||||
void vec_sort(struct vector *v, int (*compar)(const void *, const void *));
|
void vec_sort(struct vector *v, int (*compar)(const void *, const void *));
|
||||||
void vec_destroy(struct vector *v);
|
void vec_destroy(struct vector *v);
|
||||||
void vec_deep_destroy(struct vector *v);
|
void vec_deep_destroy(struct vector *v);
|
||||||
struct vector *vec_dup(struct vector *v);
|
void vec_dup(struct vector *v, struct vector *vv);
|
||||||
|
|
||||||
#define vec_size(v) (v)->size
|
#define vec_size(v) (v)->size
|
||||||
#define vec_cap(v) (v)->cap
|
#define vec_cap(v) (v)->cap
|
||||||
|
@ -245,9 +245,9 @@ void setup_sighandlers(void (*handler)(int)) {
|
|||||||
fd == NULL -> Ignore output
|
fd == NULL -> Ignore output
|
||||||
*fd < 0 -> Open pipe and set *fd to the read end
|
*fd < 0 -> Open pipe and set *fd to the read end
|
||||||
*fd >= 0 -> STDOUT (or STDERR) will be redirected to *fd
|
*fd >= 0 -> STDOUT (or STDERR) will be redirected to *fd
|
||||||
*cb -> A callback function which runs after fork
|
*setenv -> A callback function which sets up a vector of environment variables
|
||||||
*/
|
*/
|
||||||
static int v_exec_command(int err, int *fd, void (*setupenv)(struct vector*), const char *argv0, va_list argv) {
|
int exec_array(int err, int *fd, void (*setenv)(struct vector *), char *const *argv) {
|
||||||
int pipefd[2], writeEnd = -1;
|
int pipefd[2], writeEnd = -1;
|
||||||
|
|
||||||
if (fd) {
|
if (fd) {
|
||||||
@ -260,20 +260,12 @@ static int v_exec_command(int err, int *fd, void (*setupenv)(struct vector*), co
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Collect va_list into vector
|
|
||||||
struct vector args;
|
|
||||||
vec_init(&args);
|
|
||||||
vec_push_back(&args, strdup(argv0));
|
|
||||||
for (void *arg = va_arg(argv, void*); arg; arg = va_arg(argv, void*))
|
|
||||||
vec_push_back(&args, strdup(arg));
|
|
||||||
vec_push_back(&args, NULL);
|
|
||||||
|
|
||||||
// Setup environment
|
// Setup environment
|
||||||
char *const *envp;
|
char *const *envp;
|
||||||
struct vector env;
|
struct vector env;
|
||||||
vec_init(&env);
|
vec_init(&env);
|
||||||
if (setupenv) {
|
if (setenv) {
|
||||||
setupenv(&env);
|
setenv(&env);
|
||||||
envp = (char **) vec_entry(&env);
|
envp = (char **) vec_entry(&env);
|
||||||
} else {
|
} else {
|
||||||
extern char **environ;
|
extern char **environ;
|
||||||
@ -287,21 +279,34 @@ static int v_exec_command(int err, int *fd, void (*setupenv)(struct vector*), co
|
|||||||
*fd = pipefd[0];
|
*fd = pipefd[0];
|
||||||
close(pipefd[1]);
|
close(pipefd[1]);
|
||||||
}
|
}
|
||||||
vec_deep_destroy(&args);
|
|
||||||
vec_deep_destroy(&env);
|
vec_deep_destroy(&env);
|
||||||
return pid;
|
return pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fd) {
|
if (fd) {
|
||||||
xdup2(writeEnd, STDOUT_FILENO);
|
xdup2(writeEnd, STDOUT_FILENO);
|
||||||
if (err) xdup2(writeEnd, STDERR_FILENO);
|
if (err)
|
||||||
|
xdup2(writeEnd, STDERR_FILENO);
|
||||||
}
|
}
|
||||||
|
|
||||||
execvpe(argv0, (char **) vec_entry(&args), envp);
|
execvpe(argv[0], argv, envp);
|
||||||
PLOGE("execvpe %s", argv0);
|
PLOGE("execvpe %s", argv[0]);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int v_exec_command(int err, int *fd, void (*setenv)(struct vector*), const char *argv0, va_list argv) {
|
||||||
|
// Collect va_list into vector
|
||||||
|
struct vector args;
|
||||||
|
vec_init(&args);
|
||||||
|
vec_push_back(&args, strdup(argv0));
|
||||||
|
for (void *arg = va_arg(argv, void*); arg; arg = va_arg(argv, void*))
|
||||||
|
vec_push_back(&args, strdup(arg));
|
||||||
|
vec_push_back(&args, NULL);
|
||||||
|
int pid = exec_array(err, fd, setenv, (char **) vec_entry(&args));
|
||||||
|
vec_deep_destroy(&args);
|
||||||
|
return pid;
|
||||||
|
}
|
||||||
|
|
||||||
int exec_command_sync(char *const argv0, ...) {
|
int exec_command_sync(char *const argv0, ...) {
|
||||||
va_list argv;
|
va_list argv;
|
||||||
va_start(argv, argv0);
|
va_start(argv, argv0);
|
||||||
@ -314,10 +319,10 @@ int exec_command_sync(char *const argv0, ...) {
|
|||||||
return WEXITSTATUS(status);
|
return WEXITSTATUS(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
int exec_command(int err, int *fd, void (*setupenv)(struct vector*), const char *argv0, ...) {
|
int exec_command(int err, int *fd, void (*setenv)(struct vector*), const char *argv0, ...) {
|
||||||
va_list argv;
|
va_list argv;
|
||||||
va_start(argv, argv0);
|
va_start(argv, argv0);
|
||||||
int pid = v_exec_command(err, fd, setupenv, argv0, argv);
|
int pid = v_exec_command(err, fd, setenv, argv0, argv);
|
||||||
va_end(argv);
|
va_end(argv);
|
||||||
return pid;
|
return pid;
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
#include "vector.h"
|
#include "vector.h"
|
||||||
|
|
||||||
@ -23,6 +24,15 @@ void vec_push_back(struct vector *v, void *p) {
|
|||||||
++vec_size(v);
|
++vec_size(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void vec_push_back_all(struct vector *v, void *p, ...) {
|
||||||
|
va_list argv;
|
||||||
|
va_start(argv, p);
|
||||||
|
vec_push_back(v, p);
|
||||||
|
for (void *arg = va_arg(argv, char*); arg; arg = va_arg(argv, char*))
|
||||||
|
vec_push_back(v, arg);
|
||||||
|
va_end(argv);
|
||||||
|
}
|
||||||
|
|
||||||
void *vec_pop_back(struct vector *v) {
|
void *vec_pop_back(struct vector *v) {
|
||||||
void *ret = vec_entry(v)[vec_size(v) - 1];
|
void *ret = vec_entry(v)[vec_size(v) - 1];
|
||||||
--vec_size(v);
|
--vec_size(v);
|
||||||
@ -73,11 +83,9 @@ void vec_deep_destroy(struct vector *v) {
|
|||||||
vec_destroy(v);
|
vec_destroy(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct vector *vec_dup(struct vector *v) {
|
void vec_dup(struct vector *v, struct vector *vv) {
|
||||||
struct vector *ret = malloc(sizeof(*ret));
|
vec_size(vv) = vec_size(v);
|
||||||
vec_size(ret) = vec_size(v);
|
vec_cap(vv) = vec_cap(v);
|
||||||
vec_cap(ret) = vec_cap(v);
|
vec_entry(vv) = malloc(sizeof(void*) * vec_cap(v));
|
||||||
vec_entry(v) = malloc(sizeof(void*) * vec_cap(ret));
|
memcpy(vec_entry(vv), vec_entry(v), sizeof(void*) * vec_cap(v));
|
||||||
memcpy(vec_entry(ret), vec_entry(v), sizeof(void*) * vec_cap(ret));
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user