From c419659fc9ed18a97cee506dae26b28717742147 Mon Sep 17 00:00:00 2001 From: LoveSy Date: Wed, 11 Sep 2024 21:49:54 +0800 Subject: [PATCH 1/2] Remove dtb command from magiskboot --- native/src/Cargo.lock | 7 - native/src/Cargo.toml | 1 - native/src/boot/Cargo.toml | 1 - native/src/boot/dtb.rs | 307 --------------------------------- native/src/boot/lib.rs | 3 - native/src/boot/magiskboot.hpp | 1 - native/src/boot/main.cpp | 6 - 7 files changed, 326 deletions(-) delete mode 100644 native/src/boot/dtb.rs diff --git a/native/src/Cargo.lock b/native/src/Cargo.lock index 4b234fd6f5ff..73db8e2c380e 100644 --- a/native/src/Cargo.lock +++ b/native/src/Cargo.lock @@ -283,12 +283,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "fdt" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "784a4df722dc6267a04af36895398f59d21d07dce47232adf31ec0ff2fa45e67" - [[package]] name = "ff" version = "0.13.0" @@ -408,7 +402,6 @@ dependencies = [ "cxx-gen", "der", "digest", - "fdt", "num-traits", "p256", "p384", diff --git a/native/src/Cargo.toml b/native/src/Cargo.toml index 7a8bc0a9419a..c0ac29609537 100644 --- a/native/src/Cargo.toml +++ b/native/src/Cargo.toml @@ -23,7 +23,6 @@ rsa = "0.10.0-pre.2" #x509-cert = "0.3" der = "0.8.0-rc.0" bytemuck = "1.16" -fdt = "0.1" const_format = "0.2" [workspace.dependencies.argh] diff --git a/native/src/boot/Cargo.toml b/native/src/boot/Cargo.toml index e3e0d3005fff..24e2b92db870 100644 --- a/native/src/boot/Cargo.toml +++ b/native/src/boot/Cargo.toml @@ -27,6 +27,5 @@ p521 = { workspace = true } rsa = { workspace = true, features = ["sha2"] } x509-cert = { workspace = true } der = { workspace = true, features = ["derive", "pem"] } -fdt = { workspace = true } bytemuck = { workspace = true, features = ["derive", "min_const_generics"] } num-traits = { workspace = true } diff --git a/native/src/boot/dtb.rs b/native/src/boot/dtb.rs deleted file mode 100644 index 371a804044be..000000000000 --- a/native/src/boot/dtb.rs +++ /dev/null @@ -1,307 +0,0 @@ -use std::{cell::UnsafeCell, process::exit}; - -use argh::FromArgs; -use fdt::{ - node::{FdtNode, NodeProperty}, - Fdt, -}; - -use base::{ - libc::c_char, log_err, map_args, EarlyExitExt, LoggedResult, MappedFile, ResultExt, Utf8CStr, -}; - -use crate::{check_env, patch::patch_verity}; - -#[derive(FromArgs)] -struct DtbCli { - #[argh(positional)] - file: String, - #[argh(subcommand)] - action: DtbAction, -} - -#[derive(FromArgs)] -#[argh(subcommand)] -enum DtbAction { - Print(Print), - Patch(Patch), - Test(Test), -} - -#[derive(FromArgs)] -#[argh(subcommand, name = "print")] -struct Print { - #[argh(switch, short = 'f')] - fstab: bool, -} - -#[derive(FromArgs)] -#[argh(subcommand, name = "patch")] -struct Patch {} - -#[derive(FromArgs)] -#[argh(subcommand, name = "test")] -struct Test {} - -fn print_dtb_usage() { - eprintln!( - r#"Usage: magiskboot dtb [args...] -Do dtb related actions to . - -Supported actions: - print [-f] - Print all contents of dtb for debugging - Specify [-f] to only print fstab nodes - patch - Search for fstab and remove verity/avb - Modifications are done directly to the file in-place - Configure with env variables: KEEPVERITY - test - Test the fstab's status - Return values: - 0:valid 1:error"# - ); -} - -const MAX_PRINT_LEN: usize = 32; - -fn print_node(node: &FdtNode) { - fn pretty_node(depth_set: &[bool]) { - let mut depth_set = depth_set.iter().peekable(); - while let Some(depth) = depth_set.next() { - let last = depth_set.peek().is_none(); - if *depth { - if last { - print!("├── "); - } else { - print!("│ "); - } - } else if last { - print!("└── "); - } else { - print!(" "); - } - } - } - - fn pretty_prop(depth_set: &[bool]) { - let mut depth_set = depth_set.iter().peekable(); - while let Some(depth) = depth_set.next() { - let last = depth_set.peek().is_none(); - if *depth { - if last { - print!("│ "); - } else { - print!("│ "); - } - } else if last { - print!("└─ "); - } else { - print!(" "); - } - } - } - - fn do_print_node(node: &FdtNode, depth_set: &mut Vec) { - pretty_node(depth_set); - let depth = depth_set.len(); - depth_set.push(true); - println!("{}", node.name); - let mut properties = node.properties().peekable(); - let mut children = node.children().peekable(); - while let Some(NodeProperty { name, value }) = properties.next() { - let size = value.len(); - let is_str = !(size > 1 && value[0] == 0) - && matches!(value.last(), Some(0u8) | None) - && value.iter().all(|c| *c == 0 || (*c >= 32 && *c < 127)); - - if depth_set[depth] && properties.peek().is_none() && children.peek().is_none() { - depth_set[depth] = false; - } - - pretty_prop(depth_set); - if is_str { - println!( - "[{}]: [\"{}\"]", - name, - if value.is_empty() { - "" - } else { - unsafe { Utf8CStr::from_bytes_unchecked(value) } - } - ); - } else if size > MAX_PRINT_LEN { - println!("[{}]: ({})", name, size); - } else { - println!("[{}]: {:02x?}", name, value); - } - } - - while let Some(child) = children.next() { - if depth_set[depth] && children.peek().is_none() { - depth_set[depth] = false; - } - do_print_node(&child, depth_set); - } - depth_set.pop(); - } - - do_print_node(node, &mut vec![]); -} - -fn for_each_fdt LoggedResult<()>>( - file: &Utf8CStr, - rw: bool, - mut f: F, -) -> LoggedResult<()> { - eprintln!("Loading dtbs from [{}]", file); - let file = if rw { - MappedFile::open_rw(file)? - } else { - MappedFile::open(file)? - }; - let mut buf = Some(file.as_ref()); - let mut dtb_num = 0usize; - while let Some(slice) = buf { - let slice = if let Some(pos) = slice.windows(4).position(|w| w == b"\xd0\x0d\xfe\xed") { - &slice[pos..] - } else { - break; - }; - if slice.len() < 40 { - break; - } - let fdt = Fdt::new(slice)?; - - let size = fdt.total_size(); - - if size > slice.len() { - eprintln!("dtb.{:04} is truncated", dtb_num); - break; - } - - f(dtb_num, fdt)?; - - dtb_num += 1; - buf = Some(&slice[size..]); - } - Ok(()) -} - -fn find_fstab<'b, 'a: 'b>(fdt: &'b Fdt<'a>) -> Option> { - fdt.all_nodes().find(|node| node.name == "fstab") -} - -fn dtb_print(file: &Utf8CStr, fstab: bool) -> LoggedResult<()> { - for_each_fdt(file, false, |n, fdt| { - if fstab { - if let Some(fstab) = find_fstab(&fdt) { - eprintln!("Found fstab in dtb.{:04}", n); - print_node(&fstab); - } - } else if let Some(mut root) = fdt.find_node("/") { - eprintln!("Printing dtb.{:04}", n); - if root.name.is_empty() { - root.name = "/"; - } - print_node(&root); - } - Ok(()) - }) -} - -fn dtb_test(file: &Utf8CStr) -> LoggedResult { - let mut ret = true; - for_each_fdt(file, false, |_, fdt| { - if let Some(fstab) = find_fstab(&fdt) { - for child in fstab.children() { - if child.name != "system" { - continue; - } - if let Some(mount_point) = child.property("mnt_point") { - if mount_point.value == b"/system_root\0" { - ret = false; - break; - } - } - } - } - Ok(()) - })?; - Ok(ret) -} - -fn dtb_patch(file: &Utf8CStr) -> LoggedResult { - let keep_verity = check_env("KEEPVERITY"); - let mut patched = false; - for_each_fdt(file, true, |n, fdt| { - for node in fdt.all_nodes() { - if node.name != "chosen" { - continue; - } - if let Some(boot_args) = node.property("bootargs") { - boot_args.value.windows(14).for_each(|w| { - if w == b"skip_initramfs" { - let w = unsafe { - &mut *std::mem::transmute::<&[u8], &UnsafeCell<[u8]>>(w).get() - }; - w[..=4].copy_from_slice(b"want"); - eprintln!("Patch [skip_initramfs] -> [want_initramfs] in dtb.{:04}", n); - patched = true; - } - }); - } - } - if keep_verity { - return Ok(()); - } - if let Some(fstab) = find_fstab(&fdt) { - for child in fstab.children() { - if let Some(flags) = child.property("fsmgr_flags") { - let flags = unsafe { - &mut *std::mem::transmute::<&[u8], &UnsafeCell<[u8]>>(flags.value).get() - }; - if patch_verity(flags) != flags.len() { - patched = true; - } - } - } - } - Ok(()) - })?; - Ok(patched) -} - -pub fn dtb_commands(argc: i32, argv: *const *const c_char) -> bool { - fn inner(argc: i32, argv: *const *const c_char) -> LoggedResult<()> { - if argc < 1 { - return Err(log_err!("No arguments")); - } - let cmds = map_args(argc, argv)?; - - let mut cli = - DtbCli::from_args(&["magiskboot", "dtb"], &cmds).on_early_exit(print_dtb_usage); - - let file = Utf8CStr::from_string(&mut cli.file); - - match cli.action { - DtbAction::Print(Print { fstab }) => { - dtb_print(file, fstab)?; - } - DtbAction::Test(_) => { - if !dtb_test(file)? { - exit(1); - } - } - DtbAction::Patch(_) => { - if !dtb_patch(file)? { - exit(1); - } - } - } - Ok(()) - } - inner(argc, argv) - .log_with_msg(|w| w.write_str("Failed to process dtb")) - .is_ok() -} diff --git a/native/src/boot/lib.rs b/native/src/boot/lib.rs index 2adf6915261e..4e7c435f0101 100644 --- a/native/src/boot/lib.rs +++ b/native/src/boot/lib.rs @@ -4,14 +4,12 @@ pub use base; use cpio::cpio_commands; -use dtb::dtb_commands; use patch::hexpatch; use payload::extract_boot_from_payload; use sign::{get_sha, sha1_hash, sha256_hash, sign_boot_image, verify_boot_image, SHA}; use std::env; mod cpio; -mod dtb; mod patch; mod payload; // Suppress warnings in generated code @@ -63,7 +61,6 @@ pub mod ffi { cert: *const c_char, key: *const c_char, ) -> Vec; - unsafe fn dtb_commands(argc: i32, argv: *const *const c_char) -> bool; } } diff --git a/native/src/boot/magiskboot.hpp b/native/src/boot/magiskboot.hpp index f590a740b04e..b0d16bbf3d00 100644 --- a/native/src/boot/magiskboot.hpp +++ b/native/src/boot/magiskboot.hpp @@ -21,7 +21,6 @@ void repack(const char *src_img, const char *out_img, bool skip_comp = false); int verify(const char *image, const char *cert); int sign(const char *image, const char *name, const char *cert, const char *key); int split_image_dtb(const char *filename, bool skip_decomp = false); -int dtb_commands(int argc, char *argv[]); static inline bool check_env(const char *name) { using namespace std::string_view_literals; diff --git a/native/src/boot/main.cpp b/native/src/boot/main.cpp index 9859f3e1f18b..1db2cc6dcc38 100644 --- a/native/src/boot/main.cpp +++ b/native/src/boot/main.cpp @@ -90,10 +90,6 @@ Supported actions: Each command is a single argument; add quotes for each command. See "cpio --help" for supported commands. - dtb [args...] - Do dtb related actions to . - See "dtb --help" for supported actions. - split [-n] Split image.*-dtb into kernel + kernel_dtb. If '-n' is provided, decompression operations will be skipped; @@ -214,8 +210,6 @@ int main(int argc, char *argv[]) { return hexpatch(byte_view(argv[2]), byte_view(argv[3]), byte_view(argv[4])) ? 0 : 1; } else if (argc > 2 && action == "cpio") { return rust::cpio_commands(argc - 2, argv + 2) ? 0 : 1; - } else if (argc > 2 && action == "dtb") { - return rust::dtb_commands(argc - 2, argv + 2) ? 0 : 1; } else if (argc > 2 && action == "extract") { return rust::extract_boot_from_payload( argv[2], From cb6258d2a4c6436f209b2a7ae238794381fb5c17 Mon Sep 17 00:00:00 2001 From: LoveSy Date: Wed, 11 Sep 2024 22:03:59 +0800 Subject: [PATCH 2/2] Remove dtb from docs and scripts --- docs/tools.md | 19 ++----------------- scripts/boot_patch.sh | 12 ------------ 2 files changed, 2 insertions(+), 29 deletions(-) diff --git a/docs/tools.md b/docs/tools.md index b32c00e55119..d00d147c2a8a 100644 --- a/docs/tools.md +++ b/docs/tools.md @@ -14,11 +14,11 @@ su -> magisk ### magiskboot -A tool to unpack / repack boot images, parse / patch / extract cpio, patch dtb, hex patch binaries, and compress / decompress files with multiple algorithms. +A tool to unpack / repack boot images, parse / patch / extract cpio, hex patch binaries, and compress / decompress files with multiple algorithms. `magiskboot` natively supports (which means it does not rely on external tools) common compression formats including `gzip`, `lz4`, `lz4_legacy` , `lz4_lg` ([the LG edition](https://events.static.linuxfound.org/sites/events/files/lcjpcojp13_klee.pdf) of `lz4_legacy`, only used on LG), `lzma`, `xz`, and `bzip2`. -The concept of `magiskboot` is to make boot image modification simpler. For unpacking, it parses the header and extracts all sections in the image, decompressing on-the-fly if compression is detected in any sections. For repacking, the original boot image is required so the original headers can be used, changing only the necessary entries such as section sizes and checksum. All sections will be compressed back to the original format if required. The tool also supports many CPIO and DTB operations. +The concept of `magiskboot` is to make boot image modification simpler. For unpacking, it parses the header and extracts all sections in the image, decompressing on-the-fly if compression is detected in any sections. For repacking, the original boot image is required so the original headers can be used, changing only the necessary entries such as section sizes and checksum. All sections will be compressed back to the original format if required. The tool also supports many CPIO operations. ``` Usage: ./magiskboot [args...] @@ -108,21 +108,6 @@ Supported actions: restore Restore ramdisk from ramdisk backup stored within incpio - dtb [args...] - Do dtb related actions to - Supported actions: - print [-f] - Print all contents of dtb for debugging - Specify [-f] to only print fstab nodes - patch - Search for fstab and remove verity/avb - Modifications are done directly to the file in-place - Configure with env variables: KEEPVERITY - test - Test the fstab's status - Return values: - 0:valid 1:error - split Split image.*-dtb into kernel + kernel_dtb diff --git a/scripts/boot_patch.sh b/scripts/boot_patch.sh index 64f3d8e07dab..8fdb111d35cf 100644 --- a/scripts/boot_patch.sh +++ b/scripts/boot_patch.sh @@ -195,18 +195,6 @@ rm -f ramdisk.cpio.orig config *.xz # Binary Patches ################# -for dt in dtb kernel_dtb extra; do - if [ -f $dt ]; then - if ! ./magiskboot dtb $dt test; then - ui_print "! Boot image $dt was patched by old (unsupported) Magisk" - abort "! Please try again with *unpatched* boot image" - fi - if ./magiskboot dtb $dt patch; then - ui_print "- Patch fstab in boot image $dt" - fi - fi -done - if [ -f kernel ]; then PATCHEDKERNEL=false # Remove Samsung RKP