diff --git a/app b/app index e79d76414..6764a9840 160000 --- a/app +++ b/app @@ -1 +1 @@ -Subproject commit e79d764148a493aeb82fa590301a4301f662ff76 +Subproject commit 6764a98409fac8da30218ec87b7f7e6fcfcef4c9 diff --git a/native/jni/Android.mk b/native/jni/Android.mk index eadf36fce..8b54020aa 100644 --- a/native/jni/Android.mk +++ b/native/jni/Android.mk @@ -31,6 +31,7 @@ LOCAL_SHARED_LIBRARIES := libsqlite libselinux LOCAL_C_INCLUDES := \ jni/include \ + jni/magiskpolicy \ $(EXT_PATH)/include \ $(LIBSELINUX) @@ -74,7 +75,6 @@ LOCAL_C_INCLUDES := \ LOCAL_SRC_FILES := \ core/magiskinit.c \ - core/socket.c \ magiskpolicy/api.c \ magiskpolicy/magiskpolicy.c \ magiskpolicy/rules.c \ diff --git a/native/jni/core/bootstages.c b/native/jni/core/bootstages.c index 0ce221802..1e899c57b 100644 --- a/native/jni/core/bootstages.c +++ b/native/jni/core/bootstages.c @@ -19,6 +19,7 @@ #include "utils.h" #include "daemon.h" #include "resetprop.h" +#include "magiskpolicy.h" static char *buf, *buf2; static struct vector module_list; @@ -451,7 +452,7 @@ static int prepare_img() { void fix_filecon() { int dirfd = xopen(MOUNTPOINT, O_RDONLY | O_CLOEXEC); - restorecon(dirfd, 0); + restorecon(dirfd); close(dirfd); } @@ -621,8 +622,7 @@ void late_start(int client) { if (buf2 == NULL) buf2 = xmalloc(PATH_MAX); // Wait till the full patch is done - wait_till_exists(PATCHDONE); - unlink(PATCHDONE); + waitpid(full_patch_pid, NULL, 0); // Run scripts after full patch, most reliable way to run scripts LOGI("* Running service.d scripts\n"); @@ -639,7 +639,7 @@ core_only: // Install Magisk Manager if exists if (access(MANAGERAPK, F_OK) == 0) { rename(MANAGERAPK, "/data/magisk.apk"); - setfilecon("/data/magisk.apk", "u:object_r:su_file:s0"); + setfilecon("/data/magisk.apk", "u:object_r:"SEPOL_FILE_DOMAIN":s0"); while (1) { sleep(5); LOGD("apk_install: attempting to install APK"); diff --git a/native/jni/core/daemon.c b/native/jni/core/daemon.c index 7e5f1a302..af3438c93 100644 --- a/native/jni/core/daemon.c +++ b/native/jni/core/daemon.c @@ -19,8 +19,11 @@ #include "utils.h" #include "daemon.h" #include "resetprop.h" +#include "magiskpolicy.h" -int is_daemon_init = 0, seperate_vendor = 0; +int is_daemon_init = 0; +int seperate_vendor = 0; +int full_patch_pid; static void *request_handler(void *args) { int client = *((int *) args); @@ -133,23 +136,50 @@ void daemon_init() { LOGI("* Creating /sbin overlay"); DIR *dir; struct dirent *entry; - int root, sbin; + int root, sbin, fd; char buf[PATH_MAX], buf2[PATH_MAX]; - char magisk_name[10], init_name[10]; + void *data; + size_t size; - // Setup links under /sbin + // Create hardlink mirror of /sbin to /root xmount(NULL, "/", NULL, MS_REMOUNT, NULL); - xmkdir("/root", 0755); - chmod("/root", 0755); + full_read("/sbin/magisk", &data, &size); root = xopen("/root", O_RDONLY | O_CLOEXEC); sbin = xopen("/sbin", O_RDONLY | O_CLOEXEC); link_dir(sbin, root); unlink("/sbin/magisk"); close(sbin); + // Mount the /sbin tmpfs overlay xmount("tmpfs", "/sbin", "tmpfs", 0, NULL); chmod("/sbin", 0755); setfilecon("/sbin", "u:object_r:rootfs:s0"); + + // Setup magisk + fd = creat("/sbin/magisk", 0755); + xwrite(fd, data, size); + close(fd); + free(data); + setfilecon("/sbin/magisk", "u:object_r:"SEPOL_FILE_DOMAIN":s0"); + for (int i = 0; applet[i]; ++i) { + snprintf(buf, PATH_MAX, "/sbin/%s", applet[i]); + xsymlink("/sbin/magisk", buf); + } + + // Setup magiskinit + full_read("/root/magiskinit", &data, &size); + unlink("/root/magiskinit"); + fd = creat("/sbin/magiskinit", 0755); + xwrite(fd, data, size); + close(fd); + free(data); + setfilecon("/sbin/magiskinit", "u:object_r:"SEPOL_FILE_DOMAIN":s0"); + for (int i = 0; init_applet[i]; ++i) { + snprintf(buf, PATH_MAX, "/sbin/%s", init_applet[i]); + xsymlink("/sbin/magiskinit", buf); + } + + // Create symlinks pointing back to /root dir = xfdopendir(root); while((entry = xreaddir(dir))) { if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) continue; @@ -158,29 +188,11 @@ void daemon_init() { xsymlink(buf, buf2); } - gen_rand_str(magisk_name, sizeof(magisk_name)); - snprintf(buf, PATH_MAX, "/root/%s", magisk_name); - unlink("/sbin/magisk"); - rename("/root/magisk", buf); - xsymlink(buf, "/sbin/magisk"); - for (int i = 0; applet[i]; ++i) { - snprintf(buf2, PATH_MAX, "/sbin/%s", applet[i]); - xsymlink(buf, buf2); - } - - gen_rand_str(init_name, sizeof(init_name)); - snprintf(buf, PATH_MAX, "/root/%s", init_name); - unlink("/sbin/magiskinit"); - rename("/root/magiskinit", buf); - for (int i = 0; init_applet[i]; ++i) { - snprintf(buf2, PATH_MAX, "/sbin/%s", init_applet[i]); - xsymlink(buf, buf2); - } - close(root); - xmount(NULL, "/", NULL, MS_REMOUNT | MS_RDONLY, NULL); + full_patch_pid = exec_command(0, NULL, NULL, "/sbin/magiskpolicy", "--live", "allow "SEPOL_PROC_DOMAIN" * * *", NULL); + LOGI("* Mounting mirrors"); struct vector mounts; vec_init(&mounts); @@ -239,7 +251,7 @@ void daemon_init() { void start_daemon() { setsid(); - setcon("u:r:su:s0"); + setcon("u:r:"SEPOL_PROC_DOMAIN":s0"); umask(0); int fd = xopen("/dev/null", O_RDWR | O_CLOEXEC); xdup2(fd, STDIN_FILENO); diff --git a/native/jni/core/magiskinit.c b/native/jni/core/magiskinit.c index d555a9a04..c24e80e02 100644 --- a/native/jni/core/magiskinit.c +++ b/native/jni/core/magiskinit.c @@ -339,7 +339,7 @@ static void patch_socket_name(const char *path) { 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) { + if (memcmp(buf + i, SOCKET_NAME, sizeof(SOCKET_NAME)) == 0) { SOCKET_OFF = i; break; } @@ -350,55 +350,6 @@ static void patch_socket_name(const char *path) { munmap(buf, size); } -static void magisk_init_daemon() { - setsid(); - - // Full patch - sepol_allow("su", ALL, ALL, ALL); - - // Wait till init cold boot done - while (access("/dev/.coldboot_done", F_OK)) - usleep(1); - - int null = open("/dev/null", O_RDWR | O_CLOEXEC); - dup3(null, STDIN_FILENO, O_CLOEXEC); - dup3(null, STDOUT_FILENO, O_CLOEXEC); - dup3(null, STDERR_FILENO, O_CLOEXEC); - if (null > STDERR_FILENO) - close(null); - - // 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(creat(PATCHDONE, 0)); - destroy_policydb(); - - // Keep Magisk daemon always alive - while (1) { - struct sockaddr_un sun; - fd = setup_socket(&sun); - memcpy(sun.sun_path + 1, RAND_SOCKET_NAME, sizeof(SOCKET_NAME)); - 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 */ - close(fd); - if (fork_dont_care() == 0) { - execv("/sbin/magisk", (char *[]) { "magisk", "--daemon", NULL } ); - exit(1); - } - } -} - int main(int argc, char *argv[]) { umask(0); @@ -430,7 +381,7 @@ int main(int argc, char *argv[]) { mkdir("/overlay/sbin", 0755); dump_magisk("/overlay/sbin/magisk", 0755); patch_socket_name("/overlay/sbin/magisk"); - mkdir("/overlay/root", 0755); + mkdir("/overlay/root", 0750); link("/init", "/overlay/root/magiskinit"); struct cmdline cmd; @@ -520,20 +471,13 @@ int main(int argc, char *argv[]) { patch_ramdisk(); patch_sepolicy(); - - close(STDIN_FILENO); - close(STDOUT_FILENO); - close(STDERR_FILENO); - - if (fork_dont_care() == 0) { - strcpy(argv[0], "magiskinit"); - close(root); - magisk_init_daemon(); - } } // Clean up close(root); + close(STDIN_FILENO); + close(STDOUT_FILENO); + close(STDERR_FILENO); if (!cmd.skip_initramfs) umount("/system"); umount("/vendor"); diff --git a/native/jni/core/socket.c b/native/jni/core/socket.c index 9b1d8bd17..73861dba0 100644 --- a/native/jni/core/socket.c +++ b/native/jni/core/socket.c @@ -8,7 +8,7 @@ #include "utils.h" #include "magisk.h" -char socket_name[] = SOCKET_NAME; +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) { diff --git a/native/jni/include/daemon.h b/native/jni/include/daemon.h index 823d1a7cf..9298d275d 100644 --- a/native/jni/include/daemon.h +++ b/native/jni/include/daemon.h @@ -8,7 +8,9 @@ #include #include -extern int is_daemon_init, seperate_vendor; +extern int is_daemon_init; +extern int seperate_vendor; +extern int full_patch_pid; // Commands require connecting to daemon enum { diff --git a/native/jni/include/magisk.h b/native/jni/include/magisk.h index 1f15c7df3..6564ebc41 100644 --- a/native/jni/include/magisk.h +++ b/native/jni/include/magisk.h @@ -55,7 +55,6 @@ extern char *argv0; /* For changing process name */ #define init_applet ((char *[]) { "magiskpolicy", "supolicy", NULL }) extern int (*applet_main[]) (int, char *[]), (*init_applet_main[]) (int, char *[]); -extern char socket_name[]; /* Workaround compiler bug pre NDK r13 */ int create_links(const char *bin, const char *path); diff --git a/native/jni/include/magiskrc.h b/native/jni/include/magiskrc.h index 91d7a92e3..54bf8e08b 100644 --- a/native/jni/include/magiskrc.h +++ b/native/jni/include/magiskrc.h @@ -1,3 +1,5 @@ +#include "magiskpolicy.h" + const char magiskrc[] = // Triggers @@ -20,25 +22,25 @@ const char magiskrc[] = "service magisk_daemon /sbin/magisk --daemon\n" " user root\n" -" seclabel u:r:su:s0\n" +" seclabel u:r:"SEPOL_PROC_DOMAIN":s0\n" " oneshot\n" "\n" "service magisk_pfs /sbin/magisk --post-fs\n" " user root\n" -" seclabel u:r:su:s0\n" +" seclabel u:r:"SEPOL_PROC_DOMAIN":s0\n" " oneshot\n" "\n" "service magisk_pfsd /sbin/magisk --post-fs-data\n" " user root\n" -" seclabel u:r:su:s0\n" +" seclabel u:r:"SEPOL_PROC_DOMAIN":s0\n" " oneshot\n" "\n" -"service magisk_service /sbin/magisk --service\n" +"service magisk_service /sbin/magisk --service\n" " class late_start\n" " user root\n" -" seclabel u:r:su:s0\n" +" seclabel u:r:"SEPOL_PROC_DOMAIN":s0\n" " oneshot\n" ; diff --git a/native/jni/include/utils.h b/native/jni/include/utils.h index 7d121bd97..6e08c9deb 100644 --- a/native/jni/include/utils.h +++ b/native/jni/include/utils.h @@ -122,7 +122,7 @@ int setattrat(int dirfd, const char *pathname, struct file_attr *a); int fsetattr(int fd, struct file_attr *a); void fclone_attr(const int sourcefd, const int targetfd); void clone_attr(const char *source, const char *target); -void restorecon(int dirfd, int force); +void restorecon(int dirfd); int mmap_ro(const char *filename, void **buf, size_t *size); int mmap_rw(const char *filename, void **buf, size_t *size); void fd_full_read(int fd, void **buf, size_t *size); diff --git a/native/jni/magiskpolicy b/native/jni/magiskpolicy index 21a557a18..31110b192 160000 --- a/native/jni/magiskpolicy +++ b/native/jni/magiskpolicy @@ -1 +1 @@ -Subproject commit 21a557a1840392e1b802480814cbb86607534814 +Subproject commit 31110b192721f9c721efb154333d1110cd9800b8 diff --git a/native/jni/su b/native/jni/su index ed5dd827e..248f8a2a3 160000 --- a/native/jni/su +++ b/native/jni/su @@ -1 +1 @@ -Subproject commit ed5dd827e9092bc87a6f89e211a50092485d4e91 +Subproject commit 248f8a2a39acf51bf4cb603a32e70430b851edf4 diff --git a/native/jni/utils/file.c b/native/jni/utils/file.c index 888f7c3ea..ee690d331 100644 --- a/native/jni/utils/file.c +++ b/native/jni/utils/file.c @@ -344,7 +344,7 @@ void fclone_attr(const int sourcefd, const int targetfd) { #define UNLABEL_CON "u:object_r:unlabeled:s0" #define SYSTEM_CON "u:object_r:system_file:s0" -void restorecon(int dirfd, int force) { +void restorecon(int dirfd) { struct dirent *entry; DIR *dir; int fd; @@ -352,7 +352,7 @@ void restorecon(int dirfd, int force) { fd_getpath(dirfd, path, sizeof(path)); lgetfilecon(path, &con); - if (force || strlen(con) == 0 || strcmp(con, UNLABEL_CON) == 0) + if (strlen(con) == 0 || strcmp(con, UNLABEL_CON) == 0) lsetfilecon(path, SYSTEM_CON); freecon(con); @@ -362,12 +362,12 @@ void restorecon(int dirfd, int force) { continue; if (entry->d_type == DT_DIR) { fd = xopenat(dirfd, entry->d_name, O_RDONLY | O_CLOEXEC); - restorecon(fd, force); + restorecon(fd); } else { fd = xopenat(dirfd, entry->d_name, O_PATH | O_NOFOLLOW | O_CLOEXEC); fd_getpath(fd, path, sizeof(path)); lgetfilecon(path, &con); - if (force || strlen(con) == 0 || strcmp(con, UNLABEL_CON) == 0) + if (strlen(con) == 0 || strcmp(con, UNLABEL_CON) == 0) lsetfilecon(path, SYSTEM_CON); freecon(con); } @@ -379,7 +379,7 @@ void restorecon(int dirfd, int force) { static int _mmap(int rw, const char *filename, void **buf, size_t *size) { struct stat st; - int fd = xopen(filename, rw ? O_RDWR : O_RDONLY); + int fd = xopen(filename, (rw ? O_RDWR : O_RDONLY) | O_CLOEXEC); fstat(fd, &st); if (S_ISBLK(st.st_mode)) ioctl(fd, BLKGETSIZE64, size); @@ -407,7 +407,7 @@ void fd_full_read(int fd, void **buf, size_t *size) { } void full_read(const char *filename, void **buf, size_t *size) { - int fd = xopen(filename, O_RDONLY); + int fd = xopen(filename, O_RDONLY | O_CLOEXEC); if (fd < 0) { *buf = NULL; *size = 0; @@ -418,7 +418,7 @@ void full_read(const char *filename, void **buf, size_t *size) { } void full_read_at(int dirfd, const char *filename, void **buf, size_t *size) { - int fd = xopenat(dirfd, filename, O_RDONLY); + int fd = xopenat(dirfd, filename, O_RDONLY | O_CLOEXEC); if (fd < 0) { *buf = NULL; *size = 0;