Commit e7108483 authored by topjohnwu's avatar topjohnwu

Unify Magisk configuration

Introduce monogisk tool
parent 8d6f3c24
out/
obj/ obj/
libs/ libs/
*.zip *.zip
......
This diff is collapsed.
Subproject commit fdd700f3e5c2f9d7688d2434d4dbee8c12524411 Subproject commit 99c74b31be15a239fdffe4a727d2d83feb52b8bb
...@@ -14,17 +14,17 @@ LIBFDT := $(EXT_PATH)/dtc/libfdt ...@@ -14,17 +14,17 @@ LIBFDT := $(EXT_PATH)/dtc/libfdt
# Binaries # Binaries
######################## ########################
ifdef PRECOMPILE
# magisk main binary # magisk main binary
include $(CLEAR_VARS) include $(CLEAR_VARS)
LOCAL_MODULE := magisk LOCAL_MODULE := magisk
LOCAL_STATIC_LIBRARIES := libsepol
LOCAL_SHARED_LIBRARIES := libsqlite libselinux LOCAL_SHARED_LIBRARIES := libsqlite libselinux
LOCAL_C_INCLUDES := \ LOCAL_C_INCLUDES := \
jni/include \ jni/include \
jni/external \ jni/external \
$(LIBSELINUX) \ $(LIBSELINUX)
$(LIBSEPOL)
LOCAL_SRC_FILES := \ LOCAL_SRC_FILES := \
daemon/magisk.c \ daemon/magisk.c \
...@@ -41,10 +41,6 @@ LOCAL_SRC_FILES := \ ...@@ -41,10 +41,6 @@ LOCAL_SRC_FILES := \
magiskhide/magiskhide.c \ magiskhide/magiskhide.c \
magiskhide/proc_monitor.c \ magiskhide/proc_monitor.c \
magiskhide/hide_utils.c \ magiskhide/hide_utils.c \
magiskpolicy/magiskpolicy.c \
magiskpolicy/rules.c \
magiskpolicy/sepolicy.c \
magiskpolicy/api.c \
resetprop/resetprop.cpp \ resetprop/resetprop.cpp \
resetprop/system_properties.cpp \ resetprop/system_properties.cpp \
su/su.c \ su/su.c \
...@@ -59,6 +55,37 @@ LOCAL_CPPFLAGS := -std=c++11 ...@@ -59,6 +55,37 @@ LOCAL_CPPFLAGS := -std=c++11
LOCAL_LDLIBS := -llog LOCAL_LDLIBS := -llog
include $(BUILD_EXECUTABLE) include $(BUILD_EXECUTABLE)
# magiskinit
include $(CLEAR_VARS)
LOCAL_MODULE := magiskinit
LOCAL_STATIC_LIBRARIES := libsepol
LOCAL_C_INCLUDES := jni/include $(LIBSEPOL)
LOCAL_SRC_FILES := \
init/magiskinit.c \
utils/vector.c \
utils/file.c \
utils/xwrap.c \
magiskpolicy/api.c \
magiskpolicy/magiskpolicy.c \
magiskpolicy/rules.c \
magiskpolicy/sepolicy.c
LOCAL_CFLAGS := -DNO_SELINUX
LOCAL_LDFLAGS := -static
include $(BUILD_EXECUTABLE)
# precompile
else
# monogisk
include $(CLEAR_VARS)
LOCAL_MODULE := monogisk
LOCAL_STATIC_LIBRARIES := liblzma
LOCAL_C_INCLUDES := jni/include out/$(TARGET_ARCH_ABI) $(LIBLZMA)
LOCAL_SRC_FILES := init/monogisk.c
LOCAL_LDFLAGS := -static
include $(BUILD_EXECUTABLE)
# magiskboot # magiskboot
include $(CLEAR_VARS) include $(CLEAR_VARS)
LOCAL_MODULE := magiskboot LOCAL_MODULE := magiskboot
...@@ -81,28 +108,12 @@ LOCAL_SRC_FILES := \ ...@@ -81,28 +108,12 @@ LOCAL_SRC_FILES := \
magiskboot/types.c \ magiskboot/types.c \
magiskboot/dtb.c \ magiskboot/dtb.c \
utils/xwrap.c \ utils/xwrap.c \
utils/file.c \
utils/vector.c utils/vector.c
LOCAL_LDLIBS := -lz
include $(BUILD_EXECUTABLE)
# magiskinit
ifeq ($(TARGET_ARCH_ABI), arm64-v8a)
include $(CLEAR_VARS)
LOCAL_MODULE := magiskinit
LOCAL_STATIC_LIBRARIES := libsepol
LOCAL_C_INCLUDES := jni/include $(LIBSEPOL)
LOCAL_SRC_FILES := \
magiskinit.c \
magiskboot/boot_utils.c \
utils/file.c \
utils/xwrap.c \
magiskpolicy/rules.c \
magiskpolicy/sepolicy.c \
magiskpolicy/api.c
LOCAL_CFLAGS := -DNO_SELINUX LOCAL_CFLAGS := -DNO_SELINUX
LOCAL_LDFLAGS := -static LOCAL_LDLIBS := -lz
include $(BUILD_EXECUTABLE) include $(BUILD_EXECUTABLE)
endif
# 32-bit static binaries # 32-bit static binaries
ifneq ($(TARGET_ARCH_ABI), x86_64) ifneq ($(TARGET_ARCH_ABI), x86_64)
...@@ -120,6 +131,9 @@ include jni/external/busybox/Android.mk ...@@ -120,6 +131,9 @@ include jni/external/busybox/Android.mk
endif endif
endif endif
# Precompile
endif
######################## ########################
# Externals # Externals
######################## ########################
......
...@@ -568,7 +568,7 @@ void fix_filecon() { ...@@ -568,7 +568,7 @@ void fix_filecon() {
****************/ ****************/
static void unblock_boot_process() { static void unblock_boot_process() {
close(xopen(UNBLOCKFILE, O_RDONLY | O_CREAT)); close(xopen(UNBLOCKFILE, O_RDONLY | O_CREAT, 0));
pthread_exit(NULL); pthread_exit(NULL);
} }
...@@ -743,7 +743,8 @@ void late_start(int client) { ...@@ -743,7 +743,8 @@ void late_start(int client) {
if (buf2 == NULL) buf2 = xmalloc(PATH_MAX); if (buf2 == NULL) buf2 = xmalloc(PATH_MAX);
// Wait till the full patch is done // Wait till the full patch is done
pthread_join(sepol_patch, NULL); while (access(PATCHDONE, F_OK) == -1)
usleep(500); /* Wait 0.5ms */
// Run scripts after full patch, most reliable way to run scripts // Run scripts after full patch, most reliable way to run scripts
LOGI("* Running service.d scripts\n"); LOGI("* Running service.d scripts\n");
......
...@@ -103,16 +103,6 @@ static int setup_socket(struct sockaddr_un *sun) { ...@@ -103,16 +103,6 @@ static int setup_socket(struct sockaddr_un *sun) {
return fd; return fd;
} }
static void *large_sepol_patch(void *args) {
LOGD("sepol: Starting large patch thread\n");
// Patch su to everything
sepol_allow("su", ALL, ALL, ALL);
dump_policydb(SELINUX_LOAD);
LOGD("sepol: Large patch done\n");
destroy_policydb();
return NULL;
}
static void *start_magisk_hide(void *args) { static void *start_magisk_hide(void *args) {
launch_magiskhide(-1); launch_magiskhide(-1);
return NULL; return NULL;
...@@ -137,11 +127,6 @@ void start_daemon() { ...@@ -137,11 +127,6 @@ void start_daemon() {
xdup2(fd, STDERR_FILENO); xdup2(fd, STDERR_FILENO);
close(fd); close(fd);
// Patch selinux with medium patch before we do anything
load_policydb(SELINUX_POLICY);
sepol_med_rules();
dump_policydb(SELINUX_LOAD);
struct sockaddr_un sun; struct sockaddr_un sun;
fd = setup_socket(&sun); fd = setup_socket(&sun);
...@@ -159,9 +144,6 @@ void start_daemon() { ...@@ -159,9 +144,6 @@ void start_daemon() {
// Start the log monitor // Start the log monitor
monitor_logs(); monitor_logs();
// Continue the larger patch in another thread, we will join later
xpthread_create(&sepol_patch, NULL, large_sepol_patch, NULL);
LOGI("Magisk v" xstr(MAGISK_VERSION) "(" xstr(MAGISK_VER_CODE) ") daemon started\n"); LOGI("Magisk v" xstr(MAGISK_VERSION) "(" xstr(MAGISK_VER_CODE) ") daemon started\n");
// Change process name // Change process name
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <unistd.h> #include <unistd.h>
#include <libgen.h>
#include "utils.h" #include "utils.h"
#include "magisk.h" #include "magisk.h"
...@@ -12,10 +13,10 @@ ...@@ -12,10 +13,10 @@
char *argv0; char *argv0;
char *applet[] = char *applet[] =
{ "su", "resetprop", "magiskpolicy", "supolicy", "magiskhide", NULL }; { "su", "resetprop", "magiskhide", NULL };
int (*applet_main[]) (int, char *[]) = int (*applet_main[]) (int, char *[]) =
{ su_client_main, resetprop_main, magiskpolicy_main, magiskpolicy_main, magiskhide_main, NULL }; { su_client_main, resetprop_main, magiskhide_main, NULL };
int create_links(const char *bin, const char *path) { int create_links(const char *bin, const char *path) {
char self[PATH_MAX], linkpath[PATH_MAX]; char self[PATH_MAX], linkpath[PATH_MAX];
...@@ -56,7 +57,7 @@ static void usage() { ...@@ -56,7 +57,7 @@ static void usage() {
" --clone-attr SRC DEST clone permission, owner, and selinux context\n" " --clone-attr SRC DEST clone permission, owner, and selinux context\n"
"\n" "\n"
"Supported init services:\n" "Supported init services:\n"
" daemon post-fs, post-fs-data, service\n" " daemon, post-fs, post-fs-data, service\n"
"\n" "\n"
"Supported applets:\n" "Supported applets:\n"
, argv0, argv0); , argv0, argv0);
...@@ -69,10 +70,7 @@ static void usage() { ...@@ -69,10 +70,7 @@ static void usage() {
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
argv0 = argv[0]; argv0 = argv[0];
char * arg = strrchr(argv[0], '/'); if (strcmp(basename(argv[0]), "magisk") == 0) {
if (arg) ++arg;
else arg = argv[0];
if (strcmp(arg, "magisk") == 0) {
if (argc < 2) usage(); if (argc < 2) usage();
if (strcmp(argv[1], "-c") == 0) { if (strcmp(argv[1], "-c") == 0) {
printf("%s\n", MAGISK_VER_STR); printf("%s\n", MAGISK_VER_STR);
...@@ -168,16 +166,15 @@ int main(int argc, char *argv[]) { ...@@ -168,16 +166,15 @@ int main(int argc, char *argv[]) {
// It's calling applets // It's calling applets
--argc; --argc;
++argv; ++argv;
arg = argv[0];
} }
} }
// Applets // Applets
for (int i = 0; applet[i]; ++i) { for (int i = 0; applet[i]; ++i) {
if (strcmp(arg, applet[i]) == 0) if (strcmp(basename(argv[0]), applet[i]) == 0)
return (*applet_main[i])(argc, argv); return (*applet_main[i])(argc, argv);
} }
fprintf(stderr, "%s: applet not found\n", arg); fprintf(stderr, "%s: applet not found\n", basename(argv[0]));
return 1; return 1;
} }
...@@ -8,6 +8,9 @@ ...@@ -8,6 +8,9 @@
#include <errno.h> #include <errno.h>
#include <stdlib.h> #include <stdlib.h>
#define str(a) #a
#define xstr(a) str(a)
#ifdef IS_DAEMON #ifdef IS_DAEMON
#include <pthread.h> #include <pthread.h>
......
...@@ -6,9 +6,6 @@ ...@@ -6,9 +6,6 @@
#include "logging.h" #include "logging.h"
#define str(a) #a
#define xstr(a) str(a)
#define MAGISK_VER_STR xstr(MAGISK_VERSION) ":MAGISK" #define MAGISK_VER_STR xstr(MAGISK_VERSION) ":MAGISK"
#define REQUESTOR_DAEMON_PATH "\0MAGISK" #define REQUESTOR_DAEMON_PATH "\0MAGISK"
...@@ -20,6 +17,7 @@ ...@@ -20,6 +17,7 @@
#define LASTLOG "/cache/last_magisk.log" #define LASTLOG "/cache/last_magisk.log"
#define DEBUG_LOG "/data/magisk_debug.log" #define DEBUG_LOG "/data/magisk_debug.log"
#define UNBLOCKFILE "/dev/.magisk.unblock" #define UNBLOCKFILE "/dev/.magisk.unblock"
#define PATCHDONE "/dev/.magisk.patch.done"
#define DISABLEFILE "/cache/.disable_magisk" #define DISABLEFILE "/cache/.disable_magisk"
#define UNINSTALLER "/cache/magisk_uninstaller.sh" #define UNINSTALLER "/cache/magisk_uninstaller.sh"
#define CACHEMOUNT "/cache/magisk_mount" #define CACHEMOUNT "/cache/magisk_mount"
......
const char magiskrc[] =
// Triggers
"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"
"on post-fs-data\n"
" load_persist_props\n"
" rm /dev/.magisk.unblock\n"
" start magisk_pfsd\n"
" wait /dev/.magisk.unblock 10\n"
"\n"
// Services
"service magisk_daemon /sbin/magisk --daemon\n"
" user root\n"
" seclabel u:r:su:s0\n"
"\n"
"service magisk_pfs /sbin/magisk --post-fs\n"
" user root\n"
" seclabel u:r:su:s0\n"
" oneshot\n"
"\n"
"service magisk_pfsd /sbin/magisk --post-fs-data\n"
" user root\n"
" seclabel u:r:su:s0\n"
" oneshot\n"
"\n"
"service magisk_service /sbin/magisk --service\n"
" class late_start\n"
" user root\n"
" seclabel u:r:su:s0\n"
" oneshot\n"
;
...@@ -116,6 +116,8 @@ int fsetattr(int fd, struct file_attr *a); ...@@ -116,6 +116,8 @@ int fsetattr(int fd, struct file_attr *a);
void fclone_attr(const int sourcefd, const int targetfd); void fclone_attr(const int sourcefd, const int targetfd);
void clone_attr(const char *source, const char *target); void clone_attr(const char *source, const char *target);
void restorecon(int dirfd, int force); 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);
// img.c // img.c
......
This diff is collapsed.
/* monogisk.c - Monolithic binary hosting Magisk binaries
*
* This code has to be compiled statically to work properly.
*
* To unify Magisk support for both legacy "normal" devices and new skip_initramfs devices,
* this tool is born. Magisk binary compilation is split into two parts - first part contains
* "magisk" and "magiskinit". The python build script will load these 2 binaries and compress
* them with lzma2, dumping the results into "dump.h". Monogisk is simply just a static lzma
* extractor embedded with binary blobs, with a few additional operations to construct an
* environment for "magiskinit" to handle the rest of the work.
*/
#include <fcntl.h>
#include <unistd.h>
#include <lzma.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include "dump.h"
#include "magiskrc.h"
#define str(a) #a
#define xstr(a) str(a)
#define BUFSIZE 0x100000
lzma_stream strm = LZMA_STREAM_INIT;
static void usage() {
const char usage[] =
"Monogisk v" xstr(MAGISK_VERSION) "(" xstr(MAGISK_VER_CODE) ") (by topjohnwu)\n"
"A monolithic binary used as /init to add Magisk support\n"
"\n"
"Usage:\n"
" monogisk -x <binary> <out>\n"
" extract \"magisk\", \"magiskinit\", or \"magiskrc\"\n"
" /init\n"
" Startup the system with Magisk support\n"
"\n";
write(STDERR_FILENO, usage, sizeof(usage));
exit(1);
}
static int unxz(lzma_stream *strm, const void *buf, size_t size, int fd) {
lzma_ret ret = 0;
uint8_t out[BUFSIZE];
strm->next_in = buf;
strm->avail_in = size;
do {
strm->next_out = out;
strm->avail_out = sizeof(out);
ret = lzma_code(strm, LZMA_RUN);
write(fd, out, sizeof(out) - strm->avail_out);
} while (strm->avail_out == 0 && ret == LZMA_OK);
if (ret != LZMA_OK && ret != LZMA_STREAM_END)
write(STDERR_FILENO, "LZMA error!\n", 13);
return ret;
}
static int dump_magisk(const char *path, mode_t mode) {
if (lzma_auto_decoder(&strm, UINT64_MAX, 0) != LZMA_OK)
return 1;
unlink(path);
int fd = creat(path, mode);
int ret = unxz(&strm, magisk_dump, sizeof(magisk_dump), fd);
close(fd);
return ret;
}
static int dump_magiskinit(const char *path, mode_t mode) {
if (lzma_auto_decoder(&strm, UINT64_MAX, 0) != LZMA_OK)
return 1;
unlink(path);
int fd = creat(path, mode);
int ret = unxz(&strm, magiskinit_dump, sizeof(magiskinit_dump), fd);
close(fd);
return ret;
}
static int dump_magiskrc(const char *path, mode_t mode) {
unlink(path);
int fd = creat(path, mode);
write(fd, magiskrc, sizeof(magiskrc));
close(fd);
return 0;
}
static int init_main(int argc, char *argv[]) {
dump_magiskinit("/init", 0750);
mkdir("/overlay", 0);
dump_magiskrc("/overlay/init.magisk.rc", 0750);
mkdir("/overlay/sbin", 0755);
dump_magisk("/overlay/sbin/magisk", 0755);
mkdir("/overlay/root", 0755);
link("/init", "/overlay/root/magiskpolicy");
link("/init", "/overlay/root/supolicy");
execv("/init", argv);
return 1; /* Should not happen */
}
int main(int argc, char *argv[]) {
umask(0);
if (argc == 1)
return init_main(argc, argv);
if (argc < 4)
usage();
if (strcmp(argv[2], "magisk") == 0)
dump_magisk(argv[3], 0755);
else if (strcmp(argv[2], "magiskinit") == 0)
dump_magiskinit(argv[3], 0755);
else
usage();
lzma_end(&strm);
return 0;
}
#include <unistd.h> #include <unistd.h>
#include <stdio.h> #include <stdio.h>
#include <sys/mman.h>
#include "utils.h" #include "utils.h"
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) { void write_zero(int fd, size_t size) {
size_t pos = lseek(fd, 0, SEEK_CUR); size_t pos = lseek(fd, 0, SEEK_CUR);
ftruncate(fd, pos + size); ftruncate(fd, pos + size);
...@@ -51,35 +34,6 @@ int open_new(const char *filename) { ...@@ -51,35 +34,6 @@ int open_new(const char *filename) {
return xopen(filename, O_WRONLY | O_CREAT | O_TRUNC, 0644); return xopen(filename, O_WRONLY | O_CREAT | O_TRUNC, 0644);
} }
void *patch_init_rc(char *data, uint32_t *size) {
int injected = 0;
char *new_data = xmalloc(*size + 23);
char *old_data = data;
uint32_t pos = 0;
for (char *tok = strsep(&old_data, "\n"); tok; tok = strsep(&old_data, "\n")) {
if (!injected && strncmp(tok, "import", 6) == 0) {
if (strstr(tok, "init.magisk.rc")) {
injected = 1;
} else {
fprintf(stderr, "Inject [import /init.magisk.rc] to [init.rc]\n");
strcpy(new_data + pos, "import /init.magisk.rc\n");
pos += 23;
injected = 1;
}
} else if (strstr(tok, "selinux.reload_policy")) {
continue;
}
// Copy the line
strcpy(new_data + pos, tok);
pos += strlen(tok);
new_data[pos++] = '\n';
}
*size = pos;
return new_data;
}
int check_verity_pattern(const char *s) { int check_verity_pattern(const char *s) {
int pos = 0; int pos = 0;
if (s[0] == ',') ++pos; if (s[0] == ',') ++pos;
......
...@@ -186,7 +186,7 @@ static void cpio_test(struct vector *v) { ...@@ -186,7 +186,7 @@ static void cpio_test(struct vector *v) {
int ret = STOCK_BOOT; int ret = STOCK_BOOT;
cpio_entry *f; cpio_entry *f;
const char *OTHER_LIST[] = { "sbin/launch_daemonsu.sh", "sbin/su", "init.xposed.rc", "boot/sbin/launch_daemonsu.sh", NULL }; const char *OTHER_LIST[] = { "sbin/launch_daemonsu.sh", "sbin/su", "init.xposed.rc", "boot/sbin/launch_daemonsu.sh", NULL };
const char *MAGISK_LIST[] = { "init.magisk.rc", "overlay/init.magisk.rc", NULL }; const char *MAGISK_LIST[] = { ".backup/.magisk", "init.magisk.rc", "overlay/init.magisk.rc", NULL };
vec_for_each(v, f) { vec_for_each(v, f) {
for (int i = 0; OTHER_LIST[i]; ++i) { for (int i = 0; OTHER_LIST[i]; ++i) {
if (strcmp(f->filename, OTHER_LIST[i]) == 0) { if (strcmp(f->filename, OTHER_LIST[i]) == 0) {
...@@ -208,42 +208,36 @@ static void cpio_patch(struct vector *v, int keepverity, int keepforceencrypt) { ...@@ -208,42 +208,36 @@ static void cpio_patch(struct vector *v, int keepverity, int keepforceencrypt) {
cpio_entry *f; cpio_entry *f;
int skip, write; int skip, write;
vec_for_each(v, f) { vec_for_each(v, f) {
if (strcmp(f->filename, "init.rc") == 0) { if (!keepverity) {
void *new_data = patch_init_rc(f->data, &f->filesize); if (strstr(f->filename, "fstab") != NULL && S_ISREG(f->mode)) {
free(f->data); write = 0;
f->data = new_data; for (int read = 0; read < f->filesize; ++write, ++read) {
} else { if ((skip = check_verity_pattern(f->data + read)) > 0) {
if (!keepverity) { fprintf(stderr, "Remove pattern [%.*s] in [%s]\n", skip, f->data + read, f->filename);
if (strstr(f->filename, "fstab") != NULL && S_ISREG(f->mode)) { read += skip;
write = 0;
for (int read = 0; read < f->filesize; ++write, ++read) {
if ((skip = check_verity_pattern(f->data + read)) > 0) {
fprintf(stderr, "Remove pattern [%.*s] in [%s]\n", skip, f->data + read, f->filename);
read += skip;
}
f->data[write] = f->data[read];
} }
f->filesize = write; f->data[write] = f->data[read];
} else if (strcmp(f->filename, "verity_key") == 0) {
fprintf(stderr, "Remove [verity_key]\n");
f->remove = 1;
} }
f->filesize = write;
} else if (strcmp(f->filename, "verity_key") == 0) {
fprintf(stderr, "Remove [verity_key]\n");
f->remove = 1;
} }
if (!keepforceencrypt) { }
if (strstr(f->filename, "fstab") != NULL && S_ISREG(f->mode)) { if (!keepforceencrypt) {
write = 0; if (strstr(f->filename, "fstab") != NULL && S_ISREG(f->mode)) {
for (int read = 0; read < f->filesize; ++write, ++read) { write = 0;
if ((skip = check_encryption_pattern(f->data + read)) > 0) { for (int read = 0; read < f->filesize; ++write, ++read) {
// assert(skip > 11)! if ((skip = check_encryption_pattern(f->data + read)) > 0) {
fprintf(stderr, "Replace pattern [%.*s] with [encryptable] in [%s]\n", skip, f->data + read, f->filename); // assert(skip > 11)!
memcpy(f->data + write, "encryptable", 11); fprintf(stderr, "Replace pattern [%.*s] with [encryptable] in [%s]\n", skip, f->data + read, f->filename);
write += 11; memcpy(f->data + write, "encryptable", 11);
read += skip; write += 11;
} read += skip;
f->data[write] = f->data[read];
} }
f->filesize = write; f->data[write] = f->data[read];
} }
f->filesize = write;
} }
} }
} }
...@@ -265,19 +259,35 @@ static void cpio_extract(const char *entry, const char *filename, struct vector ...@@ -265,19 +259,35 @@ static void cpio_extract(const char *entry, const char *filename, struct vector
LOGE("Cannot find the file entry [%s]\n", entry); LOGE("Cannot find the file entry [%s]\n", entry);
} }
static void cpio_backup(const char *orig, struct vector *v) { static void cpio_backup(const char *orig, const char *sha1, struct vector *v) {
struct vector o_body, *o = &o_body, bak; struct vector o_body, *o = &o_body, bak;
cpio_entry *m, *n, *dir, *rem; cpio_entry *m, *n, *rem, *cksm;
char buf[PATH_MAX]; char buf[PATH_MAX];
int res, doBak; int res, doBak;
dir = xcalloc(sizeof(*dir), 1); if (sha1) cksm = xcalloc(sizeof(*cksm), 1);
rem = xcalloc(sizeof(*rem), 1);
vec_init(o); vec_init(o);
vec_init(&bak); vec_init(&bak);
// First push back the directory and the rmlist
vec_push_back(&bak, dir); m = xcalloc(sizeof(*m), 1);
m->filename = strdup(".backup");
m->namesize = strlen(m->filename) + 1;
m->mode = S_IFDIR;
vec_push_back(&bak, m);
m = xcalloc(sizeof(*m), 1);
m->filename = strdup(".backup/.magisk");
m->namesize = strlen(m->filename) + 1;
m->mode = S_IFREG;
vec_push_back(&bak, m);
rem = xcalloc(sizeof(*rem), 1);
rem->filename = strdup(".backup/.rmlist");
rem->namesize = strlen(rem->filename) + 1;
rem->mode = S_IFREG;
vec_push_back(&bak, rem); vec_push_back(&bak, rem);
if (sha1) vec_push_back(&bak, cksm);
parse_cpio(orig, o); parse_cpio(orig, o);
// Remove possible backups in original ramdisk // Remove possible backups in original ramdisk
cpio_rm(1, ".backup", o); cpio_rm(1, ".backup", o);
...@@ -287,13 +297,14 @@ static void cpio_backup(const char *orig, struct vector *v) { ...@@ -287,13 +297,14 @@ static void cpio_backup(const char *orig, struct vector *v) {
vec_sort(v, cpio_cmp); vec_sort(v, cpio_cmp);
vec_sort(o, cpio_cmp); vec_sort(o, cpio_cmp);
// Init the directory and rmlist if (sha1) {
dir->filename = strdup(".backup"); fprintf(stderr, "Save SHA1: [%s] -> [.backup/.sha1]\n", sha1);
dir->namesize = strlen(dir->filename) + 1; cksm->filename = strdup(".backup/.sha1");
dir->mode = S_IFDIR; cksm->namesize = strlen(cksm->filename) + 1;
rem->filename = strdup(".backup/.rmlist"); cksm->mode = S_IFREG;
rem->namesize = strlen(rem->filename) + 1; cksm->data = strdup(sha1);
rem->mode = S_IFREG; cksm->filesize = strlen(sha1) + 1;
}
// Start comparing // Start comparing
size_t i = 0, j = 0; size_t i = 0, j = 0;
...@@ -349,12 +360,8 @@ static void cpio_backup(const char *orig, struct vector *v) { ...@@ -349,12 +360,8 @@ static void cpio_backup(const char *orig, struct vector *v) {
vec_push_back(v, m); vec_push_back(v, m);
} }
// Don't include if empty if (rem->filesize == 0)
if (rem->filesize == 0) {
rem->remove = 1; rem->remove = 1;
if (bak.size == 2)
dir->remove = 1;
}
// Cleanup // Cleanup
cpio_vec_destroy(o); cpio_vec_destroy(o);
...@@ -367,21 +374,24 @@ static int cpio_restore(struct vector *v) { ...@@ -367,21 +374,24 @@ static int cpio_restore(struct vector *v) {
if (strstr(f->filename, ".backup") != NULL) { if (strstr(f->filename, ".backup") != NULL) {
ret = 0; ret = 0;
f->remove = 1; f->remove = 1;
if (strcmp(f->filename, ".backup") == 0) continue; if (f->filename[7] == '\0') continue;
if (strcmp(f->filename, ".backup/.rmlist") == 0) { if (f->filename[8] == '.') {
for (int pos = 0; pos < f->filesize; pos += strlen(f->data + pos) + 1) if (strcmp(f->filename, ".backup/.rmlist") == 0) {
cpio_rm(0, f->data + pos, v); for (int pos = 0; pos < f->filesize; pos += strlen(f->data + pos) + 1)
cpio_rm(0, f->data + pos, v);
}
continue; continue;
} else {
n = xcalloc(sizeof(*n), 1);
memcpy(n, f, sizeof(*f));
n->namesize -= 8;
n->filename = strdup(f->filename + 8);
n->data = f->data;
f->data = NULL;
n->remove = 0;
fprintf(stderr, "Restore [%s] -> [%s]\n", f->filename, n->filename);
cpio_vec_insert(v, n);
} }
n = xcalloc(sizeof(*n), 1);
memcpy(n, f, sizeof(*f));
n->namesize -= 8;
n->filename = strdup(f->filename + 8);
n->data = f->data;
f->data = NULL;
n->remove = 0;
fprintf(stderr, "Restoring [%s] -> [%s]\n", f->filename, n->filename);
cpio_vec_insert(v, n);
} }
} }
// Some known stuff we can remove // Some known stuff we can remove
...@@ -406,6 +416,8 @@ static void cpio_stocksha1(struct vector *v) { ...@@ -406,6 +416,8 @@ static void cpio_stocksha1(struct vector *v) {
return; return;
} }
} }
} else if (strcmp(f->filename, ".backup/.sha1") == 0) {
printf("%s\n", f->data);
} }
} }
} }
...@@ -443,7 +455,7 @@ int cpio_commands(const char *command, int argc, char *argv[]) { ...@@ -443,7 +455,7 @@ int cpio_commands(const char *command, int argc, char *argv[]) {
cmd = RESTORE; cmd = RESTORE;
} else if (strcmp(command, "stocksha1") == 0) { } else if (strcmp(command, "stocksha1") == 0) {
cmd = STOCKSHA1; cmd = STOCKSHA1;
} else if (argc == 1 && strcmp(command, "backup") == 0) { } else if (argc >= 1 && strcmp(command, "backup") == 0) {
cmd = BACKUP; cmd = BACKUP;
} else if (argc > 0 && strcmp(command, "rm") == 0) { } else if (argc > 0 && strcmp(command, "rm") == 0) {
cmd = RM; cmd = RM;
...@@ -479,7 +491,7 @@ int cpio_commands(const char *command, int argc, char *argv[]) { ...@@ -479,7 +491,7 @@ int cpio_commands(const char *command, int argc, char *argv[]) {
cpio_stocksha1(&v); cpio_stocksha1(&v);
return 0; return 0;
case BACKUP: case BACKUP:
cpio_backup(argv[0], &v); cpio_backup(argv[0], argc > 1 ? argv[1] : NULL, &v);
case RM: case RM:
cpio_rm(recursive, argv[0], &v); cpio_rm(recursive, argv[0], &v);
break; break;
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
#include <sys/types.h> #include <sys/types.h>
#include "logging.h"
#include "bootimg.h" #include "bootimg.h"
#define KERNEL_FILE "kernel" #define KERNEL_FILE "kernel"
...@@ -12,9 +13,6 @@ ...@@ -12,9 +13,6 @@
#define DTB_FILE "dtb" #define DTB_FILE "dtb"
#define NEW_BOOT "new-boot.img" #define NEW_BOOT "new-boot.img"
#define str(a) #a
#define xstr(a) str(a)
// Main entries // Main entries
void unpack(const char *image); void unpack(const char *image);
void repack(const char* orig_image, const char* out_image); void repack(const char* orig_image, const char* out_image);
...@@ -36,13 +34,10 @@ long long comp(file_t type, int to, const void *from, size_t size); ...@@ -36,13 +34,10 @@ 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); long long decomp(file_t type, int to, const void *from, size_t size);
// Utils // Utils
extern void mmap_ro(const char *filename, void **buf, size_t *size);
extern void mmap_rw(const char *filename, void **buf, size_t *size);
extern void write_zero(int fd, size_t size); extern void write_zero(int fd, size_t size);
extern void mem_align(size_t *pos, size_t align); extern void mem_align(size_t *pos, size_t align);
extern void file_align(int fd, size_t align, int out); extern void file_align(int fd, size_t align, int out);
extern int open_new(const char *filename); extern int open_new(const char *filename);
extern void *patch_init_rc(char *data, uint32_t *size);
extern int check_verity_pattern(const char *s); extern int check_verity_pattern(const char *s);
extern int check_encryption_pattern(const char *s); extern int check_encryption_pattern(const char *s);
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include <sys/mman.h> #include <sys/mman.h>
#include "magiskboot.h" #include "magiskboot.h"
#include "utils.h"
#include "sha1.h" #include "sha1.h"
/******************** /********************
...@@ -47,8 +48,9 @@ static void usage(char *arg0) { ...@@ -47,8 +48,9 @@ static void usage(char *arg0) {
" Return value: 0/stock 1/Magisk 2/other (e.g. phh, SuperSU)\n" " Return value: 0/stock 1/Magisk 2/other (e.g. phh, SuperSU)\n"
" -patch <KEEPVERITY> <KEEPFORCEENCRYPT>\n" " -patch <KEEPVERITY> <KEEPFORCEENCRYPT>\n"
" Patch cpio for Magisk. KEEP**** are true/false values\n" " Patch cpio for Magisk. KEEP**** are true/false values\n"
" -backup <origcpio>\n" " -backup <origcpio> [SHA1]\n"
" Create ramdisk backups into <incpio> from <origcpio>\n" " Create ramdisk backups into <incpio> from <origcpio>\n"
" SHA1 of stock boot image is optional\n"
" -restore\n" " -restore\n"
" Restore ramdisk from ramdisk backup within <incpio>\n" " Restore ramdisk from ramdisk backup within <incpio>\n"
" -stocksha1\n" " -stocksha1\n"
......
Subproject commit 3c6a170138cacb1f817c65181bd6e3ef15cfca9e Subproject commit 9e96824161ddf1d6af516f44cad4d0e904a7abed
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include <fcntl.h> #include <fcntl.h>
#include <unistd.h> #include <unistd.h>
#include <sys/sendfile.h> #include <sys/sendfile.h>
#include <sys/mman.h>
#ifndef NO_SELINUX #ifndef NO_SELINUX
#include <selinux/selinux.h> #include <selinux/selinux.h>
...@@ -52,6 +53,8 @@ int mkdir_p(const char *pathname, mode_t mode) { ...@@ -52,6 +53,8 @@ int mkdir_p(const char *pathname, mode_t mode) {
void rm_rf(const char *path) { void rm_rf(const char *path) {
int fd = xopen(path, O_RDONLY | O_CLOEXEC); int fd = xopen(path, O_RDONLY | O_CLOEXEC);
if (fd < 0)
return;
frm_rf(fd); frm_rf(fd);
close(fd); close(fd);
rmdir(path); rmdir(path);
...@@ -294,6 +297,22 @@ void fclone_attr(const int sourcefd, const int targetfd) { ...@@ -294,6 +297,22 @@ void fclone_attr(const int sourcefd, const int targetfd) {
fsetattr(targetfd, &a); 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 #ifndef NO_SELINUX
#define UNLABEL_CON "u:object_r:unlabeled:s0" #define UNLABEL_CON "u:object_r:unlabeled:s0"
......
...@@ -11,18 +11,15 @@ ...@@ -11,18 +11,15 @@
# boot_patch.sh script A script to patch boot. Expect path to boot image as parameter. # boot_patch.sh script A script to patch boot. Expect path to boot image as parameter.
# (this file) The script will use binaries and files in its same directory # (this file) The script will use binaries and files in its same directory
# to complete the patching process # to complete the patching process
# magisk binary The main binary for all Magisk operations. # monogisk binary The monolithic binary to replace /init
# It is also used to patch the sepolicy in the ramdisk.
# magiskboot binary A tool to unpack boot image, decompress ramdisk, extract ramdisk # magiskboot binary A tool to unpack boot image, decompress ramdisk, extract ramdisk
# , and patch the ramdisk for Magisk support # , and patch the ramdisk for Magisk support
# init.magisk.rc script A new line will be added to init.rc to import this script.
# All magisk entrypoints are defined here
# chromeos folder This folder should store all the utilities and keys to sign # chromeos folder This folder should store all the utilities and keys to sign
# (optional) a chromeos device, used in the tablet Pixel C # (optional) a chromeos device, used in the tablet Pixel C
# #
# If the script is not running as root, then the input boot image should be a stock image # If the script is not running as root, then the input boot image should be a stock image
# or have a backup included in ramdisk internally, since we cannot access the stock boot # or have a backup included in ramdisk internally, since we cannot access the stock boot
# image placed under /data we've created when previously installing # image placed under /data we've created when previously installed
# #
########################################################################################## ##########################################################################################
########################################################################################## ##########################################################################################
...@@ -47,21 +44,6 @@ basename_wrap() { ...@@ -47,21 +44,6 @@ basename_wrap() {
echo ${1##*/} echo ${1##*/}
} }
# --cpio-add <incpio> <mode> <entry> <infile>
cpio_add() {
./magiskboot --cpio-add ramdisk.cpio $1 $2 $3
}
# --cpio-extract <incpio> <entry> <outfile>
cpio_extract() {
./magiskboot --cpio-extract ramdisk.cpio $1 $2
}
# --cpio-mkdir <incpio> <mode> <entry>
cpio_mkdir() {
./magiskboot --cpio-mkdir ramdisk.cpio $1 $2
}
########################################################################################## ##########################################################################################
# Initialization # Initialization
########################################################################################## ##########################################################################################
...@@ -85,6 +67,9 @@ BOOTIMAGE="$1" ...@@ -85,6 +67,9 @@ BOOTIMAGE="$1"
chmod -R 755 . chmod -R 755 .
# Extract magisk if doesn't exist
[ -e magisk ] || ./monogisk -x magisk magisk
########################################################################################## ##########################################################################################
# Unpack # Unpack
########################################################################################## ##########################################################################################
...@@ -172,33 +157,11 @@ esac ...@@ -172,33 +157,11 @@ esac
ui_print "- Patching ramdisk" ui_print "- Patching ramdisk"
if [ ! -z $SHA1 ]; then ./magiskboot --cpio-add ramdisk.cpio 750 init monogisk
cp init.magisk.rc init.magisk.rc.bak ./magiskboot --cpio-patch ramdisk.cpio $KEEPVERITY $KEEPFORCEENCRYPT
echo "# STOCKSHA1=$SHA1" >> init.magisk.rc
fi
if $SKIP_INITRAMFS; then
cpio_add 750 init magiskinit
cpio_mkdir 000 overlay
cpio_add 750 overlay/init.magisk.rc init.magisk.rc
cpio_mkdir 750 overlay/sbin
cpio_add 755 overlay/sbin/magisk magisk
else
./magiskboot --cpio-patch ramdisk.cpio $KEEPVERITY $KEEPFORCEENCRYPT
cpio_extract sepolicy sepolicy
./magisk magiskpolicy --load sepolicy --save sepolicy --minimal
cpio_add 644 sepolicy sepolicy
rm -f sepolicy
cpio_add 750 init.magisk.rc init.magisk.rc
cpio_add 755 sbin/magisk magisk
fi
mv init.magisk.rc.bak init.magisk.rc 2>/dev/null
# Create ramdisk backups # Create ramdisk backups
./magiskboot --cpio-backup ramdisk.cpio ramdisk.cpio.orig ./magiskboot --cpio-backup ramdisk.cpio ramdisk.cpio.orig $SHA1
if ! $KEEPVERITY && [ -f dtb ]; then if ! $KEEPVERITY && [ -f dtb ]; then
./magiskboot --dtb-patch dtb && ui_print "- Patching fstab in dtb to remove dm-verity" ./magiskboot --dtb-patch dtb && ui_print "- Patching fstab in dtb to remove dm-verity"
...@@ -218,7 +181,7 @@ rm -f ramdisk.cpio.orig ...@@ -218,7 +181,7 @@ rm -f ramdisk.cpio.orig
A1020054011440B93FA00F7140020054010840B93FA00F71E0010054001840B91FA00F7181010054 A1020054011440B93FA00F7140020054010840B93FA00F71E0010054001840B91FA00F7181010054
# skip_initramfs -> want_initramfs # skip_initramfs -> want_initramfs
$SKIP_INITRAMFS && ./magiskboot --hexpatch kernel \ ./magiskboot --hexpatch kernel \
736B69705F696E697472616D6673 \ 736B69705F696E697472616D6673 \
77616E745F696E697472616D6673 77616E745F696E697472616D6673
......
...@@ -79,18 +79,12 @@ ui_print "- Constructing environment" ...@@ -79,18 +79,12 @@ ui_print "- Constructing environment"
is_mounted /data && MAGISKBIN=/data/magisk || MAGISKBIN=/cache/data_bin is_mounted /data && MAGISKBIN=/data/magisk || MAGISKBIN=/cache/data_bin
if $BOOTMODE; then
# Cleanup binary mirrors
umount -l /dev/magisk/mirror/bin 2>/dev/null
rm -rf /dev/magisk/mirror/bin 2>/dev/null
fi
# Save our stock boot image dump before removing it # Save our stock boot image dump before removing it
mv /data/magisk/stock_boot* /data 2>/dev/null mv /data/magisk/stock_boot* /data 2>/dev/null
# Copy required files # Copy required files
rm -rf $MAGISKBIN 2>/dev/null rm -rf $MAGISKBIN/* 2>/dev/null
mkdir -p $MAGISKBIN mkdir -p $MAGISKBIN 2>/dev/null
cp -af $BINDIR/. $COMMONDIR/. $CHROMEDIR $TMPDIR/bin/busybox $MAGISKBIN cp -af $BINDIR/. $COMMONDIR/. $CHROMEDIR $TMPDIR/bin/busybox $MAGISKBIN
chmod -R 755 $MAGISKBIN chmod -R 755 $MAGISKBIN
......
# Triggers
on post-fs
start logd
start magisk_daemon
wait /dev/.magisk.unblock 5
rm /dev/.magisk.unblock
start magisk_pfs
wait /dev/.magisk.unblock 10
on post-fs-data
load_persist_props
rm /dev/.magisk.unblock
start magisk_pfsd
wait /dev/.magisk.unblock 10
# Services
# Self recoverable service
service magisk_daemon /sbin/magisk --daemon
user root
seclabel u:r:su:s0
# launch post-fs script
service magisk_pfs /sbin/magisk --post-fs
user root
seclabel u:r:su:s0
oneshot
# launch post-fs-data script
service magisk_pfsd /sbin/magisk --post-fs-data
user root
seclabel u:r:su:s0
oneshot
# launch late_start script
service magisk_service /sbin/magisk --service
class late_start
user root
seclabel u:r:su:s0
oneshot
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment