diff --git a/jni/daemon/bootstages.c b/jni/daemon/bootstages.c index 9de282d42..9a8438540 100644 --- a/jni/daemon/bootstages.c +++ b/jni/daemon/bootstages.c @@ -133,7 +133,14 @@ static void trim_img(const char *img) { * Scripts * ***********/ -void exec_common_script(const char* stage) { +static void bb_path() { + char *path = strdup(getenv("PATH")); + snprintf(buf, PATH_MAX, "%s:%s", BBPATH, path); + setenv("PATH", buf, 1); + free(path); +} + +static void exec_common_script(const char* stage) { DIR *dir; struct dirent *entry; snprintf(buf, PATH_MAX, "%s/%s.d", COREDIR, stage); @@ -148,7 +155,7 @@ void exec_common_script(const char* stage) { continue; LOGI("%s.d: exec [%s]\n", stage, entry->d_name); char *const command[] = { "sh", buf2, NULL }; - int pid = run_command(0, NULL, "/system/bin/sh", command); + int pid = run_command(0, NULL, bb_path, "/system/bin/sh", command); if (pid != -1) waitpid(pid, NULL, 0); } @@ -157,7 +164,7 @@ void exec_common_script(const char* stage) { closedir(dir); } -void exec_module_script(const char* stage) { +static void exec_module_script(const char* stage) { char *module; vec_for_each(&module_list, module) { snprintf(buf, PATH_MAX, "%s/%s/%s.sh", MOUNTPOINT, module, stage); @@ -166,7 +173,7 @@ void exec_module_script(const char* stage) { continue; LOGI("%s: exec [%s.sh]\n", module, stage); char *const command[] = { "sh", buf, NULL }; - int pid = run_command(0, NULL, "/system/bin/sh", command); + int pid = run_command(0, NULL, bb_path, "/system/bin/sh", command); if (pid != -1) waitpid(pid, NULL, 0); } @@ -489,7 +496,7 @@ void post_fs_data(int client) { // Start debug logs in new process debug_log_fd = xopen(DEBUG_LOG, O_WRONLY | O_CREAT | O_CLOEXEC | O_TRUNC, 0644); char *const command[] = { "logcat", "-v", "brief", NULL }; - debug_log_pid = run_command(0, &debug_log_fd, "/system/bin/logcat", command); + debug_log_pid = run_command(0, &debug_log_fd, NULL, "/system/bin/logcat", command); close(debug_log_fd); #endif @@ -552,6 +559,9 @@ void post_fs_data(int client) { xmkdir(COREDIR "/props", 0755); } + // Link busybox + link_busybox(); + // Core only mode if (access(DISABLEFILE, F_OK) == 0) goto core_only; @@ -722,6 +732,10 @@ unblock: unblock_boot_process(); } +static void pm_setenv() { + setenv("CLASSPATH", "/system/framework/pm.jar", 1); +} + void late_start(int client) { LOGI("** late_start service mode running\n"); // ack @@ -751,18 +765,19 @@ core_only: if (access(MANAGERAPK, F_OK) == 0) { while (1) { sleep(5); - char *const command[] = { "sh", "-c", - "CLASSPATH=/system/framework/pm.jar " - "/system/bin/app_process /system/bin " - "com.android.commands.pm.Pm install -r " MANAGERAPK, NULL }; + char *const command[] = { "app_process", + "/system/bin", "com.android.commands.pm.Pm", + "install", "-r", MANAGERAPK, NULL }; int apk_res = -1, pid; - pid = run_command(1, &apk_res, "/system/bin/sh", command); - waitpid(pid, NULL, 0); - fdgets(buf, PATH_MAX, apk_res); - close(apk_res); - // Keep trying until pm is started - if (strstr(buf, "Error:") == NULL) - break; + pid = run_command(1, &apk_res, pm_setenv, "/system/bin/app_process", command); + if (pid != -1) { + waitpid(pid, NULL, 0); + fdgets(buf, PATH_MAX, apk_res); + close(apk_res); + // Keep trying until pm is started + if (strstr(buf, "Error:") == NULL) + break; + } } unlink(MANAGERAPK); } diff --git a/jni/daemon/log_monitor.c b/jni/daemon/log_monitor.c index 48c3cfa14..d6ffbd00d 100644 --- a/jni/daemon/log_monitor.c +++ b/jni/daemon/log_monitor.c @@ -27,12 +27,12 @@ static void *logger_thread(void *args) { while (1) { // Start logcat char *const command[] = { "logcat", "-s", "Magisk", "-v", "thread", NULL }; - log_pid = run_command(0, &log_fd, "/system/bin/logcat", command); + log_pid = run_command(0, &log_fd, NULL, "/system/bin/logcat", command); if (log_pid > 0) waitpid(log_pid, NULL, 0); // For some reason it went here, clear buffer and restart char *const restart[] = { "logcat", "-c", NULL }; - log_pid = run_command(0, NULL, "/system/bin/logcat", restart); + log_pid = run_command(0, NULL, NULL, "/system/bin/logcat", restart); if (log_pid > 0) waitpid(log_pid, NULL, 0); } diff --git a/jni/include/magisk.h b/jni/include/magisk.h index 3b4f5ca44..821bbc8bb 100644 --- a/jni/include/magisk.h +++ b/jni/include/magisk.h @@ -35,9 +35,11 @@ #define MAINIMG "/data/magisk.img" #define DATABIN "/data/magisk" #define MANAGERAPK DATABIN "/magisk.apk" +#define BBBIN DATABIN "/busybox" #define MAGISKTMP "/dev/magisk" #define MIRRDIR MAGISKTMP "/mirror" #define DUMMDIR MAGISKTMP "/dummy" +#define BBPATH MAGISKTMP "/bin" #define CACHEMOUNT "/cache/magisk_mount" #define SELINUX_PATH "/sys/fs/selinux/" diff --git a/jni/include/utils.h b/jni/include/utils.h index fb5414eef..a4c0393e7 100644 --- a/jni/include/utils.h +++ b/jni/include/utils.h @@ -82,7 +82,7 @@ void ps_filter_proc_name(const char *filter, void (*func)(int)); int create_links(const char *bin, const char *path); void unlock_blocks(); void setup_sighandlers(void (*handler)(int)); -int run_command(int err, int *fd, const char *path, char *const argv[]); +int run_command(int err, int *fd, void (*cb)(void), const char *path, char *const argv[]); int mkdir_p(const char *pathname, mode_t mode); int bind_mount(const char *from, const char *to); int open_new(const char *filename); @@ -93,6 +93,7 @@ void fclone_attr(const int sourcefd, const int targetfd); void clone_attr(const char *source, const char *target); void get_client_cred(int fd, struct ucred *cred); int switch_mnt_ns(int pid); +void link_busybox(); // img.c int create_img(const char *img, int size); diff --git a/jni/magiskhide/proc_monitor.c b/jni/magiskhide/proc_monitor.c index e7ccd5b4a..03c9408cc 100644 --- a/jni/magiskhide/proc_monitor.c +++ b/jni/magiskhide/proc_monitor.c @@ -1,5 +1,5 @@ /* proc_monitor.c - Monitor am_proc_start events and unmount - * + * * We monitor the logcat am_proc_start events. When a target starts up, * we pause it ASAP, and fork a new process to join its mount namespace * and do all the unmounting/mocking @@ -182,14 +182,14 @@ void proc_monitor() { while (1) { // Clear previous logcat buffer char *const restart[] = { "logcat", "-b", "events", "-c", NULL }; - log_pid = run_command(0, NULL, "/system/bin/logcat", restart); + log_pid = run_command(0, NULL, NULL, "/system/bin/logcat", restart); if (log_pid > 0) waitpid(log_pid, NULL, 0); // Monitor am_proc_start char *const command[] = { "logcat", "-b", "events", "-v", "raw", "-s", "am_proc_start", NULL }; log_fd = -1; - log_pid = run_command(0, &log_fd, "/system/bin/logcat", command); + log_pid = run_command(0, &log_fd, NULL, "/system/bin/logcat", command); if (log_pid < 0) continue; if (kill(log_pid, 0)) continue; diff --git a/jni/utils/img.c b/jni/utils/img.c index 2823a0165..3849bc308 100644 --- a/jni/utils/img.c +++ b/jni/utils/img.c @@ -15,7 +15,7 @@ static int e2fsck(const char *img) { char buffer[128]; int pid, fd = -1; char *const command[] = { "e2fsck", "-yf", (char *) img, NULL }; - pid = run_command(1, &fd, "/system/bin/e2fsck", command); + pid = run_command(1, &fd, NULL, "/system/bin/e2fsck", command); if (pid < 0) return 1; while (fdgets(buffer, sizeof(buffer), fd)) @@ -63,7 +63,7 @@ int create_img(const char *img, int size) { char buffer[16]; snprintf(buffer, sizeof(buffer), "%dM", size); char *const command[] = { "make_ext4fs", "-l", buffer, "-a", "/magisk", "-S", filename, (char *) img, NULL }; - pid = run_command(0, NULL, "/system/bin/make_ext4fs", command); + pid = run_command(0, NULL, NULL, "/system/bin/make_ext4fs", command); if (pid < 0) return 1; waitpid(pid, &status, 0); @@ -77,7 +77,7 @@ int get_img_size(const char *img, int *used, int *total) { char buffer[PATH_MAX]; int pid, fd = -1, status = 1; char *const command[] = { "e2fsck", "-n", (char *) img, NULL }; - pid = run_command(1, &fd, "/system/bin/e2fsck", command); + pid = run_command(1, &fd, NULL, "/system/bin/e2fsck", command); if (pid < 0) return 1; while (fdgets(buffer, sizeof(buffer), fd)) { @@ -110,7 +110,7 @@ int resize_img(const char *img, int size) { int pid, status, fd = -1; snprintf(buffer, sizeof(buffer), "%dM", size); char *const command[] = { "resize2fs", (char *) img, buffer, NULL }; - pid = run_command(1, &fd, "/system/bin/resize2fs", command); + pid = run_command(1, &fd, NULL, "/system/bin/resize2fs", command); if (pid < 0) return 1; while (fdgets(buffer, sizeof(buffer), fd)) diff --git a/jni/utils/misc.c b/jni/utils/misc.c index 48d72c0ad..5c0a9b5bd 100644 --- a/jni/utils/misc.c +++ b/jni/utils/misc.c @@ -223,8 +223,9 @@ void setup_sighandlers(void (*handler)(int)) { fd == NULL -> Ignore output *fd < 0 -> Open pipe and set *fd to the read end *fd >= 0 -> STDOUT (or STDERR) will be redirected to *fd + *cb -> A callback function which runs after fork */ -int run_command(int err, int *fd, const char *path, char *const argv[]) { +int run_command(int err, int *fd, void (*cb)(void), const char *path, char *const argv[]) { int pipefd[2], writeEnd = -1; if (fd) { @@ -247,6 +248,8 @@ int run_command(int err, int *fd, const char *path, char *const argv[]) { return pid; } + if (cb) cb(); + if (fd) { xdup2(writeEnd, STDOUT_FILENO); if (err) xdup2(writeEnd, STDERR_FILENO); @@ -406,3 +409,11 @@ int switch_mnt_ns(int pid) { close(fd); return ret; } + +void link_busybox() { + mkdir_p(BBPATH, 0755); + char *const command[] = { "busybox", "--install", "-s", BBPATH, NULL}; + int pid = run_command(0, NULL, NULL, BBBIN, command); + if (pid != -1) + waitpid(pid, NULL, 0); +}