diff --git a/core/jni/Android.mk b/core/jni/Android.mk index 666ef4ec1..959286c9c 100644 --- a/core/jni/Android.mk +++ b/core/jni/Android.mk @@ -76,6 +76,7 @@ LOCAL_SRC_FILES := \ utils/vector.c \ utils/file.c \ utils/xwrap.c \ + utils/cpio.c \ magiskpolicy/api.c \ magiskpolicy/magiskpolicy.c \ magiskpolicy/rules.c \ diff --git a/core/jni/core/magiskinit.c b/core/jni/core/magiskinit.c index 650a4119a..90d636b33 100644 --- a/core/jni/core/magiskinit.c +++ b/core/jni/core/magiskinit.c @@ -44,6 +44,7 @@ #include "utils.h" #include "magiskpolicy.h" #include "daemon.h" +#include "cpio.h" #include "magisk.h" // #define VLOG(fmt, ...) printf(fmt, __VA_ARGS__) /* Enable to debug */ @@ -459,9 +460,34 @@ int main(int argc, char *argv[]) { close(system_root); } else { - // Revert original init binary - unlink("/init"); - link("/.backup/init", "/init"); + char *ramdisk_xz = NULL; + if (access("/ramdisk-recovery.xz", R_OK) == 0) + ramdisk_xz = "/ramdisk-recovery.xz"; + else if (access("/ramdisk.cpio.xz", R_OK) == 0) + ramdisk_xz = "/ramdisk.cpio.xz"; + + if (ramdisk_xz) { + // High compress mode + void *addr; + size_t size; + mmap_ro(ramdisk_xz, &addr, &size); + int fd = creat("/ramdisk.cpio", 0); + unxz(addr, size, fd); + munmap(addr, size); + close(fd); + struct vector v; + vec_init(&v); + parse_cpio(&v, "/ramdisk.cpio"); + excl_list = (char *[]) { "overlay", ".backup", NULL }; + frm_rf(root); + chdir("/"); + cpio_extract_all(&v); + cpio_vec_destroy(&v); + } else { + // Revert original init binary + unlink("/init"); + link("/.backup/init", "/init"); + } } // Only patch initramfs if not intended to run in recovery (legacy devices) diff --git a/core/jni/include/cpio.h b/core/jni/include/cpio.h index 0eebb19d4..30c9da773 100644 --- a/core/jni/include/cpio.h +++ b/core/jni/include/cpio.h @@ -55,8 +55,8 @@ void cpio_extract_all(struct vector *v); // Magisk specific int cpio_test(struct vector *v); -void cpio_backup(struct vector *v, const char *orig, const char *sha1); -int cpio_restore(struct vector *v); +struct vector *cpio_backup(struct vector *v, const char *orig, const char *sha1); +void cpio_restore(struct vector *v); char *cpio_stocksha1(struct vector *v); #endif diff --git a/core/jni/include/utils.h b/core/jni/include/utils.h index 0b5d13ff9..15333df57 100644 --- a/core/jni/include/utils.h +++ b/core/jni/include/utils.h @@ -117,8 +117,8 @@ 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 mmap_ro(const char *filename, void **buf, size_t *size); -void mmap_rw(const char *filename, void **buf, size_t *size); +int mmap_ro(const char *filename, void **buf, size_t *size); +int mmap_rw(const char *filename, void **buf, size_t *size); void full_read(int fd, void **buf, size_t *size); void write_zero(int fd, size_t size); void mem_align(size_t *pos, size_t align); diff --git a/core/jni/magiskboot/bootimg.c b/core/jni/magiskboot/bootimg.c index ae8372700..3025077c5 100644 --- a/core/jni/magiskboot/bootimg.c +++ b/core/jni/magiskboot/bootimg.c @@ -8,6 +8,11 @@ #include "utils.h" #include "logging.h" +#define INSUF_BLOCK_RET 2 +#define CHROMEOS_RET 3 +#define ELF32_RET 4 +#define ELF64_RET 5 + static void dump(void *buf, size_t size, const char *filename) { int fd = creat(filename, 0644); xwrite(fd, buf, size); @@ -53,60 +58,61 @@ static void print_hdr(const boot_img_hdr *hdr) { fprintf(stderr, "\n"); } -int parse_img(void *orig, size_t size, boot_img *boot) { - void *base, *end; - size_t pos = 0; - int ret = 0; +int parse_img(const char *image, boot_img *boot) { memset(boot, 0, sizeof(*boot)); - for(base = orig, end = orig + size; base < end; base += 256, size -= 256) { - switch (check_type(base)) { + int is_blk = mmap_ro(image, &boot->map_addr, &boot->map_size); + + // Parse image + fprintf(stderr, "Parsing boot image: [%s]\n\n", image); + for (size_t pos = 0; pos < boot->map_size; pos += 256) { + switch (check_type(boot->map_addr + pos)) { case CHROMEOS: // The caller should know it's chromeos, as it needs additional signing - ret = 2; + boot->flags |= CHROMEOS_FLAG; continue; case ELF32: - exit(3); + exit(ELF32_RET); case ELF64: - exit(4); + exit(ELF64_RET); case AOSP: // Read the header - memcpy(&boot->hdr, base, sizeof(boot->hdr)); + memcpy(&boot->hdr, boot->map_addr + pos, sizeof(boot->hdr)); pos += boot->hdr.page_size; print_hdr(&boot->hdr); - boot->kernel = base + pos; + boot->kernel = boot->map_addr + pos; pos += boot->hdr.kernel_size; mem_align(&pos, boot->hdr.page_size); - boot->ramdisk = base + pos; + boot->ramdisk = boot->map_addr + pos; pos += boot->hdr.ramdisk_size; mem_align(&pos, boot->hdr.page_size); if (boot->hdr.second_size) { - boot->second = base + pos; + boot->second = boot->map_addr + pos; pos += boot->hdr.second_size; mem_align(&pos, boot->hdr.page_size); } if (boot->hdr.extra_size) { - boot->extra = base + pos; + boot->extra = boot->map_addr + pos; pos += boot->hdr.extra_size; mem_align(&pos, boot->hdr.page_size); } - if (pos < size) { - boot->tail = base + pos; - boot->tail_size = end - base - pos; + if (pos < boot->map_size) { + boot->tail = boot->map_addr + pos; + boot->tail_size = boot->map_size - pos; } // Search for dtb in kernel - for (int i = 0; i < boot->hdr.kernel_size; ++i) { + for (uint32_t i = 0; i < boot->hdr.kernel_size; ++i) { if (memcmp(boot->kernel + i, DTB_MAGIC, 4) == 0) { boot->dtb = boot->kernel + i; boot->dt_size = boot->hdr.kernel_size - i; boot->hdr.kernel_size = i; - fprintf(stderr, "DTB [%d]\n", boot->dt_size); + fprintf(stderr, "DTB [%u]\n", boot->dt_size); } } @@ -139,25 +145,19 @@ int parse_img(void *orig, size_t size, boot_img *boot) { fprintf(stderr, "RAMDISK_FMT [%s]\n", fmt); fprintf(stderr, "\n"); - return ret; + return boot->flags & CHROMEOS_FLAG ? CHROMEOS_RET : + ((is_blk && boot->tail_size < 500 * 1024) ? INSUF_BLOCK_RET : 0); default: continue; } } LOGE("No boot image magic found!\n"); - return 1; } void unpack(const char* image) { - size_t size; - void *orig; - mmap_ro(image, &orig, &size); - int fd; boot_img boot; - - // Parse image - fprintf(stderr, "Parsing boot image: [%s]\n\n", image); - int ret = parse_img(orig, size, &boot); + int ret = parse_img(image, &boot); + int fd; // Dump kernel if (COMPRESSED(boot.kernel_type)) { @@ -193,24 +193,18 @@ void unpack(const char* image) { dump(boot.extra, boot.hdr.extra_size, EXTRA_FILE); } - munmap(orig, size); + munmap(boot.map_addr, boot.map_size); exit(ret); } void repack(const char* orig_image, const char* out_image) { - size_t size; - void *orig; boot_img boot; // There are possible two MTK headers size_t mtk_kernel_off, mtk_ramdisk_off; - // Load original image - mmap_ro(orig_image, &orig, &size); - // Parse original image - fprintf(stderr, "Parsing boot image: [%s]\n\n", orig_image); - parse_img(orig, size, &boot); + parse_img(orig_image, &boot); fprintf(stderr, "Repack to boot image: [%s]\n\n", out_image); @@ -309,7 +303,6 @@ void repack(const char* orig_image, const char* out_image) { // Print new image info print_hdr(&boot.hdr); - munmap(orig, size); + munmap(boot.map_addr, boot.map_size); close(fd); } - diff --git a/core/jni/magiskboot/bootimg.h b/core/jni/magiskboot/bootimg.h index c27aa8c9d..f871f53d9 100644 --- a/core/jni/magiskboot/bootimg.h +++ b/core/jni/magiskboot/bootimg.h @@ -103,20 +103,25 @@ typedef struct mtk_hdr { // Flags #define MTK_KERNEL 0x1 #define MTK_RAMDISK 0x2 +#define CHROMEOS_FLAG 0x4 typedef struct boot_img { + size_t map_size; + uint32_t dt_size; + size_t tail_size; + uint8_t flags; + file_t kernel_type, ramdisk_type; + boot_img_hdr hdr; + mtk_hdr mtk_kernel_hdr, mtk_ramdisk_hdr; + + void *map_addr; void *kernel; void *dtb; - uint32_t dt_size; void *ramdisk; void *second; void *extra; void *tail; - uint32_t tail_size; - uint32_t flags; - file_t kernel_type, ramdisk_type; - mtk_hdr mtk_kernel_hdr, mtk_ramdisk_hdr; } boot_img; #endif diff --git a/core/jni/magiskboot/magiskboot.h b/core/jni/magiskboot/magiskboot.h index 0cc6b116a..dd6c0ce03 100644 --- a/core/jni/magiskboot/magiskboot.h +++ b/core/jni/magiskboot/magiskboot.h @@ -17,7 +17,7 @@ void unpack(const char *image); void repack(const char* orig_image, const char* out_image); void hexpatch(const char *image, const char *from, const char *to); -int parse_img(void *orig, size_t size, boot_img *boot); +int parse_img(const char *image, boot_img *boot); int cpio_commands(const char *cmd, int argc, char *argv[]); void comp_file(const char *method, const char *from, const char *to); void decomp_file(char *from, const char *to); diff --git a/core/jni/magiskboot/main.c b/core/jni/magiskboot/main.c index 71f3eaab5..9b343ca39 100644 --- a/core/jni/magiskboot/main.c +++ b/core/jni/magiskboot/main.c @@ -17,16 +17,21 @@ static void usage(char *arg0) { "Usage: %s [args...]\n" "\n" "Supported actions:\n" + " --parse \n" + " Parse only, do not unpack. Return value: \n" + " 0:OK 1:error 2:insufficient boot partition size\n" + " 3:chromeos 4:ELF32 5:ELF64\n" + "\n" " --unpack \n" " Unpack to kernel, ramdisk.cpio, (second), (dtb), (extra) into\n" - " the current directory\n" + " the current directory. Return value is the same as parse command\n" "\n" " --repack [outbootimg]\n" " Repack kernel, ramdisk.cpio[.ext], second, dtb... from current directory\n" " to [outbootimg], or new-boot.img if not specified.\n" - " It will compress ramdisk.cpio with the same method used in \n" - " if exists, or attempt to find ramdisk.cpio.[ext], and repack\n" - " directly with the compressed ramdisk file\n" + " It will compress ramdisk.cpio with the same method used in ,\n" + " or attempt to find ramdisk.cpio.[ext], and repack directly with the\n" + " compressed ramdisk file\n" "\n" " --hexpatch \n" " Search in , and replace with \n" @@ -40,18 +45,19 @@ static void usage(char *arg0) { " Create directory as an \n" " -ln \n" " Create symlink to point to \n" - " -add \n" - " Add as an ; replaces if already exists\n" " -mv \n" " Move to \n" + " -add \n" + " Add as an ; replaces if already exists\n" " -extract [ ]\n" " Extract to , or extract all to current directory\n" " -test\n" " Return value: 0/stock 1/Magisk 2/other (phh, SuperSU, Xposed)\n" " -patch \n" - " Patch cpio for Magisk. KEEP**** are true/false values\n" - " -backup [SHA1]\n" + " Patch cpio for Magisk. KEEP**** are boolean values\n" + " -backup [SHA1]\n" " Create ramdisk backups into from \n" + " HIGH_COMP is a boolean value, toggles high compression mode\n" " SHA1 of stock boot image is optional\n" " -restore\n" " Restore ramdisk from ramdisk backup within \n" @@ -63,6 +69,9 @@ static void usage(char *arg0) { " Supported commands:\n" " -dump\n" " Dump all contents from dtb for debugging\n" + " -test\n" + " Check if fstab has verity/avb flags\n" + " Return value: 0/no flags 1/flag exists" " -patch\n" " Search for fstab and remove verity/avb\n" "\n" @@ -74,8 +83,7 @@ static void usage(char *arg0) { for (int i = 0; SUP_LIST[i]; ++i) fprintf(stderr, "%s ", SUP_LIST[i]); fprintf(stderr, - "\n" - "\n" + "\n\n" " --decompress [outfile]\n" " Detect method and decompress , optionally to [outfile]\n" " /[outfile] can be '-' to be STDIN/STDOUT\n" @@ -83,8 +91,7 @@ static void usage(char *arg0) { for (int i = 0; SUP_LIST[i]; ++i) fprintf(stderr, "%s ", SUP_LIST[i]); fprintf(stderr, - "\n" - "\n" + "\n\n" " --sha1 \n" " Print the SHA1 checksum for \n" "\n" @@ -121,6 +128,9 @@ int main(int argc, char *argv[]) { printf("%02x", sha1[i]); printf("\n"); munmap(buf, size); + } else if (argc > 2 && strcmp(argv[1], "--parse") == 0) { + boot_img boot; + exit(parse_img(argv[2], &boot)); } else if (argc > 2 && strcmp(argv[1], "--unpack") == 0) { unpack(argv[2]); } else if (argc > 2 && strcmp(argv[1], "--repack") == 0) { diff --git a/core/jni/magiskboot/ramdisk.c b/core/jni/magiskboot/ramdisk.c index 5dcfa4b34..a12663d30 100644 --- a/core/jni/magiskboot/ramdisk.c +++ b/core/jni/magiskboot/ramdisk.c @@ -1,6 +1,9 @@ #include #include #include +#include +#include +#include #include "magiskboot.h" #include "cpio.h" @@ -70,8 +73,68 @@ void cpio_patch(struct vector *v, int keepverity, int keepforceencrypt) { } } +static void restore_high_compress(struct vector *v, const char *incpio) { + // Check if the ramdisk is in high compression mode + if (cpio_extract(v, "ramdisk.cpio.xz", incpio) == 0) { + void *addr, *xz; + size_t size; + mmap_ro(incpio, &addr, &size); + xz = xmalloc(size); + memcpy(xz, addr, size); + munmap(addr, size); + int fd = creat(incpio, 0644); + lzma(0, fd, xz, size); + close(fd); + cpio_rm(v, 0, "ramdisk.cpio.xz"); + cpio_rm(v, 0, "init"); + struct vector vv; + vec_init(&vv); + parse_cpio(&vv, incpio); + cpio_entry *e; + vec_for_each(&vv, e) + vec_push_back(v, e); + vec_destroy(&vv); + } +} + +static void enable_high_compress(struct vector *v, struct vector *b, const char *incpio) { + cpio_entry *e, *magiskinit, *init; + + // Swap magiskinit with original init + vec_for_each(b, e) { + if (strcmp(e->filename, ".backup/init") == 0) { + free(e->filename); + e->filename = strdup("init"); + init = e; + vec_for_each(v, e) { + if (strcmp(e->filename, "init") == 0) { + magiskinit = e; + vec_cur(v) = init; + break; + } + } + vec_cur(b) = NULL; + break; + } + } + + dump_cpio(v, incpio); + cpio_vec_destroy(v); + void *addr, *cpio; + size_t size; + mmap_ro(incpio, &addr, &size); + cpio = xmalloc(size); + memcpy(cpio, addr, size); + munmap(addr, size); + int fd = creat(incpio, 0644); + lzma(1, fd, cpio, size); + close(fd); + vec_init(v); + vec_push_back(v, magiskinit); + cpio_add(v, 0, "ramdisk.cpio.xz", incpio); +} + int cpio_commands(const char *command, int argc, char *argv[]) { - int ret = 0; char *incpio = argv[0]; ++argv; --argc; @@ -82,12 +145,23 @@ int cpio_commands(const char *command, int argc, char *argv[]) { if (strcmp(command, "test") == 0) { exit(cpio_test(&v)); } else if (strcmp(command, "restore") == 0) { - ret = cpio_restore(&v); + restore_high_compress(&v, incpio); + cpio_restore(&v); } else if (strcmp(command, "stocksha1") == 0) { printf("%s\n", cpio_stocksha1(&v)); return 0; - } else if (argc >= 1 && strcmp(command, "backup") == 0) { - cpio_backup(&v, argv[0], argc > 1 ? argv[1] : NULL); + } else if (argc >= 2 && strcmp(command, "backup") == 0) { + struct vector *back; + cpio_entry *e; + back = cpio_backup(&v, argv[0], argc > 2 ? argv[2] : NULL); + + // Enable high compression mode + if (strcmp(argv[1], "true") == 0) + enable_high_compress(&v, back, incpio); + + vec_for_each(back, e) + if (e) vec_push_back(&v, e); + } else if (argc > 0 && strcmp(command, "rm") == 0) { int recursive = 0; if (argc == 2 && strcmp(argv[0], "-r") == 0) { @@ -119,5 +193,5 @@ int cpio_commands(const char *command, int argc, char *argv[]) { dump_cpio(&v, incpio); cpio_vec_destroy(&v); - exit(ret); + exit(0); } diff --git a/core/jni/magiskboot/types.c b/core/jni/magiskboot/types.c index 275f87eb1..4833b0b3e 100644 --- a/core/jni/magiskboot/types.c +++ b/core/jni/magiskboot/types.c @@ -3,10 +3,6 @@ #include "bootimg.h" #include "types.h" -char *SUP_LIST[] = { "gzip", "xz", "lzma", "bzip2", "lz4", "lz4_legacy", NULL }; -char *SUP_EXT_LIST[] = { "gz", "xz", "lzma", "bz2", "lz4", "lz4", NULL }; -file_t SUP_TYPE_LIST[] = { GZIP, XZ, LZMA, BZIP2, LZ4, LZ4_LEGACY, 0 }; - file_t check_type(const void *buf) { if (memcmp(buf, CHROMEOS_MAGIC, 8) == 0) { return CHROMEOS; diff --git a/core/jni/magiskboot/types.h b/core/jni/magiskboot/types.h index 5a2bd37a1..c65183c97 100644 --- a/core/jni/magiskboot/types.h +++ b/core/jni/magiskboot/types.h @@ -33,9 +33,8 @@ typedef enum { #define DTB_MAGIC "\xd0\x0d\xfe\xed" #define LG_BUMP_MAGIC "\x41\xa9\xe4\x67\x74\x4d\x1d\x1b\xa4\x29\xf2\xec\xea\x65\x52\x79" -extern char *SUP_LIST[]; -extern char *SUP_EXT_LIST[]; -extern file_t SUP_TYPE_LIST[]; +#define SUP_LIST ((char *[]) { "gzip", "xz", "lzma", "bzip2", "lz4", "lz4_legacy", NULL }) +#define SUP_EXT_LIST ((char *[]) { "gz", "xz", "lzma", "bz2", "lz4", "lz4", NULL }) file_t check_type(const void *buf); void get_type_name(file_t type, char *name); diff --git a/core/jni/utils/cpio.c b/core/jni/utils/cpio.c index 2985cf4c3..8a3b967a1 100644 --- a/core/jni/utils/cpio.c +++ b/core/jni/utils/cpio.c @@ -213,7 +213,6 @@ int cpio_extract(struct vector *v, const char *entry, const char *filename) { vec_for_each(v, f) { if (strcmp(f->filename, entry) == 0) { fprintf(stderr, "Extracting [%s] to [%s]\n\n", entry, filename); - unlink(filename); if (S_ISREG(f->mode)) { int fd = creat(filename, f->mode & 0777); xwrite(fd, f->data, f->filesize); @@ -222,6 +221,7 @@ int cpio_extract(struct vector *v, const char *entry, const char *filename) { } else if (S_ISLNK(f->mode)) { char *target = xcalloc(f->filesize + 1, 1); memcpy(target, f->data, f->filesize); + unlink(filename); symlink(target, filename); } return 0; @@ -263,9 +263,8 @@ int cpio_test(struct vector *v) { vec_for_each(v, f) { for (int i = 0; OTHER_LIST[i]; ++i) { if (strcmp(f->filename, OTHER_LIST[i]) == 0) { - ret |= OTHER_PATCH; // Already find other files, abort - exit(OTHER_PATCH); + return OTHER_PATCH; } } for (int i = 0; MAGISK_LIST[i]; ++i) { @@ -277,34 +276,36 @@ int cpio_test(struct vector *v) { return ret; } -void cpio_backup(struct vector *v, const char *orig, const char *sha1) { - struct vector o_body, *o = &o_body, bak; +struct vector * cpio_backup(struct vector *v, const char *orig, const char *sha1) { + struct vector o_body, *o = &o_body, *ret; cpio_entry *m, *n, *rem, *cksm; char buf[PATH_MAX]; - int res, doBak; + int res, backup; + + ret = xcalloc(sizeof(*ret), 1); vec_init(o); - vec_init(&bak); + vec_init(ret); m = xcalloc(sizeof(*m), 1); m->filename = strdup(".backup"); m->mode = S_IFDIR; - vec_push_back(&bak, m); + vec_push_back(ret, m); m = xcalloc(sizeof(*m), 1); m->filename = strdup(".backup/.magisk"); m->mode = S_IFREG; - vec_push_back(&bak, m); + vec_push_back(ret, m); rem = xcalloc(sizeof(*rem), 1); rem->filename = strdup(".backup/.rmlist"); rem->mode = S_IFREG; - vec_push_back(&bak, rem); + vec_push_back(ret, rem); if (sha1) { fprintf(stderr, "Save SHA1: [%s] -> [.backup/.sha1]\n", sha1); cksm = xcalloc(sizeof(*cksm), 1); - vec_push_back(&bak, cksm); + vec_push_back(ret, cksm); cksm->filename = strdup(".backup/.sha1"); cksm->mode = S_IFREG; cksm->data = strdup(sha1); @@ -323,7 +324,7 @@ void cpio_backup(struct vector *v, const char *orig, const char *sha1) { // Start comparing size_t i = 0, j = 0; while(i != vec_size(o) || j != vec_size(v)) { - doBak = 0; + backup = 0; if (i != vec_size(o) && j != vec_size(v)) { m = vec_entry(o)[i]; n = vec_entry(v)[j]; @@ -339,14 +340,14 @@ void cpio_backup(struct vector *v, const char *orig, const char *sha1) { if (res < 0) { // Something is missing in new ramdisk, backup! ++i; - doBak = 1; + backup = 1; fprintf(stderr, "Backup missing entry: "); } else if (res == 0) { ++i; ++j; if (m->filesize == n->filesize && memcmp(m->data, n->data, m->filesize) == 0) continue; // Not the same! - doBak = 1; + backup = 1; fprintf(stderr, "Backup mismatch entry: "); } else { // Someting new in ramdisk, record in rem @@ -357,35 +358,30 @@ void cpio_backup(struct vector *v, const char *orig, const char *sha1) { rem->filesize += strlen(n->filename) + 1; fprintf(stderr, "Record new entry: [%s] -> [.backup/.rmlist]\n", n->filename); } - if (doBak) { + if (backup) { sprintf(buf, ".backup/%s", m->filename); free(m->filename); m->filename = strdup(buf); fprintf(stderr, "[%s] -> [%s]\n", buf, m->filename); - vec_push_back(&bak, m); + vec_push_back(ret, m); // NULL the original entry, so it won't be freed vec_entry(o)[i - 1] = NULL; } } - // Add the backup files to the original ramdisk - vec_for_each(&bak, m) { - vec_push_back(v, m); - } - if (rem->filesize == 0) rem->remove = 1; // Cleanup cpio_vec_destroy(o); + + return ret; } -int cpio_restore(struct vector *v) { +void cpio_restore(struct vector *v) { cpio_entry *f, *n; - int ret = 1; vec_for_each(v, f) { - if (strstr(f->filename, ".backup") != NULL) { - ret = 0; + if (strncmp(f->filename, ".backup", 7) == 0) { f->remove = 1; if (f->filename[7] == '\0') continue; if (f->filename[8] == '.') { @@ -405,12 +401,14 @@ int cpio_restore(struct vector *v) { cpio_vec_insert(v, n); } } + if (strncmp(f->filename, "overlay", 7) == 0) + f->remove = 1; } // Some known stuff we can remove cpio_rm(v, 0, "sbin/magic_mask.sh"); cpio_rm(v, 0, "init.magisk.rc"); cpio_rm(v, 0, "magisk"); - return ret; + cpio_rm(v, 0, "ramdisk-recovery.xz"); } char *cpio_stocksha1(struct vector *v) { diff --git a/core/jni/utils/file.c b/core/jni/utils/file.c index e33d1c4e6..6e06a908f 100644 --- a/core/jni/utils/file.c +++ b/core/jni/utils/file.c @@ -357,24 +357,25 @@ void restorecon(int dirfd, int force) { #endif // SELINUX -static void _mmap(int rw, const char *filename, void **buf, size_t *size) { +static int _mmap(int rw, const char *filename, void **buf, size_t *size) { struct stat st; - stat(filename, &st); int fd = xopen(filename, rw ? O_RDWR : O_RDONLY); + fstat(fd, &st); if (S_ISBLK(st.st_mode)) ioctl(fd, BLKGETSIZE64, size); else *size = st.st_size; *buf = *size > 0 ? xmmap(NULL, *size, PROT_READ | (rw ? PROT_WRITE : 0), MAP_SHARED, fd, 0) : NULL; close(fd); + return S_ISBLK(st.st_mode); } -void mmap_ro(const char *filename, void **buf, size_t *size) { - _mmap(0, filename, buf, size); +int mmap_ro(const char *filename, void **buf, size_t *size) { + return _mmap(0, filename, buf, size); } -void mmap_rw(const char *filename, void **buf, size_t *size) { - _mmap(1, filename, buf, size); +int mmap_rw(const char *filename, void **buf, size_t *size) { + return _mmap(1, filename, buf, size); } void full_read(int fd, void **buf, size_t *size) { diff --git a/scripts/boot_patch.sh b/scripts/boot_patch.sh index 237cb5894..d35d1fef0 100644 --- a/scripts/boot_patch.sh +++ b/scripts/boot_patch.sh @@ -64,6 +64,7 @@ BOOTIMAGE="$1" # Presets [ -z $KEEPVERITY ] && KEEPVERITY=false [ -z $KEEPFORCEENCRYPT ] && KEEPFORCEENCRYPT=false +[ -z $HIGH_COMP ] && HIGH_COMP=false chmod -R 755 . @@ -86,14 +87,19 @@ case $? in abort "! Unable to unpack boot image" ;; 2 ) + ui_print "! Insufficient boot partition size detected" + ui_print "- Enable high compression mode" + HIGH_COMP=true + ;; + 3 ) ui_print "- ChromeOS boot image detected" CHROMEOS=true ;; - 3 ) + 4 ) ui_print "! Sony ELF32 format detected" abort "! Please use BootBridge from @AdrianDC to flash Magisk" ;; - 4 ) + 5 ) ui_print "! Sony ELF64 format detected" abort "! Stock kernel cannot be patched, please use a custom kernel" esac @@ -118,30 +124,7 @@ case $? in ui_print "- Magisk patched image detected!" # Find SHA1 of stock boot image [ -z $SHA1 ] && SHA1=`./magiskboot --cpio-stocksha1 ramdisk.cpio 2>/dev/null` - OK=false ./magiskboot --cpio-restore ramdisk.cpio - if [ $? -eq 0 ]; then - ui_print "- Ramdisk restored from internal backup" - OK=true - else - # Restore failed - ui_print "! Cannot restore from internal backup" - # If we are root and SHA1 known, we try to find the stock backup - if [ ! -z $SHA1 ]; then - STOCKDUMP=/data/stock_boot_${SHA1}.img.gz - if [ -f $STOCKDUMP ]; then - ui_print "- Stock boot image backup found" - ./magiskboot --decompress $STOCKDUMP stock_boot.img - ./magiskboot --unpack stock_boot.img - rm -f stock_boot.img - OK=true - fi - fi - fi - if ! $OK; then - ui_print "! Ramdisk restoration incomplete" - ui_print "! Will still try to continue installation" - fi cp -af ramdisk.cpio ramdisk.cpio.orig ;; 2 ) # Other patched @@ -156,14 +139,21 @@ esac ui_print "- Patching ramdisk" -./magiskboot --cpio-add ramdisk.cpio 750 init magiskinit -./magiskboot --cpio-patch ramdisk.cpio $KEEPVERITY $KEEPFORCEENCRYPT +[ -f /sdcard/ramdisk-recovery.img ] && HIGH_COMP=true -# Create ramdisk backups -./magiskboot --cpio-backup ramdisk.cpio ramdisk.cpio.orig $SHA1 +./magiskboot --cpio-patch ramdisk.cpio $KEEPVERITY $KEEPFORCEENCRYPT +./magiskboot --cpio-add ramdisk.cpio 750 init magiskinit +./magiskboot --cpio-backup ramdisk.cpio ramdisk.cpio.orig $HIGH_COMP $SHA1 rm -f ramdisk.cpio.orig +if [ -f /sdcard/ramdisk-recovery.img ]; then + ui_print "- Adding ramdisk-recovery.img" + ./magiskboot --decompress - < /sdcard/ramdisk-recovery.img | ./magiskboot --compress=xz - ramdisk-recovery.xz + ./magiskboot --cpio-add ramdisk.cpio 0 ramdisk-recovery.xz ramdisk-recovery.xz + rm ramdisk-recovery.xz +fi + ########################################################################################## # Binary patches ########################################################################################## diff --git a/scripts/util_functions.sh b/scripts/util_functions.sh index e965f2daa..315a979c1 100644 --- a/scripts/util_functions.sh +++ b/scripts/util_functions.sh @@ -84,7 +84,7 @@ getvar() { local VARNAME=$1 local VALUE=$(eval echo \$$VARNAME) [ ! -z $VALUE ] && return - for DIR in /dev /data /cache /system; do + for DIR in /.backup /data /cache /system; do VALUE=`grep_prop $VARNAME $DIR/.magisk` [ ! -z $VALUE ] && break; done