diff --git a/userspace/ksud_magic/src/boot_patch.rs b/userspace/ksud_magic/src/boot_patch.rs index c548a265..ced3265e 100644 --- a/userspace/ksud_magic/src/boot_patch.rs +++ b/userspace/ksud_magic/src/boot_patch.rs @@ -182,6 +182,21 @@ fn do_vendor_init_boot_cpio_cmd(magiskboot: &Path, workdir: &Path, cmd: &str) -> Ok(()) } +fn do_vendor_ramdisk_cpio_cmd(magiskboot: &Path, workdir: &Path, cmd: &str) -> Result<()> { + let vendor_ramdisk_cpio = workdir.join("vendor_ramdisk").join("ramdisk.cpio"); + let status = Command::new(magiskboot) + .current_dir(workdir) + .stdout(Stdio::null()) + .stderr(Stdio::null()) + .arg("cpio") + .arg(vendor_ramdisk_cpio) + .arg(cmd) + .status()?; + + ensure!(status.success(), "magiskboot cpio {} failed", cmd); + Ok(()) +} + fn is_magisk_patched(magiskboot: &Path, workdir: &Path) -> Result { let status = Command::new(magiskboot) .current_dir(workdir) @@ -207,6 +222,19 @@ fn is_magisk_patched_vendor_init_boot(magiskboot: &Path, workdir: &Path) -> Resu Ok(status.code() == Some(1)) } +fn is_magisk_patched_vendor_ramdisk(magiskboot: &Path, workdir: &Path) -> Result { + let vendor_ramdisk_cpio = workdir.join("vendor_ramdisk").join("ramdisk.cpio"); + let status = Command::new(magiskboot) + .current_dir(workdir) + .stdout(Stdio::null()) + .stderr(Stdio::null()) + .args(["cpio", vendor_ramdisk_cpio.to_str().unwrap(), "test"]) + .status()?; + + // 0: stock, 1: magisk + Ok(status.code() == Some(1)) +} + fn is_kernelsu_patched(magiskboot: &Path, workdir: &Path) -> Result { let status = Command::new(magiskboot) .current_dir(workdir) @@ -234,6 +262,22 @@ fn is_kernelsu_patched_vendor_init_boot(magiskboot: &Path, workdir: &Path) -> Re Ok(status.success()) } +fn is_kernelsu_patched_vendor_ramdisk(magiskboot: &Path, workdir: &Path) -> Result { + let vendor_ramdisk_cpio = workdir.join("vendor_ramdisk").join("ramdisk.cpio"); + let status = Command::new(magiskboot) + .current_dir(workdir) + .stdout(Stdio::null()) + .stderr(Stdio::null()) + .args([ + "cpio", + vendor_ramdisk_cpio.to_str().unwrap(), + "exists kernelsu.ko", + ]) + .status()?; + + Ok(status.success()) +} + fn dd, Q: AsRef>(ifile: P, ofile: Q) -> Result<()> { let status = Command::new("dd") .stdout(Stdio::null()) @@ -279,11 +323,21 @@ pub fn restore( ensure!(status.success(), "magiskboot unpack failed"); let no_ramdisk = !workdir.join("ramdisk.cpio").exists(); + let no_vendor_init_boot = !workdir + .join("vendor_ramdisk") + .join("init_boot.cpio") + .exists(); + let no_vendor_ramdisk = !workdir + .join("vendor_ramdisk") + .join("ramdisk.cpio") + .exists(); let is_kernelsu_patched = is_kernelsu_patched(&magiskboot, workdir)?; let is_kernelsu_patched_vendor_init_boot = is_kernelsu_patched_vendor_init_boot(&magiskboot, workdir)?; + let is_kernelsu_patched_vendor_ramdisk = + is_kernelsu_patched_vendor_ramdisk(&magiskboot, workdir)?; ensure!( - is_kernelsu_patched || is_kernelsu_patched_vendor_init_boot, + is_kernelsu_patched || is_kernelsu_patched_vendor_init_boot || is_kernelsu_patched_vendor_ramdisk, "boot image is not patched by KernelSU Next" ); @@ -318,16 +372,30 @@ pub fn restore( if new_boot.is_none() { if no_ramdisk { - // vendor init_boot restore - do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "rm kernelsu.ko")?; + if !no_vendor_init_boot { + // vendor init_boot restore + do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "rm kernelsu.ko")?; - let status = - do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "exists init.real").is_ok(); - if status { - do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "mv init.real init")?; - } else { - let vendor_init_boot = workdir.join("vendor_ramdisk").join("init_boot.cpio"); - std::fs::remove_file(vendor_init_boot)?; + let status = + do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "exists init.real").is_ok(); + if status { + do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "mv init.real init")?; + } else { + let vendor_init_boot = workdir.join("vendor_ramdisk").join("init_boot.cpio"); + std::fs::remove_file(vendor_init_boot)?; + } + } else if !no_vendor_ramdisk { + // vendor ramdisk restore + do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "rm kernelsu.ko")?; + + let status = + do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "exists init.real").is_ok(); + if status { + do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "mv init.real init")?; + } else { + let vendor_ramdisk = workdir.join("vendor_ramdisk").join("ramdisk.cpio"); + std::fs::remove_file(vendor_ramdisk)?; + } } } else { // remove kernelsu.ko @@ -517,14 +585,20 @@ fn do_patch( .join("vendor_ramdisk") .join("init_boot.cpio") .exists(); - if no_ramdisk && no_vendor_init_boot { + let no_vendor_ramdisk = !workdir + .join("vendor_ramdisk") + .join("ramdisk.cpio") + .exists(); + if no_ramdisk && no_vendor_init_boot && no_vendor_ramdisk { bail!("No compatible ramdisk found."); } let is_magisk_patched = is_magisk_patched(&magiskboot, workdir)?; let is_magisk_patched_vendor_init_boot = is_magisk_patched_vendor_init_boot(&magiskboot, workdir)?; + let is_magisk_patched_vendor_ramdisk = + is_magisk_patched_vendor_ramdisk(&magiskboot, workdir)?; ensure!( - !is_magisk_patched || !is_magisk_patched_vendor_init_boot, + !is_magisk_patched || !is_magisk_patched_vendor_init_boot || !is_magisk_patched_vendor_ramdisk, "Cannot work with Magisk patched image" ); @@ -532,14 +606,25 @@ fn do_patch( let is_kernelsu_patched = is_kernelsu_patched(&magiskboot, workdir)?; let is_kernelsu_patched_vendor_init_boot = is_kernelsu_patched_vendor_init_boot(&magiskboot, workdir)?; + let is_kernelsu_patched_vendor_ramdisk = + is_kernelsu_patched_vendor_ramdisk(&magiskboot, workdir)?; let mut need_backup = false; - if !is_kernelsu_patched || (no_ramdisk && !is_kernelsu_patched_vendor_init_boot) { + if !is_kernelsu_patched || (no_ramdisk && !is_kernelsu_patched_vendor_init_boot) || (no_ramdisk && no_vendor_init_boot && !is_kernelsu_patched_vendor_ramdisk) + { if no_ramdisk { - // vendor init_boot patching - let status = do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "exists init"); - if status.is_ok() { - do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "mv init init.real")?; + if !no_vendor_init_boot { + // vendor init_boot patching + let status = do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "exists init"); + if status.is_ok() { + do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "mv init init.real")?; + } + } else if !no_vendor_ramdisk { + // vendor ramdisk patching + let status = do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "exists init"); + if status.is_ok() { + do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "mv init init.real")?; + } } } else { // kernelsu.ko is not exist, backup init if necessary @@ -552,8 +637,13 @@ fn do_patch( } if no_ramdisk { - do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "add 0755 init init")?; - do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "add 0755 kernelsu.ko kernelsu.ko")?; + if !no_vendor_init_boot { + do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "add 0755 init init")?; + do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "add 0755 kernelsu.ko kernelsu.ko")?; + } else if !no_vendor_ramdisk { + do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "add 0750 init init")?; + do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "add 0750 kernelsu.ko kernelsu.ko")?; + } } else { do_cpio_cmd(&magiskboot, workdir, "add 0755 init init")?; do_cpio_cmd(&magiskboot, workdir, "add 0755 kernelsu.ko kernelsu.ko")?; diff --git a/userspace/ksud_overlayfs/src/boot_patch.rs b/userspace/ksud_overlayfs/src/boot_patch.rs index c548a265..ced3265e 100644 --- a/userspace/ksud_overlayfs/src/boot_patch.rs +++ b/userspace/ksud_overlayfs/src/boot_patch.rs @@ -182,6 +182,21 @@ fn do_vendor_init_boot_cpio_cmd(magiskboot: &Path, workdir: &Path, cmd: &str) -> Ok(()) } +fn do_vendor_ramdisk_cpio_cmd(magiskboot: &Path, workdir: &Path, cmd: &str) -> Result<()> { + let vendor_ramdisk_cpio = workdir.join("vendor_ramdisk").join("ramdisk.cpio"); + let status = Command::new(magiskboot) + .current_dir(workdir) + .stdout(Stdio::null()) + .stderr(Stdio::null()) + .arg("cpio") + .arg(vendor_ramdisk_cpio) + .arg(cmd) + .status()?; + + ensure!(status.success(), "magiskboot cpio {} failed", cmd); + Ok(()) +} + fn is_magisk_patched(magiskboot: &Path, workdir: &Path) -> Result { let status = Command::new(magiskboot) .current_dir(workdir) @@ -207,6 +222,19 @@ fn is_magisk_patched_vendor_init_boot(magiskboot: &Path, workdir: &Path) -> Resu Ok(status.code() == Some(1)) } +fn is_magisk_patched_vendor_ramdisk(magiskboot: &Path, workdir: &Path) -> Result { + let vendor_ramdisk_cpio = workdir.join("vendor_ramdisk").join("ramdisk.cpio"); + let status = Command::new(magiskboot) + .current_dir(workdir) + .stdout(Stdio::null()) + .stderr(Stdio::null()) + .args(["cpio", vendor_ramdisk_cpio.to_str().unwrap(), "test"]) + .status()?; + + // 0: stock, 1: magisk + Ok(status.code() == Some(1)) +} + fn is_kernelsu_patched(magiskboot: &Path, workdir: &Path) -> Result { let status = Command::new(magiskboot) .current_dir(workdir) @@ -234,6 +262,22 @@ fn is_kernelsu_patched_vendor_init_boot(magiskboot: &Path, workdir: &Path) -> Re Ok(status.success()) } +fn is_kernelsu_patched_vendor_ramdisk(magiskboot: &Path, workdir: &Path) -> Result { + let vendor_ramdisk_cpio = workdir.join("vendor_ramdisk").join("ramdisk.cpio"); + let status = Command::new(magiskboot) + .current_dir(workdir) + .stdout(Stdio::null()) + .stderr(Stdio::null()) + .args([ + "cpio", + vendor_ramdisk_cpio.to_str().unwrap(), + "exists kernelsu.ko", + ]) + .status()?; + + Ok(status.success()) +} + fn dd, Q: AsRef>(ifile: P, ofile: Q) -> Result<()> { let status = Command::new("dd") .stdout(Stdio::null()) @@ -279,11 +323,21 @@ pub fn restore( ensure!(status.success(), "magiskboot unpack failed"); let no_ramdisk = !workdir.join("ramdisk.cpio").exists(); + let no_vendor_init_boot = !workdir + .join("vendor_ramdisk") + .join("init_boot.cpio") + .exists(); + let no_vendor_ramdisk = !workdir + .join("vendor_ramdisk") + .join("ramdisk.cpio") + .exists(); let is_kernelsu_patched = is_kernelsu_patched(&magiskboot, workdir)?; let is_kernelsu_patched_vendor_init_boot = is_kernelsu_patched_vendor_init_boot(&magiskboot, workdir)?; + let is_kernelsu_patched_vendor_ramdisk = + is_kernelsu_patched_vendor_ramdisk(&magiskboot, workdir)?; ensure!( - is_kernelsu_patched || is_kernelsu_patched_vendor_init_boot, + is_kernelsu_patched || is_kernelsu_patched_vendor_init_boot || is_kernelsu_patched_vendor_ramdisk, "boot image is not patched by KernelSU Next" ); @@ -318,16 +372,30 @@ pub fn restore( if new_boot.is_none() { if no_ramdisk { - // vendor init_boot restore - do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "rm kernelsu.ko")?; + if !no_vendor_init_boot { + // vendor init_boot restore + do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "rm kernelsu.ko")?; - let status = - do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "exists init.real").is_ok(); - if status { - do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "mv init.real init")?; - } else { - let vendor_init_boot = workdir.join("vendor_ramdisk").join("init_boot.cpio"); - std::fs::remove_file(vendor_init_boot)?; + let status = + do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "exists init.real").is_ok(); + if status { + do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "mv init.real init")?; + } else { + let vendor_init_boot = workdir.join("vendor_ramdisk").join("init_boot.cpio"); + std::fs::remove_file(vendor_init_boot)?; + } + } else if !no_vendor_ramdisk { + // vendor ramdisk restore + do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "rm kernelsu.ko")?; + + let status = + do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "exists init.real").is_ok(); + if status { + do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "mv init.real init")?; + } else { + let vendor_ramdisk = workdir.join("vendor_ramdisk").join("ramdisk.cpio"); + std::fs::remove_file(vendor_ramdisk)?; + } } } else { // remove kernelsu.ko @@ -517,14 +585,20 @@ fn do_patch( .join("vendor_ramdisk") .join("init_boot.cpio") .exists(); - if no_ramdisk && no_vendor_init_boot { + let no_vendor_ramdisk = !workdir + .join("vendor_ramdisk") + .join("ramdisk.cpio") + .exists(); + if no_ramdisk && no_vendor_init_boot && no_vendor_ramdisk { bail!("No compatible ramdisk found."); } let is_magisk_patched = is_magisk_patched(&magiskboot, workdir)?; let is_magisk_patched_vendor_init_boot = is_magisk_patched_vendor_init_boot(&magiskboot, workdir)?; + let is_magisk_patched_vendor_ramdisk = + is_magisk_patched_vendor_ramdisk(&magiskboot, workdir)?; ensure!( - !is_magisk_patched || !is_magisk_patched_vendor_init_boot, + !is_magisk_patched || !is_magisk_patched_vendor_init_boot || !is_magisk_patched_vendor_ramdisk, "Cannot work with Magisk patched image" ); @@ -532,14 +606,25 @@ fn do_patch( let is_kernelsu_patched = is_kernelsu_patched(&magiskboot, workdir)?; let is_kernelsu_patched_vendor_init_boot = is_kernelsu_patched_vendor_init_boot(&magiskboot, workdir)?; + let is_kernelsu_patched_vendor_ramdisk = + is_kernelsu_patched_vendor_ramdisk(&magiskboot, workdir)?; let mut need_backup = false; - if !is_kernelsu_patched || (no_ramdisk && !is_kernelsu_patched_vendor_init_boot) { + if !is_kernelsu_patched || (no_ramdisk && !is_kernelsu_patched_vendor_init_boot) || (no_ramdisk && no_vendor_init_boot && !is_kernelsu_patched_vendor_ramdisk) + { if no_ramdisk { - // vendor init_boot patching - let status = do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "exists init"); - if status.is_ok() { - do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "mv init init.real")?; + if !no_vendor_init_boot { + // vendor init_boot patching + let status = do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "exists init"); + if status.is_ok() { + do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "mv init init.real")?; + } + } else if !no_vendor_ramdisk { + // vendor ramdisk patching + let status = do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "exists init"); + if status.is_ok() { + do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "mv init init.real")?; + } } } else { // kernelsu.ko is not exist, backup init if necessary @@ -552,8 +637,13 @@ fn do_patch( } if no_ramdisk { - do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "add 0755 init init")?; - do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "add 0755 kernelsu.ko kernelsu.ko")?; + if !no_vendor_init_boot { + do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "add 0755 init init")?; + do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "add 0755 kernelsu.ko kernelsu.ko")?; + } else if !no_vendor_ramdisk { + do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "add 0750 init init")?; + do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "add 0750 kernelsu.ko kernelsu.ko")?; + } } else { do_cpio_cmd(&magiskboot, workdir, "add 0755 init init")?; do_cpio_cmd(&magiskboot, workdir, "add 0755 kernelsu.ko kernelsu.ko")?;