diff --git a/manager/app/src/main/jniLibs/arm64-v8a/libmagiskboot.so b/manager/app/src/main/jniLibs/arm64-v8a/libmagiskboot.so index 451ca81c42d8..ce7478d6bcc1 100644 Binary files a/manager/app/src/main/jniLibs/arm64-v8a/libmagiskboot.so and b/manager/app/src/main/jniLibs/arm64-v8a/libmagiskboot.so differ diff --git a/userspace/ksud/src/boot_patch.rs b/userspace/ksud/src/boot_patch.rs index 4744e3d17b56..2a4875349879 100644 --- a/userspace/ksud/src/boot_patch.rs +++ b/userspace/ksud/src/boot_patch.rs @@ -153,38 +153,40 @@ fn parse_kmi_from_boot(magiskboot: &Path, image: &PathBuf, workdir: &Path) -> Re parse_kmi_from_kernel(&image_path, workdir) } -fn do_cpio_cmd(magiskboot: &Path, workdir: &Path, cmd: &str) -> Result<()> { +fn do_cpio_cmd(magiskboot: &Path, workdir: &Path, cpio_path: &Path, cmd: &str) -> Result<()> { let status = Command::new(magiskboot) .current_dir(workdir) .stdout(Stdio::null()) .stderr(Stdio::null()) .arg("cpio") - .arg("ramdisk.cpio") + .arg(cpio_path) .arg(cmd) .status()?; - ensure!(status.success(), "magiskboot cpio {} failed", cmd); Ok(()) } -fn is_magisk_patched(magiskboot: &Path, workdir: &Path) -> Result { +fn is_magisk_patched(magiskboot: &Path, workdir: &Path, cpio_path: &Path) -> Result { let status = Command::new(magiskboot) .current_dir(workdir) .stdout(Stdio::null()) .stderr(Stdio::null()) - .args(["cpio", "ramdisk.cpio", "test"]) + .arg("cpio") + .arg(cpio_path) + .arg("test") .status()?; - // 0: stock, 1: magisk Ok(status.code() == Some(1)) } -fn is_kernelsu_patched(magiskboot: &Path, workdir: &Path) -> Result { +fn is_kernelsu_patched(magiskboot: &Path, workdir: &Path, cpio_path: &Path) -> Result { let status = Command::new(magiskboot) .current_dir(workdir) .stdout(Stdio::null()) .stderr(Stdio::null()) - .args(["cpio", "ramdisk.cpio", "exists kernelsu.ko"]) + .arg("cpio") + .arg(cpio_path) + .arg("exists kernelsu.ko") .status()?; Ok(status.success()) @@ -234,17 +236,36 @@ pub fn restore( .status()?; ensure!(status.success(), "magiskboot unpack failed"); - let is_kernelsu_patched = is_kernelsu_patched(&magiskboot, workdir)?; + let mut ramdisk = workdir.join("ramdisk.cpio"); + if !ramdisk.exists() { + ramdisk = workdir.join("vendor_ramdisk").join("init_boot.cpio") + } + if !ramdisk.exists() { + ramdisk = workdir.join("vendor_ramdisk").join("ramdisk.cpio"); + } + if !ramdisk.exists() { + bail!("No compatible ramdisk found.") + } + let ramdisk = ramdisk.as_path(); + let is_kernelsu_patched = is_kernelsu_patched(&magiskboot, workdir, ramdisk)?; ensure!(is_kernelsu_patched, "boot image is not patched by KernelSU"); let mut new_boot = None; let mut from_backup = false; #[cfg(target_os = "android")] - if do_cpio_cmd(&magiskboot, workdir, &format!("exists {BACKUP_FILENAME}")).is_ok() { + if do_cpio_cmd( + &magiskboot, + workdir, + ramdisk, + &format!("exists {BACKUP_FILENAME}"), + ) + .is_ok() + { do_cpio_cmd( &magiskboot, workdir, + ramdisk, &format!("extract {BACKUP_FILENAME} {BACKUP_FILENAME}"), )?; let sha = std::fs::read(workdir.join(BACKUP_FILENAME))?; @@ -268,15 +289,12 @@ pub fn restore( if new_boot.is_none() { // remove kernelsu.ko - do_cpio_cmd(&magiskboot, workdir, "rm kernelsu.ko")?; + do_cpio_cmd(&magiskboot, workdir, ramdisk, "rm kernelsu.ko")?; // if init.real exists, restore it - let status = do_cpio_cmd(&magiskboot, workdir, "exists init.real").is_ok(); + let status = do_cpio_cmd(&magiskboot, workdir, ramdisk, "exists init.real").is_ok(); if status { - do_cpio_cmd(&magiskboot, workdir, "mv init.real init")?; - } else { - let ramdisk = workdir.join("ramdisk.cpio"); - std::fs::remove_file(ramdisk)?; + do_cpio_cmd(&magiskboot, workdir, ramdisk, "mv init.real init")?; } println!("- Repacking boot image"); @@ -285,7 +303,7 @@ pub fn restore( .stdout(Stdio::null()) .stderr(Stdio::null()) .arg("repack") - .arg(bootimage.display().to_string()) + .arg(&bootimage) .status()?; ensure!(status.success(), "magiskboot repack failed"); new_boot = Some(workdir.join("new-boot.img")); @@ -409,7 +427,7 @@ fn do_patch( let (bootimage, bootdevice) = find_boot_image(&image, skip_init, ota, is_replace_kernel, workdir)?; - let bootimage = bootimage.display().to_string(); + let bootimage = bootimage.as_path(); // try extract magiskboot/bootctl let _ = assets::ensure_binaries(false); @@ -438,48 +456,54 @@ fn do_patch( assets::copy_assets_to_file("ksuinit", init_file).context("copy ksuinit failed")?; } - // magiskboot unpack boot.img - // magiskboot cpio ramdisk.cpio 'cp init init.real' - // magiskboot cpio ramdisk.cpio 'add 0755 ksuinit init' - // magiskboot cpio ramdisk.cpio 'add 0755 kernelsu.ko' - println!("- Unpacking boot image"); let status = Command::new(&magiskboot) .current_dir(workdir) .stdout(Stdio::null()) .stderr(Stdio::null()) .arg("unpack") - .arg(&bootimage) + .arg(bootimage) .status()?; ensure!(status.success(), "magiskboot unpack failed"); - let no_ramdisk = !workdir.join("ramdisk.cpio").exists(); - let is_magisk_patched = is_magisk_patched(&magiskboot, workdir)?; - ensure!( - no_ramdisk || !is_magisk_patched, - "Cannot work with Magisk patched image" - ); + let mut ramdisk = workdir.join("ramdisk.cpio"); + if !ramdisk.exists() { + ramdisk = workdir.join("vendor_ramdisk").join("init_boot.cpio") + } + if !ramdisk.exists() { + ramdisk = workdir.join("vendor_ramdisk").join("ramdisk.cpio"); + } + if !ramdisk.exists() { + bail!("No compatible ramdisk found."); + } + let ramdisk = ramdisk.as_path(); + let is_magisk_patched = is_magisk_patched(&magiskboot, workdir, ramdisk)?; + ensure!(!is_magisk_patched, "Cannot work with Magisk patched image"); println!("- Adding KernelSU LKM"); - let is_kernelsu_patched = is_kernelsu_patched(&magiskboot, workdir)?; + let is_kernelsu_patched = is_kernelsu_patched(&magiskboot, workdir, ramdisk)?; let mut need_backup = false; if !is_kernelsu_patched { // kernelsu.ko is not exist, backup init if necessary - let status = do_cpio_cmd(&magiskboot, workdir, "exists init"); + let status = do_cpio_cmd(&magiskboot, workdir, ramdisk, "exists init"); if status.is_ok() { - do_cpio_cmd(&magiskboot, workdir, "mv init init.real")?; + do_cpio_cmd(&magiskboot, workdir, ramdisk, "mv init init.real")?; } - need_backup = flash; } - do_cpio_cmd(&magiskboot, workdir, "add 0755 init init")?; - do_cpio_cmd(&magiskboot, workdir, "add 0755 kernelsu.ko kernelsu.ko")?; + do_cpio_cmd(&magiskboot, workdir, ramdisk, "add 0755 init init")?; + do_cpio_cmd( + &magiskboot, + workdir, + ramdisk, + "add 0755 kernelsu.ko kernelsu.ko", + )?; #[cfg(target_os = "android")] if need_backup { - if let Err(e) = do_backup(&magiskboot, workdir, &bootimage) { + if let Err(e) = do_backup(&magiskboot, workdir, ramdisk, bootimage) { println!("- Backup stock image failed: {e}"); } } @@ -491,7 +515,7 @@ fn do_patch( .stdout(Stdio::null()) .stderr(Stdio::null()) .arg("repack") - .arg(&bootimage) + .arg(bootimage) .status()?; ensure!(status.success(), "magiskboot repack failed"); let new_boot = workdir.join("new-boot.img"); @@ -546,7 +570,7 @@ fn calculate_sha1(file_path: impl AsRef) -> Result { } #[cfg(target_os = "android")] -fn do_backup(magiskboot: &Path, workdir: &Path, image: &str) -> Result<()> { +fn do_backup(magiskboot: &Path, workdir: &Path, cpio_path: &Path, image: &Path) -> Result<()> { let sha1 = calculate_sha1(image)?; let filename = format!("{KSU_BACKUP_FILE_PREFIX}{sha1}"); @@ -558,6 +582,7 @@ fn do_backup(magiskboot: &Path, workdir: &Path, image: &str) -> Result<()> { do_cpio_cmd( magiskboot, workdir, + cpio_path, &format!("add 0755 {BACKUP_FILENAME} {BACKUP_FILENAME}"), )?; println!("- Stock image has been backup to"); @@ -655,8 +680,12 @@ fn find_boot_image( let init_boot_exist = Path::new(&format!("/dev/block/by-name/init_boot{slot_suffix}")).exists(); + let vendor_boot_exist = + Path::new(&format!("/dev/block/by-name/vendor_boot{slot_suffix}")).exists(); let boot_partition = if !is_replace_kernel && init_boot_exist && !skip_init { format!("/dev/block/by-name/init_boot{slot_suffix}") + } else if !is_replace_kernel && vendor_boot_exist && !skip_init { + format!("/dev/block/by-name/vendor_boot{slot_suffix}") } else { format!("/dev/block/by-name/boot{slot_suffix}") };