From 6663fd3526f6a104755b2beed7ad2e81f01a81c7 Mon Sep 17 00:00:00 2001 From: Chris Renshaw Date: Sat, 30 Oct 2021 22:59:20 -0300 Subject: [PATCH] Support custom legacy Sony devices with init.real setup Custom ROM bring-ups of legacy Sony devices contain the following: /init (symlink to /bin/init_sony) /init.real (the "real" Android init) /bin/init_sony (this was /sbin/init_sony on Android <11) Kernel loads the ramdisk and starts /init -> /bin/init_sony /bin/init_sony does low-level device setup (see: https://github.com/LineageOS/android_device_sony_common/blob/lineage-18.1/init/init_main.cpp) /bin/init_sony unlinks /init and renames /init.real to /init /bin/init_sony starts /init Since init_sony needs to run first magiskinit needs to replace init.real instead, so add workarounds based on detection of init.real to boot patcher and uninstaller Thanks @115ek and @bleckdeth Fixes #3636 Co-authored-by: topjohnwu --- native/jni/init/getinfo.cpp | 8 +++++++- native/jni/init/init.cpp | 2 +- native/jni/init/init.hpp | 1 + native/jni/init/mount.cpp | 2 +- native/jni/init/twostage.cpp | 4 ++-- native/jni/magiskboot/main.cpp | 6 +++--- native/jni/magiskboot/ramdisk.cpp | 10 +++++++--- scripts/boot_patch.sh | 16 +++++++++++++++- scripts/uninstaller.sh | 4 ++++ 9 files changed, 41 insertions(+), 12 deletions(-) diff --git a/native/jni/init/getinfo.cpp b/native/jni/init/getinfo.cpp index 42fba9263..d19489911 100644 --- a/native/jni/init/getinfo.cpp +++ b/native/jni/init/getinfo.cpp @@ -252,6 +252,12 @@ bool check_two_stage() { if (access("/system/bin/init", F_OK) == 0) return true; // If we still have no indication, parse the original init and see what's up - auto init = mmap_data::ro("/.backup/init"); + auto init = mmap_data::ro(backup_init()); return init.contains("selinux_setup"); } + +const char *backup_init() { + if (access("/.backup/init.real", F_OK) == 0) + return "/.backup/init.real"; + return "/.backup/init"; +} diff --git a/native/jni/init/init.cpp b/native/jni/init/init.cpp index de0a261b3..db366eb83 100644 --- a/native/jni/init/init.cpp +++ b/native/jni/init/init.cpp @@ -59,7 +59,7 @@ public: RecoveryInit(char *argv[], BootConfig *cmd) : BaseInit(argv, cmd) {} void start() override { LOGD("Ramdisk is recovery, abort\n"); - rename("/.backup/init", "/init"); + rename(backup_init(), "/init"); rm_rf("/.backup"); exec_init(); } diff --git a/native/jni/init/init.hpp b/native/jni/init/init.hpp index 88edd6864..8b78137f3 100644 --- a/native/jni/init/init.hpp +++ b/native/jni/init/init.hpp @@ -40,6 +40,7 @@ bool unxz(int fd, const uint8_t *buf, size_t size); void load_kernel_info(BootConfig *config); bool check_two_stage(); void setup_klog(); +const char *backup_init(); /*************** * Base classes diff --git a/native/jni/init/mount.cpp b/native/jni/init/mount.cpp index 527440e90..32d7b17ad 100644 --- a/native/jni/init/mount.cpp +++ b/native/jni/init/mount.cpp @@ -289,7 +289,7 @@ void RootFSInit::early_mount() { self = mmap_data::ro("/init"); LOGD("Restoring /init\n"); - rename("/.backup/init", "/init"); + rename(backup_init(), "/init"); mount_with_dt(); } diff --git a/native/jni/init/twostage.cpp b/native/jni/init/twostage.cpp index 639e727e6..405f66fb2 100644 --- a/native/jni/init/twostage.cpp +++ b/native/jni/init/twostage.cpp @@ -61,7 +61,7 @@ void FirstStageInit::prepare() { xmkdirs(FSR "/system/bin", 0755); rename("/init" /* magiskinit */, FSR "/system/bin/init"); symlink("/system/bin/init", FSR "/init"); - rename("/.backup/init", "/init"); + rename(backup_init(), "/init"); rename("/.backup", FSR "/.backup"); rename("/overlay.d", FSR "/overlay.d"); @@ -71,7 +71,7 @@ void FirstStageInit::prepare() { xmkdir("/system", 0755); xmkdir("/system/bin", 0755); rename("/init" /* magiskinit */ , "/system/bin/init"); - rename("/.backup/init", "/init"); + rename(backup_init(), "/init"); } char fstab_file[128]; diff --git a/native/jni/magiskboot/main.cpp b/native/jni/magiskboot/main.cpp index f78ce163b..b8cfa6e0b 100644 --- a/native/jni/magiskboot/main.cpp +++ b/native/jni/magiskboot/main.cpp @@ -58,9 +58,9 @@ Supported actions: extract [ENTRY OUT] Extract ENTRY to OUT, or extract all entries to current directory test - Test the current cpio's patch status - Return values: - 0:stock 1:Magisk 2:unsupported (phh, SuperSU, Xposed) + Test the current cpio's status + Return value is 0 or bitwise or-ed of following values: + 0x1:Magisk 0x2:unsupported 0x4:Sony patch Apply ramdisk patches Configure with env variables: KEEPVERITY KEEPFORCEENCRYPT diff --git a/native/jni/magiskboot/ramdisk.cpp b/native/jni/magiskboot/ramdisk.cpp index 7b928e0af..270875f90 100644 --- a/native/jni/magiskboot/ramdisk.cpp +++ b/native/jni/magiskboot/ramdisk.cpp @@ -59,11 +59,12 @@ void magisk_cpio::patch() { } } -#define STOCK_BOOT 0 #define MAGISK_PATCHED (1 << 0) #define UNSUPPORTED_CPIO (1 << 1) +#define SONY_INIT (1 << 2) int magisk_cpio::test() { + int ret = 0; for (auto file : UNSUPPORT_LIST) { if (exists(file)) { return UNSUPPORTED_CPIO; @@ -71,10 +72,13 @@ int magisk_cpio::test() { } for (auto file : MAGISK_LIST) { if (exists(file)) { - return MAGISK_PATCHED; + ret |= MAGISK_PATCHED; + break; } } - return STOCK_BOOT; + if (exists("init.real")) + ret |= SONY_INIT; + return ret; } #define for_each_line(line, buf, size) \ diff --git a/scripts/boot_patch.sh b/scripts/boot_patch.sh index bce2c742e..99d62e0bd 100644 --- a/scripts/boot_patch.sh +++ b/scripts/boot_patch.sh @@ -135,6 +135,12 @@ case $((STATUS & 3)) in ;; esac +# Work around custom legacy Sony /init -> /(s)bin/init_sony : /init.real setup +INIT=init +if [ $((status & 0x4)) -ne 0 ]; then + INIT=init.real +fi + ################## # Ramdisk Patches ################## @@ -158,8 +164,16 @@ if [ -f magisk64 ]; then unset SKIP64 fi +# Work around custom legacy Sony /init -> /(s)bin/init_sony : /init.real setup +INIT=init +SKIPSONY="#" +if ./magiskboot cpio ramdisk.cpio "exists init.real"; then + INIT=init.real + unset SKIPSONY +fi + ./magiskboot cpio ramdisk.cpio \ -"add 0750 init magiskinit" \ +"add 0750 $INIT magiskinit" \ "mkdir 0750 overlay.d" \ "mkdir 0750 overlay.d/sbin" \ "$SKIP32 add 0644 overlay.d/sbin/magisk32.xz magisk32.xz" \ diff --git a/scripts/uninstaller.sh b/scripts/uninstaller.sh index ed5309c95..6e9537da0 100644 --- a/scripts/uninstaller.sh +++ b/scripts/uninstaller.sh @@ -125,6 +125,10 @@ case $((STATUS & 3)) in else ui_print "! Boot image backup unavailable" ui_print "- Restoring ramdisk with internal backup" + if ./magiskboot cpio ramdisk.cpio "exists init.real"; then + # Work around custom legacy Sony /init -> /(s)bin/init_sony : /init.real setup + ./magiskboot cpio ramdisk.cpio "mv .backup/init .backup/init.real" + fi ./magiskboot cpio ramdisk.cpio restore if ! ./magiskboot cpio ramdisk.cpio "exists init"; then # A only system-as-root