diff --git a/jni/Android.mk b/jni/Android.mk index 21d797665..30b263e48 100644 --- a/jni/Android.mk +++ b/jni/Android.mk @@ -69,6 +69,8 @@ LOCAL_C_INCLUDES := \ LOCAL_SRC_FILES := \ core/magiskinit.c \ + core/socket.c \ + utils/misc.c \ utils/vector.c \ utils/file.c \ utils/xwrap.c \ diff --git a/jni/core/daemon.c b/jni/core/daemon.c index db9db27a3..ebdac594e 100644 --- a/jni/core/daemon.c +++ b/jni/core/daemon.c @@ -128,7 +128,8 @@ void start_daemon() { struct sockaddr_un sun; fd = setup_socket(&sun); - xbind(fd, (struct sockaddr*) &sun, sizeof(sun)); + if (xbind(fd, (struct sockaddr*) &sun, sizeof(sun))) + exit(1); xlisten(fd, 10); if ((is_restart = access(MAGISKTMP, F_OK) == 0)) { @@ -149,9 +150,6 @@ void start_daemon() { // Unlock all blocks for rw unlock_blocks(); - // Notifiy init the daemon is started - close(xopen(UNBLOCKFILE, O_RDONLY | O_CREAT)); - // Loop forever to listen for requests while(1) { int *client = xmalloc(sizeof(int)); @@ -167,7 +165,7 @@ void start_daemon() { int connect_daemon() { struct sockaddr_un sun; int fd = setup_socket(&sun); - if (xconnect(fd, (struct sockaddr*) &sun, sizeof(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 if (getuid() != UID_ROOT || getgid() != UID_ROOT) { @@ -181,10 +179,8 @@ int connect_daemon() { start_daemon(); } - do { - // Wait for 10ms - usleep(10); - } while (connect(fd, (struct sockaddr*) &sun, sizeof(sun))); + while (connect(fd, (struct sockaddr*) &sun, sizeof(sun))) + usleep(10000); } return fd; } diff --git a/jni/core/magisk.c b/jni/core/magisk.c index 87244d8e6..2e921b6f6 100644 --- a/jni/core/magisk.c +++ b/jni/core/magisk.c @@ -148,8 +148,9 @@ int main(int argc, char *argv[]) { clone_attr(argv[2], argv[3]); return 0; } else if (strcmp(argv[1], "--daemon") == 0) { - // Start daemon, this process won't return - start_daemon(); + if (xfork() == 0) + start_daemon(); + return 0; } else if (strcmp(argv[1], "--post-fs") == 0) { int fd = connect_daemon(); write_int(fd, POST_FS); diff --git a/jni/core/magiskinit.c b/jni/core/magiskinit.c index 22f32cb69..f8237d41f 100644 --- a/jni/core/magiskinit.c +++ b/jni/core/magiskinit.c @@ -38,11 +38,13 @@ #include #include -#include "magisk.h" + +#include "dump.h" +#include "magiskrc.h" #include "utils.h" #include "magiskpolicy.h" -#include "magiskrc.h" -#include "dump.h" +#include "daemon.h" +#include "magisk.h" // #define VLOG(fmt, ...) printf(fmt, __VA_ARGS__) /* Enable to debug */ #define VLOG(fmt, ...) @@ -341,13 +343,40 @@ static int dump_magiskrc(const char *path, mode_t mode) { } static void magisk_init_daemon() { - // Fork a new process for full patch setsid(); sepol_allow("su", ALL, ALL, ALL); + + // Wait till init cold boot done wait_till_exists("/dev/.coldboot_done"); + + // Transit our context to su (mimic setcon) + int fd, crap; + fd = open("/proc/self/attr/current", O_WRONLY); + write(fd, "u:r:su:s0", 9); + close(fd); + + // Dump full patch to kernel dump_policydb(SELINUX_LOAD); close(open(PATCHDONE, O_RDONLY | O_CREAT, 0)); destroy_policydb(); + + // Keep Magisk daemon always alive + struct sockaddr_un sun; + fd = setup_socket(&sun); + while (1) { + while (connect(fd, (struct sockaddr*) &sun, sizeof(sun))) + usleep(10000); /* Wait 10 ms after each try */ + + /* Should hold forever */ + read(fd, &crap, sizeof(crap)); + + /* If things went here, it means the other side of the socket is closed + * We restart the daemon again */ + if (fork_dont_care() == 0) { + execv("/sbin/magisk", (char *[]) { "resetprop", "magisk.daemon", "1", NULL } ); + exit(1); + } + } exit(0); } @@ -434,8 +463,10 @@ int main(int argc, char *argv[]) { umount("/vendor"); - if (fork() == 0) + if (fork_dont_care() == 0) { + strcpy(argv[0], "magiskinit"); magisk_init_daemon(); + } // Finally, give control back! execv("/init", argv); diff --git a/jni/include/logging.h b/jni/include/logging.h index 8ad898942..fc55afbd2 100644 --- a/jni/include/logging.h +++ b/jni/include/logging.h @@ -45,6 +45,7 @@ void start_debug_log(); #include +#define LOGI(...) #define LOGE(...) { fprintf(stderr, __VA_ARGS__); exit(1); } #define PLOGE(fmt, args...) { fprintf(stderr, fmt " failed with %d: %s\n\n", ##args, errno, strerror(errno)); exit(1); } diff --git a/jni/include/magiskrc.h b/jni/include/magiskrc.h index 6eb1a8870..019db19f1 100644 --- a/jni/include/magiskrc.h +++ b/jni/include/magiskrc.h @@ -4,9 +4,6 @@ const char magiskrc[] = "on post-fs\n" " start logd\n" -" start magisk_daemon\n" -" wait /dev/.magisk.unblock 5\n" -" rm /dev/.magisk.unblock\n" " start magisk_pfs\n" " wait /dev/.magisk.unblock 10\n" "\n" @@ -19,11 +16,16 @@ const char magiskrc[] = " rm /dev/.magisk.unblock\n" "\n" +"on property:magisk.daemon=1\n" +" start magisk_daemon\n" +"\n" + // Services "service magisk_daemon /sbin/magisk --daemon\n" " user root\n" " seclabel u:r:su:s0\n" +" oneshot\n" "\n" "service magisk_pfs /sbin/magisk --post-fs\n" diff --git a/jni/magiskpolicy b/jni/magiskpolicy index e5b6121d1..8ee9984e4 160000 --- a/jni/magiskpolicy +++ b/jni/magiskpolicy @@ -1 +1 @@ -Subproject commit e5b6121d176ee75cbfce58c471cd5d9dc1eb7caa +Subproject commit 8ee9984e4e0a0ce1917d4b131205c79a15f85876