Add support for Magisk v27.0

Upstream Magisk now xz-compresses files in modifies in the ramdisk. This
commit also implements the same in avbroot's MagiskRootPatcher.

Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
This commit is contained in:
Andrew Gunnerson
2024-02-03 13:46:28 -05:00
parent 80549346ea
commit 6ef8e548a3
3 changed files with 77 additions and 26 deletions
+71 -21
View File
@@ -140,10 +140,13 @@ impl MagiskRootPatcher {
// RULESDEVICE config option, which stored the writable block device as an
// rdev major/minor pair, which was not consistent across reboots and was
// replaced by PREINITDEVICE
const VERS_SUPPORTED: &'static [Range<u32>] = &[25102..25207, 25211..26500];
const VERS_SUPPORTED: &'static [Range<u32>] = &[25102..25207, 25211..27100];
const VER_PREINIT_DEVICE: Range<u32> =
25211..Self::VERS_SUPPORTED[Self::VERS_SUPPORTED.len() - 1].end;
const VER_RANDOM_SEED: Range<u32> = 25211..26103;
const VER_PATCH_VBMETA: Range<u32> = Self::VERS_SUPPORTED[0].start..26202;
const VER_XZ_BACKUP: Range<u32> =
26403..Self::VERS_SUPPORTED[Self::VERS_SUPPORTED.len() - 1].end;
pub fn new(
path: &Path,
@@ -216,6 +219,18 @@ impl MagiskRootPatcher {
}
}
fn xz_compress(reader: impl Read, cancel_signal: &AtomicBool) -> Result<Vec<u8>> {
let stream = Stream::new_easy_encoder(9, Check::Crc32)?;
let raw_writer = Cursor::new(Vec::new());
let mut writer = XzEncoder::new_stream(raw_writer, stream);
stream::copy(reader, &mut writer, cancel_signal)?;
let raw_writer = writer.finish()?;
Ok(raw_writer.into_inner())
}
/// Compare old and new ramdisk entry lists, creating the Magisk `.backup/`
/// directory structure. `.backup/.rmlist` will contain a sorted list of
/// NULL-terminated strings, listing which files were newly added or
@@ -223,7 +238,12 @@ impl MagiskRootPatcher {
/// entries as `.backup/<path>`.
///
/// Both lists and entries within the lists may be mutated.
fn apply_magisk_backup(old_entries: &mut [CpioEntry], new_entries: &mut Vec<CpioEntry>) {
fn apply_magisk_backup(
old_entries: &mut [CpioEntry],
new_entries: &mut Vec<CpioEntry>,
xz_compress: bool,
cancel_signal: &AtomicBool,
) -> Result<()> {
cpio::sort(old_entries);
cpio::sort(new_entries);
@@ -269,10 +289,37 @@ impl MagiskRootPatcher {
new_entries.push(CpioEntry::new_directory(b".backup", 0));
for old_entry in to_back_up {
let mut new_entry = old_entry.clone();
new_entry.path = b".backup/".to_vec();
new_entry.path.extend(&old_entry.path);
new_entries.push(new_entry);
let mut new_path = b".backup/".to_vec();
new_path.extend(&old_entry.path);
let mut new_data = None;
if xz_compress {
if let CpioEntryData::Data(data) = &old_entry.data {
new_path.extend(b".xz");
let reader = Cursor::new(data);
let buf = Self::xz_compress(reader, cancel_signal)?;
new_data = Some(CpioEntryData::Data(buf));
}
}
new_entries.push(CpioEntry {
path: new_path,
data: new_data.unwrap_or_else(|| old_entry.data.clone()),
inode: old_entry.inode,
file_type: old_entry.file_type,
file_mode: old_entry.file_mode,
uid: old_entry.uid,
gid: old_entry.gid,
nlink: old_entry.nlink,
mtime: old_entry.mtime,
dev_maj: old_entry.dev_maj,
dev_min: old_entry.dev_min,
rdev_maj: old_entry.rdev_maj,
rdev_min: old_entry.rdev_min,
crc32: old_entry.crc32,
});
}
new_entries.push(CpioEntry::new_file(
@@ -280,6 +327,8 @@ impl MagiskRootPatcher {
0,
CpioEntryData::Data(rm_list),
));
Ok(())
}
}
@@ -347,7 +396,9 @@ impl BootImagePatch for MagiskRootPatcher {
));
}
// Add xz-compressed magisk32 and magisk64.
// Add xz-compressed magisk32 and magisk64. We currently unconditionally
// include magisk32 because the boot image itself doesn't contain
// sufficient information to determine if a device is 64-bit only.
let mut xz_files = HashMap::<&str, &[u8]>::new();
xz_files.insert(
"lib/armeabi-v7a/libmagisk32.so",
@@ -366,29 +417,28 @@ impl BootImagePatch for MagiskRootPatcher {
for (source, target) in xz_files {
let reader = zip.by_name(source)?;
let raw_writer = Cursor::new(vec![]);
let stream = Stream::new_easy_encoder(9, Check::Crc32)?;
let mut writer = XzEncoder::new_stream(raw_writer, stream);
let buf = Self::xz_compress(reader, cancel_signal)?;
stream::copy(reader, &mut writer, cancel_signal)?;
let raw_writer = writer.finish()?;
entries.push(CpioEntry::new_file(
target,
0o644,
CpioEntryData::Data(raw_writer.into_inner()),
));
entries.push(CpioEntry::new_file(target, 0o644, CpioEntryData::Data(buf)));
}
// Create Magisk .backup directory structure.
Self::apply_magisk_backup(&mut old_entries, &mut entries);
Self::apply_magisk_backup(
&mut old_entries,
&mut entries,
Self::VER_XZ_BACKUP.contains(&self.version),
cancel_signal,
)?;
// Create Magisk config.
let mut magisk_config = String::new();
magisk_config.push_str("KEEPVERITY=true\n");
magisk_config.push_str("KEEPFORCEENCRYPT=true\n");
magisk_config.push_str("PATCHVBMETAFLAG=false\n");
if Self::VER_PATCH_VBMETA.contains(&self.version) {
magisk_config.push_str("PATCHVBMETAFLAG=false\n");
}
magisk_config.push_str("RECOVERYMODE=false\n");
if Self::VER_PREINIT_DEVICE.contains(&self.version) {
+4 -4
View File
@@ -47,7 +47,7 @@ data.ramdisks = ["otacerts"]
[profile.pixel_v4_gki.hashes]
original = "f9477a35e3b60a495e49431c61e3897f11775f453a6a9897ead568357c963618"
patched = "eb045799a514300727357a5ec471f9b04b276991daf4fd72f17f840b2a7dd1b8"
patched = "d3436650b4e0c60688dafb1472fa5fe95e67d19a8fad2da4850ffaa739d44574"
# Google Pixel 6a
# What's unique: boot (boot v4, no ramdisk) + vendor_boot (vendor v4, 2 ramdisks)
@@ -81,7 +81,7 @@ data.ramdisks = ["init_and_otacerts", "dlkm"]
[profile.pixel_v4_non_gki.hashes]
original = "021b4510bc244f5f686fbff89eb2058ec9c96a2949c2fe8caa7750a78d593225"
patched = "5d1a36e2eb18d9d905ab397d4eaf2d7e7c94da6e7573afe3d4e4367841171fe3"
patched = "0f90ae4c26a54a735d48e13e98bea73b6d1c026b0e95fa5b4b26179a1d6bdc86"
# Google Pixel 4a 5G
# What's unique: boot (boot v3) + vendor_boot (vendor v3)
@@ -116,7 +116,7 @@ data.ramdisks = ["otacerts"]
[profile.pixel_v3.hashes]
original = "12221a69ff32e137d5f19b61f576fc6b33f0973c4a81da7722c640554ff4bc4e"
patched = "e2049c6eba6990fc5ce30130af470c134a5ccc42947dcdd398f737fbca7ae44a"
patched = "0a92969bbd7cb30071a0799eb20028546d1cec3e6ec1ca4d7e1fe7776f1399fc"
# Google Pixel 4a
# What's unique: boot (boot v2)
@@ -145,4 +145,4 @@ data.deps = ["system"]
[profile.pixel_v2.hashes]
original = "8b38d2d999b5b6e240e894f669e9e2643b3764c108d53bb7b02447da725e7c18"
patched = "16f56e3d02c08bb646d8d0694ce77a6edb02a613bbcff14b10ead4a448c3dc00"
patched = "85b411947145e89cdc7f71b7109a12586f4dbddce3021f0f96172fc465c189d6"
+2 -1
View File
@@ -817,11 +817,12 @@ fn create_fake_magisk(output: &Path) -> Result<()> {
"lib/x86_64/libmagiskinit.so",
] {
zip_writer.start_file(path, FileOptions::default())?;
write!(zip_writer, "dummy contents for {path}")?;
}
// avbroot looks for the version number in this file.
zip_writer.start_file("assets/util_functions.sh", FileOptions::default())?;
zip_writer.write_all(b"MAGISK_VER_CODE=26400\n")?;
zip_writer.write_all(b"MAGISK_VER_CODE=27000\n")?;
Ok(())
}