From 0e5a113a0cb7b5326032c10be5e5d4591790adb7 Mon Sep 17 00:00:00 2001 From: topjohnwu Date: Sun, 22 Sep 2019 04:17:15 -0400 Subject: [PATCH] Support patching mnt_point in fstab in dtb --- native/jni/magiskboot/dtb.cpp | 37 ++++++++++++++------- native/jni/magiskboot/magiskboot.h | 3 +- native/jni/magiskboot/ramdisk.cpp | 53 +++++++++++++++++------------- scripts/boot_patch.sh | 17 ++++++---- 4 files changed, 66 insertions(+), 44 deletions(-) diff --git a/native/jni/magiskboot/dtb.cpp b/native/jni/magiskboot/dtb.cpp index 8691ace5e..3025810d2 100644 --- a/native/jni/magiskboot/dtb.cpp +++ b/native/jni/magiskboot/dtb.cpp @@ -96,15 +96,15 @@ static int find_fstab(const void *fdt, int node = 0) { } static void dtb_print(const char *file, bool fstab) { - size_t size ; - uint8_t *dtb, *fdt; + size_t size; + uint8_t *dtb; fprintf(stderr, "Loading dtbs from [%s]\n", file); mmap_ro(file, dtb, size); // Loop through all the dtbs int dtb_num = 0; for (int i = 0; i < size; ++i) { if (memcmp(dtb + i, DTB_MAGIC, 4) == 0) { - fdt = dtb + i; + auto fdt = dtb + i; if (fstab) { int node = find_fstab(fdt); if (node >= 0) { @@ -124,6 +124,9 @@ static void dtb_print(const char *file, bool fstab) { } static void dtb_patch(const char *in, const char *out) { + bool keepverity = check_env("KEEPVERITY"); + bool redirect = check_env("REDIRSYSMNT"); + vector fdt_list; size_t dtb_sz ; uint8_t *dtb; @@ -132,24 +135,34 @@ static void dtb_patch(const char *in, const char *out) { bool modified = false; for (int i = 0; i < dtb_sz; ++i) { if (memcmp(dtb + i, DTB_MAGIC, 4) == 0) { - // Patched will only be smaller int len = fdt_totalsize(dtb + i); - auto fdt = static_cast(xmalloc(len)); + auto fdt = static_cast(xmalloc(redirect ? len + 256 : len)); memcpy(fdt, dtb + i, len); + if (redirect) + fdt_open_into(fdt, fdt, len + 256); + int fstab = find_fstab(fdt); if (fstab < 0) continue; fprintf(stderr, "Found fstab in dtb.%04d\n", fdt_list.size()); int block; fdt_for_each_subnode(block, fdt, fstab) { - fprintf(stderr, "Found entry [%s] in fstab\n", fdt_get_name(fdt, block, nullptr)); - uint32_t size; - auto value = static_cast( - fdt_getprop(fdt, block, "fsmgr_flags", reinterpret_cast(&size))); - char *pval = patch_verity(value, size); - if (pval) { + const char *name = fdt_get_name(fdt, block, nullptr); + fprintf(stderr, "Found entry [%s] in fstab\n", name); + if (!keepverity) { + uint32_t size; + auto value = static_cast( + fdt_getprop(fdt, block, "fsmgr_flags", reinterpret_cast(&size))); + char *pval = patch_verity(value, size); + if (pval) { + modified = true; + fdt_setprop_string(fdt, block, "fsmgr_flags", pval); + } + } + if (redirect && name == "system"sv) { modified = true; - fdt_setprop_string(fdt, block, "fsmgr_flags", pval); + fprintf(stderr, "Changing mnt_point to /system_root\n"); + fdt_setprop_string(fdt, block, "mnt_point", "/system_root"); } } fdt_list.push_back(fdt); diff --git a/native/jni/magiskboot/magiskboot.h b/native/jni/magiskboot/magiskboot.h index 9a9f3211c..f51c7e8e3 100644 --- a/native/jni/magiskboot/magiskboot.h +++ b/native/jni/magiskboot/magiskboot.h @@ -12,13 +12,12 @@ #define DTB_FILE "dtb" #define NEW_BOOT "new-boot.img" -// Main entries int unpack(const char *image, bool hdr = false); void repack(const char* orig_image, const char* out_image, bool force_nocomp = false); int hexpatch(const char *image, const char *from, const char *to); int cpio_commands(int argc, char *argv[]); int dtb_commands(int argc, char *argv[]); -// Pattern char *patch_verity(const void *buf, uint32_t &size); void patch_encryption(void **buf, uint32_t *size); +bool check_env(const char *name); diff --git a/native/jni/magiskboot/ramdisk.cpp b/native/jni/magiskboot/ramdisk.cpp index 447bdbf0c..915ebd22d 100644 --- a/native/jni/magiskboot/ramdisk.cpp +++ b/native/jni/magiskboot/ramdisk.cpp @@ -10,7 +10,7 @@ using namespace std; -static const char *ramdisk_xz = "ramdisk.cpio.xz"; +constexpr char RAMDISK_XZ[] = "ramdisk.cpio.xz"; static const char *UNSUPPORT_LIST[] = { "sbin/launch_daemonsu.sh", "sbin/su", "init.xposed.rc", @@ -33,7 +33,7 @@ public: void decompress(); }; -static bool check_env(const char *name) { +bool check_env(const char *name) { const char *val = getenv(name); return val ? strcmp(val, "true") == 0 : false; } @@ -74,28 +74,41 @@ void magisk_cpio::patch() { } #define STOCK_BOOT 0 -#define MAGISK_PATCHED 1 << 0 -#define UNSUPPORTED_CPIO 1 << 1 -#define COMPRESSED_CPIO 1 << 2 -int magisk_cpio::test() { - if (exists(ramdisk_xz)) - return MAGISK_PATCHED | COMPRESSED_CPIO; +#define MAGISK_PATCHED (1 << 0) +#define UNSUPPORTED_CPIO (1 << 1) +#define COMPRESSED_CPIO (1 << 2) +#define TWO_STAGE_INIT (1 << 3) +int magisk_cpio::test() { for (auto file : UNSUPPORT_LIST) if (exists(file)) return UNSUPPORTED_CPIO; - for (auto file : MAGISK_LIST) - if (exists(file)) - return MAGISK_PATCHED; + int flags = STOCK_BOOT; - return STOCK_BOOT; + if (exists(RAMDISK_XZ)) { + flags |= COMPRESSED_CPIO | MAGISK_PATCHED; + decompress(); + } + + if (exists("apex") || exists("first_stage_ramdisk")) + flags |= TWO_STAGE_INIT; + + for (auto file : MAGISK_LIST) { + if (exists(file)) { + flags |= MAGISK_PATCHED; + break; + } + } + + return flags; } #define for_each_line(line, buf, size) \ for (line = (char *) buf; line < (char *) buf + size && line[0]; line = strchr(line + 1, '\n') + 1) char *magisk_cpio::sha1() { + decompress(); char sha1[41]; char *line; for (auto &e : entries) { @@ -231,32 +244,26 @@ void magisk_cpio::backup(const char *orig) { } void magisk_cpio::compress() { - if (exists(ramdisk_xz)) + if (exists(RAMDISK_XZ)) return; - fprintf(stderr, "Compressing cpio -> [%s]\n", ramdisk_xz); + fprintf(stderr, "Compressing cpio -> [%s]\n", RAMDISK_XZ); auto init = entries.extract("init"); XZEncoder encoder; encoder.set_out(make_unique()); output(encoder); encoder.finalize(); - auto backup = entries.extract(".backup"); - auto config = entries.extract(".backup/.magisk"); entries.clear(); entries.insert(std::move(init)); - entries.insert(std::move(backup)); - entries.insert(std::move(config)); - auto xz = new cpio_entry(ramdisk_xz, S_IFREG); + auto xz = new cpio_entry(RAMDISK_XZ, S_IFREG); static_cast(encoder.get_out())->release(xz->data, xz->filesize); insert(xz); } void magisk_cpio::decompress() { - auto it = entries.find(ramdisk_xz); + auto it = entries.find(RAMDISK_XZ); if (it == entries.end()) return; - fprintf(stderr, "Decompressing cpio [%s]\n", ramdisk_xz); - entries.erase(".backup"); - entries.erase(".backup/.magisk"); + fprintf(stderr, "Decompressing cpio [%s]\n", RAMDISK_XZ); LZMADecoder decoder; decoder.set_out(make_unique()); decoder.write(it->second->data, it->second->filesize); diff --git a/scripts/boot_patch.sh b/scripts/boot_patch.sh index 82a22dc26..575fbf5ed 100644 --- a/scripts/boot_patch.sh +++ b/scripts/boot_patch.sh @@ -113,7 +113,7 @@ case $((STATUS & 3)) in 1 ) # Magisk patched ui_print "- Magisk patched boot image detected" # Find SHA1 of stock boot image - [ -z $SHA1 ] && SHA1=`./magiskboot --cpio ramdisk.cpio sha1 2>/dev/null` + [ -z $SHA1 ] && SHA1=`./magiskboot cpio ramdisk.cpio sha1 2>/dev/null` ./magiskboot cpio ramdisk.cpio restore if ./magiskboot cpio ramdisk.cpio "exists init.rc"; then # Normal boot image @@ -129,6 +129,11 @@ case $((STATUS & 3)) in ;; esac +if [ $((STATUS & 8)) -ne 0 ]; then + ui_print "- 2 Stage Init ramdisk detected" + export REDIRSYSMNT=true +fi + ########################################################################################## # Ramdisk patches ########################################################################################## @@ -149,7 +154,7 @@ echo "RECOVERYMODE=$RECOVERYMODE" >> config if [ $((STATUS & 4)) -ne 0 ]; then ui_print "- Compressing ramdisk" - ./magiskboot --cpio ramdisk.cpio compress + ./magiskboot cpio ramdisk.cpio compress fi rm -f ramdisk.cpio.orig config @@ -158,11 +163,9 @@ rm -f ramdisk.cpio.orig config # Binary patches ########################################################################################## -if ! $KEEPVERITY; then - for dt in dtb kernel_dtb extra recovery_dtbo; do - [ -f $dt ] && ./magiskboot dtb $dt patch && ui_print "- Removing dm(avb)-verity in $dt" - done -fi +for dt in dtb kernel_dtb extra recovery_dtbo; do + [ -f $dt ] && ./magiskboot dtb $dt patch && ui_print "- Patching fstab in $dt" +done if [ -f kernel ]; then # Remove Samsung RKP