diff --git a/jni/Android.mk b/jni/Android.mk index 9de421dce..feadacf4d 100644 --- a/jni/Android.mk +++ b/jni/Android.mk @@ -29,7 +29,6 @@ LOCAL_C_INCLUDES := \ LOCAL_SRC_FILES := \ core/magisk.c \ core/daemon.c \ - core/socket_trans.c \ core/log_monitor.c \ core/bootstages.c \ utils/misc.c \ @@ -98,7 +97,6 @@ LOCAL_SRC_FILES := \ magiskboot/bootimg.c \ magiskboot/hexpatch.c \ magiskboot/compress.c \ - magiskboot/boot_utils.c \ magiskboot/cpio.c \ magiskboot/sha1.c \ magiskboot/types.c \ diff --git a/jni/core/bootstages.c b/jni/core/bootstages.c index 37ebc6234..b11ea74ed 100644 --- a/jni/core/bootstages.c +++ b/jni/core/bootstages.c @@ -292,7 +292,7 @@ static void clone_skeleton(struct node_entry *node) { if (IS_DIR(child)) xmkdir(buf, 0755); else if (IS_REG(child)) - close(open_new(buf)); + close(creat(buf, 0644)); // Links will be handled later if (child->parent->parent == NULL && strcmp(child->name, "vendor") == 0) { diff --git a/jni/core/daemon.c b/jni/core/daemon.c index 87b7a53dc..e69175004 100644 --- a/jni/core/daemon.c +++ b/jni/core/daemon.c @@ -192,3 +192,136 @@ int connect_daemon() { } return fd; } + +/* + * Receive a file descriptor from a Unix socket. + * Contributed by @mkasick + * + * Returns the file descriptor on success, or -1 if a file + * descriptor was not actually included in the message + * + * 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; + + struct iovec iov = { + .iov_base = &iovbuf, + .iov_len = 1, + }; + + char cmsgbuf[CMSG_SPACE(sizeof(int))]; + + struct msghdr msg = { + .msg_iov = &iov, + .msg_iovlen = 1, + .msg_control = cmsgbuf, + .msg_controllen = sizeof(cmsgbuf), + }; + + 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; + } + + 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) { +error: + LOGE("unable to read fd"); + exit(-1); + } + + return *(int *)CMSG_DATA(cmsg); +} + +/* + * Send a file descriptor through a Unix socket. + * Contributed by @mkasick + * + * On error the function terminates by calling exit(-1) + * + * fd may be -1, in which case the dummy data is sent, + * 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, + }; + + struct msghdr msg = { + .msg_iov = &iov, + .msg_iovlen = 1, + }; + + 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); + + struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); + + cmsg->cmsg_len = CMSG_LEN(sizeof(int)); + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_RIGHTS; + + *(int *)CMSG_DATA(cmsg) = fd; + } + } + + xsendmsg(sockfd, &msg, 0); +} + +int read_int(int fd) { + 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)); +} + +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; +} + +void write_string(int fd, const char* val) { + if (fd < 0) return; + int len = strlen(val); + write_int(fd, len); + xwrite(fd, val, len); +} diff --git a/jni/core/magisk.c b/jni/core/magisk.c index ab824cbb3..87244d8e6 100644 --- a/jni/core/magisk.c +++ b/jni/core/magisk.c @@ -45,7 +45,7 @@ static void usage() { " -v print running daemon version\n" " -V print running daemon version code\n" " --list list all availible applets\n" - " --install [SOURCE] DIR symlink all applets to DIR. SOURCE is optional\n" + " --install [SOURCE] DIR symlink all applets to DIR. SOURCE is optional\n" " --createimg IMG SIZE create ext4 image. SIZE is interpreted in MB\n" " --imgsize IMG report ext4 image used/total size\n" " --resizeimg IMG SIZE resize ext4 image. SIZE is interpreted in MB\n" diff --git a/jni/core/socket_trans.c b/jni/core/socket_trans.c deleted file mode 100644 index f057d64f3..000000000 --- a/jni/core/socket_trans.c +++ /dev/null @@ -1,148 +0,0 @@ -/* socket_trans.c - Functions to transfer data through socket - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "magisk.h" -#include "utils.h" -#include "daemon.h" - -/* - * Receive a file descriptor from a Unix socket. - * Contributed by @mkasick - * - * Returns the file descriptor on success, or -1 if a file - * descriptor was not actually included in the message - * - * 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; - - struct iovec iov = { - .iov_base = &iovbuf, - .iov_len = 1, - }; - - char cmsgbuf[CMSG_SPACE(sizeof(int))]; - - struct msghdr msg = { - .msg_iov = &iov, - .msg_iovlen = 1, - .msg_control = cmsgbuf, - .msg_controllen = sizeof(cmsgbuf), - }; - - 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; - } - - 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) { -error: - LOGE("unable to read fd"); - exit(-1); - } - - return *(int *)CMSG_DATA(cmsg); -} - -/* - * Send a file descriptor through a Unix socket. - * Contributed by @mkasick - * - * On error the function terminates by calling exit(-1) - * - * fd may be -1, in which case the dummy data is sent, - * 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, - }; - - struct msghdr msg = { - .msg_iov = &iov, - .msg_iovlen = 1, - }; - - 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); - - struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); - - cmsg->cmsg_len = CMSG_LEN(sizeof(int)); - cmsg->cmsg_level = SOL_SOCKET; - cmsg->cmsg_type = SCM_RIGHTS; - - *(int *)CMSG_DATA(cmsg) = fd; - } - } - - xsendmsg(sockfd, &msg, 0); -} - -int read_int(int fd) { - 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)); -} - -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; -} - -void write_string(int fd, const char* val) { - if (fd < 0) return; - int len = strlen(val); - write_int(fd, len); - xwrite(fd, val, len); -} diff --git a/jni/include/daemon.h b/jni/include/daemon.h index ab5cea0d3..6f6685b4a 100644 --- a/jni/include/daemon.h +++ b/jni/include/daemon.h @@ -42,9 +42,6 @@ typedef enum { void start_daemon(); int connect_daemon(); void auto_start_magiskhide(); - -// socket_trans.c - int recv_fd(int sockfd); void send_fd(int sockfd, int fd); int read_int(int fd); diff --git a/jni/include/utils.h b/jni/include/utils.h index 69963840b..8f1f4304f 100644 --- a/jni/include/utils.h +++ b/jni/include/utils.h @@ -85,7 +85,6 @@ void setup_sighandlers(void (*handler)(int)); int exec_command(int err, int *fd, void (*setupenv)(struct vector*), const char *argv0, ...); int exec_command_sync(char *const argv0, ...); int bind_mount(const char *from, const char *to); -int open_new(const char *filename); void get_client_cred(int fd, struct ucred *cred); int switch_mnt_ns(int pid); int fork_dont_care(); @@ -118,6 +117,9 @@ void clone_attr(const char *source, const char *target); void restorecon(int dirfd, int force); void mmap_ro(const char *filename, void **buf, size_t *size); void mmap_rw(const char *filename, void **buf, size_t *size); +void write_zero(int fd, size_t size); +void mem_align(size_t *pos, size_t align); +void file_align(int fd, size_t align, int out); // img.c diff --git a/jni/magiskboot/boot_utils.c b/jni/magiskboot/boot_utils.c deleted file mode 100644 index f01cb4b64..000000000 --- a/jni/magiskboot/boot_utils.c +++ /dev/null @@ -1,56 +0,0 @@ -#include -#include - -#include "utils.h" - -void write_zero(int fd, size_t size) { - size_t pos = lseek(fd, 0, SEEK_CUR); - ftruncate(fd, pos + size); - lseek(fd, pos + size, SEEK_SET); -} - -void mem_align(size_t *pos, size_t align) { - size_t mask = align - 1; - if (*pos & mask) { - *pos += align - (*pos & mask); - } -} - -void file_align(int fd, size_t align, int out) { - size_t pos = lseek(fd, 0, SEEK_CUR); - size_t mask = align - 1; - size_t off; - if (pos & mask) { - off = align - (pos & mask); - if (out) { - write_zero(fd, off); - } else { - lseek(fd, pos + off, SEEK_SET); - } - } -} - -int open_new(const char *filename) { - return xopen(filename, O_WRONLY | O_CREAT | O_TRUNC, 0644); -} - -int check_verity_pattern(const char *s) { - int pos = 0; - if (s[0] == ',') ++pos; - if (strncmp(s + pos, "verify", 6) != 0) return -1; - pos += 6; - if (s[pos] == '=') { - while (s[pos] != '\0' && s[pos] != ' ' && s[pos] != '\n' && s[pos] != ',') ++pos; - } - return pos; -} - -int check_encryption_pattern(const char *s) { - const char *encrypt_list[] = { "forceencrypt", "forcefdeorfbe", NULL }; - for (int i = 0 ; encrypt_list[i]; ++i) { - int len = strlen(encrypt_list[i]); - if (strncmp(s, encrypt_list[i], len) == 0) - return len; - } - return -1; -} diff --git a/jni/magiskboot/bootimg.c b/jni/magiskboot/bootimg.c index 138384236..0a367f7f6 100644 --- a/jni/magiskboot/bootimg.c +++ b/jni/magiskboot/bootimg.c @@ -1,5 +1,6 @@ #include #include +#include #include #include "bootimg.h" @@ -8,7 +9,7 @@ #include "logging.h" static void dump(void *buf, size_t size, const char *filename) { - int fd = open_new(filename); + int fd = creat(filename, 0644); xwrite(fd, buf, size); close(fd); } @@ -160,7 +161,7 @@ void unpack(const char* image) { // Dump kernel if (COMPRESSED(boot.kernel_type)) { - fd = open_new(KERNEL_FILE); + fd = creat(KERNEL_FILE, 0644); decomp(boot.kernel_type, fd, boot.kernel, boot.hdr.kernel_size); close(fd); } else { @@ -174,7 +175,7 @@ void unpack(const char* image) { // Dump ramdisk if (COMPRESSED(boot.ramdisk_type)) { - fd = open_new(RAMDISK_FILE); + fd = creat(RAMDISK_FILE, 0644); decomp(boot.ramdisk_type, fd, boot.ramdisk, boot.hdr.ramdisk_size); close(fd); } else { @@ -214,7 +215,7 @@ void repack(const char* orig_image, const char* out_image) { fprintf(stderr, "Repack to boot image: [%s]\n\n", out_image); // Create new image - int fd = open_new(out_image); + int fd = creat(out_image, 0644); // Skip a page for header write_zero(fd, boot.hdr.page_size); diff --git a/jni/magiskboot/compress.c b/jni/magiskboot/compress.c index ff65025df..0674e1a35 100644 --- a/jni/magiskboot/compress.c +++ b/jni/magiskboot/compress.c @@ -1,4 +1,5 @@ #include +#include #include #include @@ -472,7 +473,7 @@ void decomp_file(char *from, const char *to) { *ext = '\0'; to = from; } - int fd = open_new(to); + int fd = creat(to, 0644); fprintf(stderr, "Decompressing to [%s]\n\n", to); decomp(type, fd, file, size); close(fd); @@ -522,7 +523,7 @@ void comp_file(const char *method, const char *from, const char *to) { else strcpy(dest, to); fprintf(stderr, "Compressing to [%s]\n\n", dest); - int fd = open_new(dest); + int fd = creat(dest, 0644); comp(type, fd, file, size); close(fd); munmap(file, size); diff --git a/jni/magiskboot/cpio.c b/jni/magiskboot/cpio.c index f302ba29b..348ce8a23 100644 --- a/jni/magiskboot/cpio.c +++ b/jni/magiskboot/cpio.c @@ -1,5 +1,6 @@ #include #include +#include #include "magiskboot.h" #include "cpio.h" @@ -91,7 +92,7 @@ static void parse_cpio(const char *filename, struct vector *v) { static void dump_cpio(const char *filename, struct vector *v) { fprintf(stderr, "\nDump cpio: [%s]\n\n", filename); - int fd = open_new(filename); + int fd = creat(filename, 0644); unsigned inode = 300000; char header[111]; // Sort by name @@ -204,6 +205,27 @@ static void cpio_test(struct vector *v) { exit(ret); } +int check_verity_pattern(const char *s) { + int pos = 0; + if (s[0] == ',') ++pos; + if (strncmp(s + pos, "verify", 6) != 0) return -1; + pos += 6; + if (s[pos] == '=') { + while (s[pos] != '\0' && s[pos] != ' ' && s[pos] != '\n' && s[pos] != ',') ++pos; + } + return pos; +} + +int check_encryption_pattern(const char *s) { + const char *encrypt_list[] = { "forceencrypt", "forcefdeorfbe", NULL }; + for (int i = 0 ; encrypt_list[i]; ++i) { + int len = strlen(encrypt_list[i]); + if (strncmp(s, encrypt_list[i], len) == 0) + return len; + } + return -1; +} + static void cpio_patch(struct vector *v, int keepverity, int keepforceencrypt) { cpio_entry *f; int skip, write; @@ -248,7 +270,7 @@ static void cpio_extract(const char *entry, const char *filename, struct vector vec_for_each(v, f) { if (strcmp(f->filename, entry) == 0 && S_ISREG(f->mode)) { fprintf(stderr, "Extracting [%s] to [%s]\n\n", entry, filename); - int fd = open_new(filename); + int fd = creat(filename, 0644); xwrite(fd, f->data, f->filesize); fchmod(fd, f->mode); fchown(fd, f->uid, f->gid); diff --git a/jni/magiskboot/dtb.c b/jni/magiskboot/dtb.c index 2251c6b3c..6f5ebfbf1 100644 --- a/jni/magiskboot/dtb.c +++ b/jni/magiskboot/dtb.c @@ -5,6 +5,8 @@ #include "magiskboot.h" #include "utils.h" +extern int check_verity_pattern(const char *s); + static void print_subnode(const void *fdt, int parent, int depth) { int node; fdt_for_each_subnode(node, fdt, parent) { diff --git a/jni/magiskboot/magiskboot.h b/jni/magiskboot/magiskboot.h index c34aedd6f..0a1889064 100644 --- a/jni/magiskboot/magiskboot.h +++ b/jni/magiskboot/magiskboot.h @@ -33,12 +33,4 @@ size_t lz4_legacy(int mode, int fd, const void *buf, size_t size); long long comp(file_t type, int to, const void *from, size_t size); long long decomp(file_t type, int to, const void *from, size_t size); -// Utils -extern void write_zero(int fd, size_t size); -extern void mem_align(size_t *pos, size_t align); -extern void file_align(int fd, size_t align, int out); -extern int open_new(const char *filename); -extern int check_verity_pattern(const char *s); -extern int check_encryption_pattern(const char *s); - #endif diff --git a/jni/resetprop/Android.mk b/jni/resetprop/Android.mk deleted file mode 100644 index 526a20bf0..000000000 --- a/jni/resetprop/Android.mk +++ /dev/null @@ -1,8 +0,0 @@ -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) -LOCAL_MODULE := resetprop -LOCAL_SRC_FILES := resetprop.cpp system_properties.cpp libc_logging.cpp -LOCAL_LDLIBS += -latomic -LOCAL_CFLAGS := -Wno-implicit-exception-spec-mismatch -DINDEP_BINARY -include $(BUILD_EXECUTABLE) diff --git a/jni/utils/file.c b/jni/utils/file.c index 7dab09b7c..009bea50a 100644 --- a/jni/utils/file.c +++ b/jni/utils/file.c @@ -297,22 +297,6 @@ void fclone_attr(const int sourcefd, const int targetfd) { fsetattr(targetfd, &a); } -void mmap_ro(const char *filename, void **buf, size_t *size) { - int fd = xopen(filename, O_RDONLY); - *size = lseek(fd, 0, SEEK_END); - lseek(fd, 0, SEEK_SET); - *buf = *size > 0 ? xmmap(NULL, *size, PROT_READ, MAP_SHARED, fd, 0) : NULL; - close(fd); -} - -void mmap_rw(const char *filename, void **buf, size_t *size) { - int fd = xopen(filename, O_RDWR); - *size = lseek(fd, 0, SEEK_END); - lseek(fd, 0, SEEK_SET); - *buf = *size > 0 ? xmmap(NULL, *size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0) : NULL; - close(fd); -} - #ifndef NO_SELINUX #define UNLABEL_CON "u:object_r:unlabeled:s0" @@ -350,3 +334,46 @@ void restorecon(int dirfd, int force) { } #endif // NO_SELINUX + +void mmap_ro(const char *filename, void **buf, size_t *size) { + int fd = xopen(filename, O_RDONLY); + *size = lseek(fd, 0, SEEK_END); + lseek(fd, 0, SEEK_SET); + *buf = *size > 0 ? xmmap(NULL, *size, PROT_READ, MAP_SHARED, fd, 0) : NULL; + close(fd); +} + +void mmap_rw(const char *filename, void **buf, size_t *size) { + int fd = xopen(filename, O_RDWR); + *size = lseek(fd, 0, SEEK_END); + lseek(fd, 0, SEEK_SET); + *buf = *size > 0 ? xmmap(NULL, *size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0) : NULL; + close(fd); +} + +void write_zero(int fd, size_t size) { + size_t pos = lseek(fd, 0, SEEK_CUR); + ftruncate(fd, pos + size); + lseek(fd, pos + size, SEEK_SET); +} + +void mem_align(size_t *pos, size_t align) { + size_t mask = align - 1; + if (*pos & mask) { + *pos += align - (*pos & mask); + } +} + +void file_align(int fd, size_t align, int out) { + size_t pos = lseek(fd, 0, SEEK_CUR); + size_t mask = align - 1; + size_t off; + if (pos & mask) { + off = align - (pos & mask); + if (out) { + write_zero(fd, off); + } else { + lseek(fd, pos + off, SEEK_SET); + } + } +} diff --git a/jni/utils/misc.c b/jni/utils/misc.c index 8840db55c..7dc18010b 100644 --- a/jni/utils/misc.c +++ b/jni/utils/misc.c @@ -283,10 +283,6 @@ int bind_mount(const char *from, const char *to) { return ret; } -int open_new(const char *filename) { - return xopen(filename, O_WRONLY | O_CREAT | O_TRUNC, 0644); -} - void get_client_cred(int fd, struct ucred *cred) { socklen_t ucred_length = sizeof(*cred); if(getsockopt(fd, SOL_SOCKET, SO_PEERCRED, cred, &ucred_length))