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],