From e72c6685edf81706617a3444575c4500b9b8fe6c Mon Sep 17 00:00:00 2001 From: topjohnwu Date: Thu, 28 Feb 2019 05:46:36 -0500 Subject: [PATCH] Support A only System-as-root Devices Most Chinese devices (and supposedly Galaxy S10) running Android Pie is using system-as-root without A/B partition. https://source.android.com/devices/bootloader/system-as-root#about-system-as-root According to the docs above, these devices will have a ramdisk block with size 0 in their boot images. Since magiskinit can run independently on system-as-root devices, we simply just create an empty ramdisk with magiskinit added as init. Huge thanks to @vvb2060 for the heads up and original PR. Close #980, close #1102 --- native/jni/magiskboot/ramdisk.cpp | 9 +++++++-- native/jni/utils/cpio.cpp | 18 +++++++++++------- native/jni/utils/include/cpio.h | 10 ++++++---- scripts/boot_patch.sh | 26 +++++++++++++++++++------- 4 files changed, 43 insertions(+), 20 deletions(-) diff --git a/native/jni/magiskboot/ramdisk.cpp b/native/jni/magiskboot/ramdisk.cpp index 25668ce1d..d613f59a0 100644 --- a/native/jni/magiskboot/ramdisk.cpp +++ b/native/jni/magiskboot/ramdisk.cpp @@ -22,6 +22,7 @@ static const char *MAGISK_LIST[] = class magisk_cpio : public cpio_rw { public: + magisk_cpio() = default; explicit magisk_cpio(const char *filename) : cpio_rw(filename) {} void patch(bool keepverity, bool keepforceencrypt); int test(); @@ -140,6 +141,8 @@ void magisk_cpio::restore() { } void magisk_cpio::backup(const char *orig) { + if (access(orig, R_OK)) + return; entry_map bkup_entries; string remv; @@ -257,7 +260,9 @@ int cpio_commands(int argc, char *argv[]) { ++argv; --argc; - magisk_cpio cpio(incpio); + magisk_cpio cpio; + if (access(incpio, R_OK) == 0) + cpio.load_cpio(incpio); int cmdc; char *cmdv[6]; @@ -305,7 +310,7 @@ int cpio_commands(int argc, char *argv[]) { return 0; } } else if (cmdc == 3 && strcmp(cmdv[0], "mkdir") == 0) { - cpio.makedir(strtoul(cmdv[1], nullptr, 8), cmdv[2]); + cpio.mkdir(strtoul(cmdv[1], nullptr, 8), cmdv[2]); } else if (cmdc == 3 && strcmp(cmdv[0], "ln") == 0) { cpio.ln(cmdv[1], cmdv[2]); } else if (cmdc == 4 && strcmp(cmdv[0], "add") == 0) { diff --git a/native/jni/utils/cpio.cpp b/native/jni/utils/cpio.cpp index c5fcb6e47..89840c98d 100644 --- a/native/jni/utils/cpio.cpp +++ b/native/jni/utils/cpio.cpp @@ -149,11 +149,15 @@ void cpio::output(OutStream &out) { out_align(); } -cpio_rw::cpio_rw(const char *filename) { +cpio_rw::cpio_rw(const char *file) { + load_cpio(file); +} + +void cpio_rw::load_cpio(const char *file) { char *buf; size_t sz; - mmap_ro(filename, buf, sz); - fprintf(stderr, "Loading cpio: [%s]\n", filename); + mmap_ro(file, buf, sz); + fprintf(stderr, "Loading cpio: [%s]\n", file); load_cpio(buf, sz); munmap(buf, sz); } @@ -182,7 +186,7 @@ void cpio_rw::add(mode_t mode, const char *name, const char *file) { fprintf(stderr, "Add entry [%s] (%04o)\n", name, mode); } -void cpio_rw::makedir(mode_t mode, const char *name) { +void cpio_rw::mkdir(mode_t mode, const char *name) { insert(new cpio_entry(name, S_IFDIR | mode)); fprintf(stderr, "Create directory [%s] (%04o)\n", name, mode); } @@ -241,9 +245,9 @@ void cpio_rw::load_cpio(char *buf, size_t sz) { } } -cpio_mmap::cpio_mmap(const char *filename) { - mmap_ro(filename, buf, sz); - fprintf(stderr, "Loading cpio: [%s]\n", filename); +cpio_mmap::cpio_mmap(const char *file) { + mmap_ro(file, buf, sz); + fprintf(stderr, "Loading cpio: [%s]\n", file); size_t pos = 0; cpio_newc_header *header; unique_ptr entry; diff --git a/native/jni/utils/include/cpio.h b/native/jni/utils/include/cpio.h index b24e5183a..7ffa169d5 100644 --- a/native/jni/utils/include/cpio.h +++ b/native/jni/utils/include/cpio.h @@ -53,21 +53,23 @@ protected: class cpio_rw : public cpio { public: - explicit cpio_rw(const char *filename); - void insert(cpio_entry *e); + cpio_rw() = default; + explicit cpio_rw(const char *file); + void load_cpio(const char *file); void add(mode_t mode, const char *name, const char *file); - void makedir(mode_t mode, const char *name); + void mkdir(mode_t mode, const char *name); void ln(const char *target, const char *name); bool mv(const char *from, const char *to); protected: + void insert(cpio_entry *e); void mv(entry_map::iterator &it, const char *to); void load_cpio(char *buf, size_t sz); }; class cpio_mmap : public cpio { public: - explicit cpio_mmap(const char *filename); + explicit cpio_mmap(const char *file); ~cpio_mmap(); private: char *buf; diff --git a/scripts/boot_patch.sh b/scripts/boot_patch.sh index 813684064..1d35757a9 100644 --- a/scripts/boot_patch.sh +++ b/scripts/boot_patch.sh @@ -87,10 +87,15 @@ esac # Ramdisk restores ########################################################################################## -# Test patch status and do restore, after this section, ramdisk.cpio.orig is guaranteed to exist +# Test patch status and do restore ui_print "- Checking ramdisk status" -./magiskboot --cpio ramdisk.cpio test -STATUS=$? +if [ -e ramdisk.cpio ]; then + ./magiskboot --cpio ramdisk.cpio test + STATUS=$? +else + # Stock A only system-as-root + STATUS=0 +fi case $((STATUS & 3)) in 0 ) # Stock boot ui_print "- Stock boot image detected" @@ -98,18 +103,24 @@ case $((STATUS & 3)) in SHA1=`./magiskboot --sha1 "$BOOTIMAGE" 2>/dev/null` STOCKDUMP=stock_boot_${SHA1}.img.gz ./magiskboot --compress "$BOOTIMAGE" $STOCKDUMP - cp -af ramdisk.cpio ramdisk.cpio.orig + cp -af ramdisk.cpio ramdisk.cpio.orig 2>/dev/null ;; 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` ./magiskboot --cpio ramdisk.cpio restore - cp -af ramdisk.cpio ramdisk.cpio.orig + if ./magiskboot --cpio ramdisk.cpio "exists init.rc"; then + # Normal boot image + cp -af ramdisk.cpio ramdisk.cpio.orig + else + # A only system-as-root + rm -f ramdisk.cpio + fi ;; - 2 ) # Other patched + 2 ) # Unsupported ui_print "! Boot image patched by unsupported programs" - abort "! Please restore stock boot image" + abort "! Please restore back to stock boot image" ;; esac @@ -127,6 +138,7 @@ echo "KEEPFORCEENCRYPT=$KEEPFORCEENCRYPT" >> config "add 750 init magiskinit" \ "patch $KEEPVERITY $KEEPFORCEENCRYPT" \ "backup ramdisk.cpio.orig" \ +"mkdir 000 .backup" \ "add 000 .backup/.magisk config" if [ $((STATUS & 4)) -ne 0 ]; then