From 63b18246d8666593319e3bc8a4cf3d67bea236a8 Mon Sep 17 00:00:00 2001 From: topjohnwu Date: Sun, 24 Feb 2019 20:39:01 -0500 Subject: [PATCH] Add compressed ramdisk support --- .../magisk/tasks/MagiskInstaller.java | 3 ++- native/jni/core/init.cpp | 22 +++++++++++++++++- native/jni/magiskboot/ramdisk.cpp | 23 ++++++++++++++----- native/jni/utils/include/OutStream.h | 2 ++ scripts/boot_patch.sh | 11 +++++++-- scripts/flash_script.sh | 10 +++++++- scripts/util_functions.sh | 6 ++--- 7 files changed, 63 insertions(+), 14 deletions(-) diff --git a/app-core/src/main/java/com/topjohnwu/magisk/tasks/MagiskInstaller.java b/app-core/src/main/java/com/topjohnwu/magisk/tasks/MagiskInstaller.java index c9ab50122..d4c56a443 100644 --- a/app-core/src/main/java/com/topjohnwu/magisk/tasks/MagiskInstaller.java +++ b/app-core/src/main/java/com/topjohnwu/magisk/tasks/MagiskInstaller.java @@ -222,7 +222,8 @@ public abstract class MagiskInstaller { Config.keepEnc, Config.keepVerity, srcBoot)).to(console, logs).exec().isSuccess()) return false; - job = Shell.sh("mv bin/busybox busybox", + job = Shell.sh("./magiskboot --cleanup", + "mv bin/busybox busybox", "rm -rf magisk.apk bin boot.img update-binary", "cd /"); diff --git a/native/jni/core/init.cpp b/native/jni/core/init.cpp index e05394963..f7a9a9daf 100644 --- a/native/jni/core/init.cpp +++ b/native/jni/core/init.cpp @@ -30,7 +30,6 @@ #include #include #include -#include #include #include #include @@ -40,6 +39,7 @@ #include #include #include +#include #include #include @@ -320,6 +320,24 @@ static bool unxz(int fd, const uint8_t *buf, size_t size) { return true; } +static void decompress_ramdisk() { + constexpr char tmp[] = "tmp.cpio"; + constexpr char ramdisk_xz[] = "ramdisk.cpio.xz"; + if (access(ramdisk_xz, F_OK)) + return; + uint8_t *buf; + size_t sz; + mmap_ro(ramdisk_xz, (void **) &buf, &sz); + int fd = open(tmp, O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC); + unxz(fd, buf, sz); + munmap(buf, sz); + close(fd); + cpio_mmap cpio(tmp); + cpio.extract(); + unlink(tmp); + unlink(ramdisk_xz); +} + static int dump_magisk(const char *path, mode_t mode) { int fd = open(path, O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, mode); if (fd < 0) @@ -496,6 +514,8 @@ int main(int argc, char *argv[]) { frm_rf(root); excl_list = nullptr; } else { + decompress_ramdisk(); + // Revert original init binary rename("/.backup/init", "/init"); rm_rf("/.backup"); diff --git a/native/jni/magiskboot/ramdisk.cpp b/native/jni/magiskboot/ramdisk.cpp index 23d94c612..632f1a16e 100644 --- a/native/jni/magiskboot/ramdisk.cpp +++ b/native/jni/magiskboot/ramdisk.cpp @@ -18,7 +18,7 @@ static const char *UNSUPPORT_LIST[] = static const char *MAGISK_LIST[] = { ".backup/.magisk", "init.magisk.rc", - "overlay/init.magisk.rc", ramdisk_xz }; + "overlay/init.magisk.rc" }; class magisk_cpio : public cpio_rw { public: @@ -59,17 +59,21 @@ void magisk_cpio::patch(bool keepverity, bool keepforceencrypt) { } } -#define STOCK_BOOT 0x0 -#define MAGISK_PATCH 0x1 -#define UNSUPPORT_PATCH 0x2 +#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; + for (auto file : UNSUPPORT_LIST) if (exists(file)) - return UNSUPPORT_PATCH; + return UNSUPPORTED_CPIO; for (auto file : MAGISK_LIST) if (exists(file)) - return MAGISK_PATCH; + return MAGISK_PATCHED; return STOCK_BOOT; } @@ -108,6 +112,7 @@ char *magisk_cpio::sha1() { for (str = (char *) buf; str < (char *) buf + size; str = str += strlen(str) + 1) void magisk_cpio::restore() { + decompress(); char *file; auto next = entries.begin(); decltype(next) cur; @@ -218,8 +223,12 @@ void magisk_cpio::compress() { 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); static_cast(encoder.get_out())->release(xz->data, xz->filesize); insert(xz); @@ -230,6 +239,8 @@ void magisk_cpio::decompress() { if (it == entries.end()) return; fprintf(stderr, "Decompressing cpio [%s]\n", ramdisk_xz); + entries.erase(".backup"); + entries.erase(".backup/.magisk"); LZMADecoder decoder; decoder.set_out(make_unique()); decoder.write(it->second->data, it->second->filesize); diff --git a/native/jni/utils/include/OutStream.h b/native/jni/utils/include/OutStream.h index 88715e982..bcb3925b9 100644 --- a/native/jni/utils/include/OutStream.h +++ b/native/jni/utils/include/OutStream.h @@ -3,6 +3,8 @@ #include #include +#include "utils.h" + class OutStream { public: virtual bool write(const void *buf, size_t len) = 0; diff --git a/scripts/boot_patch.sh b/scripts/boot_patch.sh index 4c4836335..813684064 100644 --- a/scripts/boot_patch.sh +++ b/scripts/boot_patch.sh @@ -90,7 +90,8 @@ esac # Test patch status and do restore, after this section, ramdisk.cpio.orig is guaranteed to exist ui_print "- Checking ramdisk status" ./magiskboot --cpio ramdisk.cpio test -case $? in +STATUS=$? +case $((STATUS & 3)) in 0 ) # Stock boot ui_print "- Stock boot image detected" ui_print "- Backing up stock boot image" @@ -128,6 +129,11 @@ echo "KEEPFORCEENCRYPT=$KEEPFORCEENCRYPT" >> config "backup ramdisk.cpio.orig" \ "add 000 .backup/.magisk config" +if [ $((STATUS & 4)) -ne 0 ]; then + ui_print "- Compressing ramdisk" + ./magiskboot --cpio ramdisk.cpio compress +fi + rm -f ramdisk.cpio.orig config ########################################################################################## @@ -167,4 +173,5 @@ ui_print "- Repacking boot image" # Sign chromeos boot $CHROMEOS && sign_chromeos -./magiskboot --cleanup +# Reset any error code +true diff --git a/scripts/flash_script.sh b/scripts/flash_script.sh index bcc9a7c54..21cb83273 100644 --- a/scripts/flash_script.sh +++ b/scripts/flash_script.sh @@ -106,7 +106,15 @@ $IS64BIT && mv -f magiskinit64 magiskinit || rm -f magiskinit64 . ./boot_patch.sh "$BOOTIMAGE" ui_print "- Flashing new boot image" -flash_image new-boot.img "$BOOTIMAGE" || abort "! Insufficient partition size" + +if ! flash_image new-boot.img "$BOOTIMAGE"; then + ui_print "- Compressing ramdisk to fit in partition" + ./magiskboot --cpio ramdisk.cpio compress + ./magiskboot --repack "$BOOTIMAGE" + flash_image new-boot.img "$BOOTIMAGE" || abort "! Insufficient partition size" +fi + +./magiskboot --cleanup rm -f new-boot.img if [ -f stock_boot* ]; then diff --git a/scripts/util_functions.sh b/scripts/util_functions.sh index be71322af..c275ad023 100644 --- a/scripts/util_functions.sh +++ b/scripts/util_functions.sh @@ -256,9 +256,9 @@ flash_image() { CMD2="cat -" fi if [ -b "$2" ]; then - local s_size=`stat -c '%s' "$1"` - local t_size=`blockdev --getsize64 "$2"` - [ $s_size -gt $t_size ] && return 1 + local img_sz=`stat -c '%s' "$1"` + local blk_sz=`blockdev --getsize64 "$2"` + [ $img_sz -gt $blk_sz ] && return 1 eval $CMD1 | eval $CMD2 | cat - /dev/zero > "$2" 2>/dev/null else ui_print "- Not block device, storing image"