diff --git a/native/jni/core/magiskinit.c b/native/jni/core/magiskinit.c index 7b8e36bad..0aef45c6a 100644 --- a/native/jni/core/magiskinit.c +++ b/native/jni/core/magiskinit.c @@ -56,6 +56,8 @@ extern policydb_t *policydb; int (*init_applet_main[]) (int, char *[]) = { magiskpolicy_main, magiskpolicy_main, NULL }; static int keepverity = 0, keepencrypt = 0; +static char RAND_SOCKET_NAME[sizeof(SOCKET_NAME)]; +static int SOCKET_OFF = -1; struct cmdline { int skip_initramfs; @@ -367,6 +369,23 @@ static int dump_magiskrc(const char *path, mode_t mode) { return 0; } +static void patch_socket_name(const char *path) { + void *buf; + 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; + } + } + } + gen_rand_str(RAND_SOCKET_NAME, sizeof(SOCKET_NAME)); + memcpy(buf + SOCKET_OFF, RAND_SOCKET_NAME, sizeof(SOCKET_NAME)); + munmap(buf, size); +} + static void magisk_init_daemon() { setsid(); @@ -381,7 +400,8 @@ static void magisk_init_daemon() { dup3(null, STDIN_FILENO, O_CLOEXEC); dup3(null, STDOUT_FILENO, O_CLOEXEC); dup3(null, STDERR_FILENO, O_CLOEXEC); - close(null); + if (null > STDERR_FILENO) + close(null); // Transit our context to su (mimic setcon) int fd, crap; @@ -398,6 +418,7 @@ static void magisk_init_daemon() { 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 */ @@ -446,6 +467,7 @@ int main(int argc, char *argv[]) { dump_magisk("/overlay/sbin/magisk", 0755); mkdir("/overlay/root", 0755); link("/init", "/overlay/root/magiskinit"); + patch_socket_name("/overlay/sbin/magisk"); struct cmdline cmd; parse_cmdline(&cmd); @@ -535,6 +557,9 @@ int main(int argc, char *argv[]) { } close(overlay); + close(STDIN_FILENO); + close(STDOUT_FILENO); + close(STDERR_FILENO); if (fork_dont_care() == 0) { strcpy(argv[0], "magiskinit"); diff --git a/native/jni/core/socket.c b/native/jni/core/socket.c index 75b1b037b..e99f3d590 100644 --- a/native/jni/core/socket.c +++ b/native/jni/core/socket.c @@ -10,11 +10,12 @@ /* Setup the address and return socket fd */ int setup_socket(struct sockaddr_un *sun) { - int fd = xsocket(AF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0); - memset(sun, 0, sizeof(*sun)); - sun->sun_family = AF_LOCAL; - memcpy(sun->sun_path, REQUESTOR_DAEMON_PATH, sizeof(REQUESTOR_DAEMON_PATH) - 1); - return fd; + 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)); + return fd; } @@ -28,49 +29,49 @@ int setup_socket(struct sockaddr_un *sun) { * On error the function terminates by calling exit(-1) */ int recv_fd(int sockfd) { - // Need to receive data from the message, otherwise don't care about it. - char iovbuf; + // Need to receive data from the message, otherwise don't care about it. + char iovbuf; - struct iovec iov = { - .iov_base = &iovbuf, - .iov_len = 1, - }; + struct iovec iov = { + .iov_base = &iovbuf, + .iov_len = 1, + }; - char cmsgbuf[CMSG_SPACE(sizeof(int))]; + char cmsgbuf[CMSG_SPACE(sizeof(int))]; - struct msghdr msg = { - .msg_iov = &iov, - .msg_iovlen = 1, - .msg_control = cmsgbuf, - .msg_controllen = sizeof(cmsgbuf), - }; + struct msghdr msg = { + .msg_iov = &iov, + .msg_iovlen = 1, + .msg_control = cmsgbuf, + .msg_controllen = sizeof(cmsgbuf), + }; - xrecvmsg(sockfd, &msg, MSG_WAITALL); + xrecvmsg(sockfd, &msg, MSG_WAITALL); - // Was a control message actually sent? - switch (msg.msg_controllen) { - case 0: - // No, so the file descriptor was closed and won't be used. - return -1; - case sizeof(cmsgbuf): - // Yes, grab the file descriptor from it. - break; - default: - goto error; - } + // Was a control message actually sent? + switch (msg.msg_controllen) { + case 0: + // No, so the file descriptor was closed and won't be used. + return -1; + case sizeof(cmsgbuf): + // Yes, grab the file descriptor from it. + break; + default: + goto error; + } - struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); + struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); - if (cmsg == NULL || - cmsg->cmsg_len != CMSG_LEN(sizeof(int)) || - cmsg->cmsg_level != SOL_SOCKET || - cmsg->cmsg_type != SCM_RIGHTS) { + if (cmsg == NULL || + cmsg->cmsg_len != CMSG_LEN(sizeof(int)) || + cmsg->cmsg_level != SOL_SOCKET || + cmsg->cmsg_type != SCM_RIGHTS) { error: - LOGE("unable to read fd"); - exit(-1); - } + LOGE("unable to read fd"); + exit(-1); + } - return *(int *)CMSG_DATA(cmsg); + return *(int *)CMSG_DATA(cmsg); } /* @@ -83,70 +84,70 @@ error: * but no control message with the FD is sent. */ void send_fd(int sockfd, int fd) { - // Need to send some data in the message, this will do. - struct iovec iov = { - .iov_base = "", - .iov_len = 1, - }; + // Need to send some data in the message, this will do. + struct iovec iov = { + .iov_base = "", + .iov_len = 1, + }; - struct msghdr msg = { - .msg_iov = &iov, - .msg_iovlen = 1, - }; + struct msghdr msg = { + .msg_iov = &iov, + .msg_iovlen = 1, + }; - char cmsgbuf[CMSG_SPACE(sizeof(int))]; + char cmsgbuf[CMSG_SPACE(sizeof(int))]; - if (fd != -1) { - // Is the file descriptor actually open? - if (fcntl(fd, F_GETFD) == -1) { - if (errno != EBADF) { - PLOGE("unable to send fd"); - } - // It's closed, don't send a control message or sendmsg will EBADF. - } else { - // It's open, send the file descriptor in a control message. - msg.msg_control = cmsgbuf; - msg.msg_controllen = sizeof(cmsgbuf); + if (fd != -1) { + // Is the file descriptor actually open? + if (fcntl(fd, F_GETFD) == -1) { + if (errno != EBADF) { + PLOGE("unable to send fd"); + } + // It's closed, don't send a control message or sendmsg will EBADF. + } else { + // It's open, send the file descriptor in a control message. + msg.msg_control = cmsgbuf; + msg.msg_controllen = sizeof(cmsgbuf); - struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); + struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); - cmsg->cmsg_len = CMSG_LEN(sizeof(int)); - cmsg->cmsg_level = SOL_SOCKET; - cmsg->cmsg_type = SCM_RIGHTS; + cmsg->cmsg_len = CMSG_LEN(sizeof(int)); + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_RIGHTS; - *(int *)CMSG_DATA(cmsg) = fd; - } - } + *(int *)CMSG_DATA(cmsg) = fd; + } + } - xsendmsg(sockfd, &msg, 0); + xsendmsg(sockfd, &msg, 0); } int read_int(int fd) { - int val; - xxread(fd, &val, sizeof(int)); - return val; + int val; + xxread(fd, &val, sizeof(int)); + return val; } void write_int(int fd, int val) { - if (fd < 0) return; - xwrite(fd, &val, sizeof(int)); + if (fd < 0) return; + xwrite(fd, &val, sizeof(int)); } char* read_string(int fd) { - int len = read_int(fd); - if (len > PATH_MAX || len < 0) { - LOGE("invalid string length %d", len); - exit(1); - } - char* val = xmalloc(sizeof(char) * (len + 1)); - xxread(fd, val, len); - val[len] = '\0'; - return val; + int len = read_int(fd); + if (len > PATH_MAX || len < 0) { + LOGE("invalid string length %d", len); + exit(1); + } + char* val = xmalloc(sizeof(char) * (len + 1)); + xxread(fd, val, len); + val[len] = '\0'; + return val; } void write_string(int fd, const char* val) { - if (fd < 0) return; - int len = strlen(val); - write_int(fd, len); - xwrite(fd, val, len); + if (fd < 0) return; + int len = strlen(val); + write_int(fd, len); + xwrite(fd, val, len); } diff --git a/native/jni/include/magisk.h b/native/jni/include/magisk.h index 9baa64792..6564ebc41 100644 --- a/native/jni/include/magisk.h +++ b/native/jni/include/magisk.h @@ -7,7 +7,7 @@ #include "logging.h" #define MAGISK_VER_STR xstr(MAGISK_VERSION) ":MAGISK" -#define REQUESTOR_DAEMON_PATH "\0MAGISK" +#define SOCKET_NAME "d30138f2310a9fb9c54a3e0c21f58591" #ifndef ARG_MAX #define ARG_MAX 4096 diff --git a/native/jni/include/utils.h b/native/jni/include/utils.h index 926a661f6..7d121bd97 100644 --- a/native/jni/include/utils.h +++ b/native/jni/include/utils.h @@ -90,6 +90,7 @@ void get_client_cred(int fd, struct ucred *cred); int switch_mnt_ns(int pid); int fork_dont_care(); void wait_till_exists(const char *target); +void gen_rand_str(char *buf, int len); // file.c diff --git a/native/jni/utils/misc.c b/native/jni/utils/misc.c index 8a7112532..88bc1ee45 100644 --- a/native/jni/utils/misc.c +++ b/native/jni/utils/misc.c @@ -17,6 +17,7 @@ #include #include #include +#include #include "logging.h" #include "utils.h" @@ -341,3 +342,21 @@ void wait_till_exists(const char *target) { } close(fd); } + +void gen_rand_str(char *buf, int len) { + const char base[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_."; + int urandom; + if (access("/dev/urandom", R_OK) == 0) { + urandom = xopen("/dev/urandom", O_RDONLY | O_CLOEXEC); + } else { + mknod("/urandom", S_IFCHR | 0666, makedev(1, 9)); + urandom = xopen("/urandom", O_RDONLY | O_CLOEXEC); + unlink("/urandom"); + } + xxread(urandom, buf, len - 1); + close(urandom); + for (int i = 0; i < len - 1; ++i) { + buf[i] = base[buf[i] % (sizeof(base) - 1)]; + } + buf[len - 1] = '\0'; +}