From 510769639edd7a40e3b718b5cf2460b9facbd743 Mon Sep 17 00:00:00 2001 From: LoveSy Date: Sat, 1 Feb 2025 22:27:36 +0800 Subject: [PATCH] Replace rust inner functions to try blocks --- native/src/boot/cpio.rs | 12 +++--- native/src/boot/dtb.rs | 10 ++--- native/src/boot/lib.rs | 17 ++++++-- native/src/boot/main.cpp | 4 +- native/src/boot/patch.rs | 9 ++--- native/src/boot/payload.rs | 59 +++++++++++++--------------- native/src/boot/sign.rs | 20 ++++------ native/src/core/mount.rs | 12 +----- native/src/core/package.rs | 20 +++++----- native/src/core/resetprop/persist.rs | 42 ++++++++++---------- native/src/init/lib.rs | 3 +- native/src/init/mount.rs | 7 ++-- 12 files changed, 99 insertions(+), 116 deletions(-) diff --git a/native/src/boot/cpio.rs b/native/src/boot/cpio.rs index 9fcb8777109f..18478ae13d9d 100644 --- a/native/src/boot/cpio.rs +++ b/native/src/boot/cpio.rs @@ -755,9 +755,9 @@ impl Display for CpioEntry { } pub fn cpio_commands(argc: i32, argv: *const *const c_char) -> bool { - fn inner(argc: i32, argv: *const *const c_char) -> LoggedResult<()> { + let res: LoggedResult<()> = try { if argc < 1 { - return Err(log_err!("No arguments")); + Err(log_err!("No arguments"))?; } let cmds = map_args(argc, argv)?; @@ -807,7 +807,7 @@ pub fn cpio_commands(argc: i32, argv: *const *const c_char) -> bool { CpioAction::Add(Add { mode, path, file }) => cpio.add(*mode, path, file)?, CpioAction::Extract(Extract { paths }) => { if !paths.is_empty() && paths.len() != 2 { - return Err(log_err!("invalid arguments")); + Err(log_err!("invalid arguments"))?; } let mut it = paths.iter_mut(); cpio.extract(it.next(), it.next())?; @@ -819,10 +819,8 @@ pub fn cpio_commands(argc: i32, argv: *const *const c_char) -> bool { }; } cpio.dump(file)?; - Ok(()) - } - inner(argc, argv) - .log_with_msg(|w| w.write_str("Failed to process cpio")) + }; + res.log_with_msg(|w| w.write_str("Failed to process cpio")) .is_ok() } diff --git a/native/src/boot/dtb.rs b/native/src/boot/dtb.rs index 371a804044be..f44f0b6aec00 100644 --- a/native/src/boot/dtb.rs +++ b/native/src/boot/dtb.rs @@ -273,9 +273,9 @@ fn dtb_patch(file: &Utf8CStr) -> LoggedResult { } pub fn dtb_commands(argc: i32, argv: *const *const c_char) -> bool { - fn inner(argc: i32, argv: *const *const c_char) -> LoggedResult<()> { + let res: LoggedResult<()> = try { if argc < 1 { - return Err(log_err!("No arguments")); + Err(log_err!("No arguments"))?; } let cmds = map_args(argc, argv)?; @@ -299,9 +299,7 @@ pub fn dtb_commands(argc: i32, argv: *const *const c_char) -> bool { } } } - Ok(()) - } - inner(argc, argv) - .log_with_msg(|w| w.write_str("Failed to process dtb")) + }; + res.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 54a56ce426bb..a85ac1c90466 100644 --- a/native/src/boot/lib.rs +++ b/native/src/boot/lib.rs @@ -1,6 +1,7 @@ #![feature(format_args_nl)] #![feature(btree_extract_if)] #![feature(iter_intersperse)] +#![feature(try_blocks)] pub use base; use cpio::cpio_commands; @@ -21,6 +22,14 @@ mod sign; #[cxx::bridge] pub mod ffi { + unsafe extern "C++" { + include!("../base/include/base.hpp"); + + #[namespace = "rust"] + #[cxx_name = "Utf8CStr"] + type Utf8CStrRef<'a> = base::ffi::Utf8CStrRef<'a>; + } + unsafe extern "C++" { include!("compress.hpp"); fn decompress(buf: &[u8], fd: i32) -> bool; @@ -51,10 +60,10 @@ pub mod ffi { #[namespace = "rust"] #[allow(unused_unsafe)] extern "Rust" { - unsafe fn extract_boot_from_payload( - partition: *const c_char, - in_path: *const c_char, - out_path: *const c_char, + fn extract_boot_from_payload( + partition: Utf8CStrRef, + in_path: Utf8CStrRef, + out_path: Utf8CStrRef, ) -> bool; unsafe fn cpio_commands(argc: i32, argv: *const *const c_char) -> bool; unsafe fn verify_boot_image(img: &BootImage, cert: *const c_char) -> bool; diff --git a/native/src/boot/main.cpp b/native/src/boot/main.cpp index d198a13c1e5f..4972f3820b78 100644 --- a/native/src/boot/main.cpp +++ b/native/src/boot/main.cpp @@ -217,8 +217,8 @@ int main(int argc, char *argv[]) { } else if (argc > 2 && action == "extract") { return rust::extract_boot_from_payload( argv[2], - argc > 3 ? argv[3] : nullptr, - argc > 4 ? argv[4] : nullptr + argc > 3 ? argv[3] : "", + argc > 4 ? argv[4] : "" ) ? 0 : 1; } else { usage(argv[0]); diff --git a/native/src/boot/patch.rs b/native/src/boot/patch.rs index cac96e9c4afc..0740bb63a82f 100644 --- a/native/src/boot/patch.rs +++ b/native/src/boot/patch.rs @@ -101,7 +101,7 @@ fn hex2byte(hex: &[u8]) -> Vec { } pub fn hexpatch(file: &[u8], from: &[u8], to: &[u8]) -> bool { - fn inner(file: &[u8], from: &[u8], to: &[u8]) -> LoggedResult { + let res: LoggedResult = try { let file = Utf8CStr::from_bytes(file)?; let from = Utf8CStr::from_bytes(from)?; let to = Utf8CStr::from_bytes(to)?; @@ -114,8 +114,7 @@ pub fn hexpatch(file: &[u8], from: &[u8], to: &[u8]) -> bool { for off in &v { eprintln!("Patch @ {:#010X} [{}] -> [{}]", off, from, to); } - - Ok(!v.is_empty()) - } - inner(file, from, to).unwrap_or(false) + !v.is_empty() + }; + res.unwrap_or(false) } diff --git a/native/src/boot/payload.rs b/native/src/boot/payload.rs index 0be68152c23e..75b76083f094 100644 --- a/native/src/boot/payload.rs +++ b/native/src/boot/payload.rs @@ -1,17 +1,19 @@ -use std::fs::File; -use std::io::{BufReader, Read, Seek, SeekFrom, Write}; -use std::os::fd::{AsRawFd, FromRawFd}; +use std::{ + fs::File, + io::{BufReader, Read, Seek, SeekFrom, Write}, + os::fd::{AsRawFd, FromRawFd}, +}; use byteorder::{BigEndian, ReadBytesExt}; use quick_protobuf::{BytesReader, MessageRead}; -use base::libc::c_char; -use base::{error, LoggedError, LoggedResult, ReadSeekExt, StrErr, Utf8CStr}; -use base::{ResultExt, WriteExt}; - -use crate::ffi; -use crate::proto::update_metadata::mod_InstallOperation::Type; -use crate::proto::update_metadata::DeltaArchiveManifest; +use crate::{ + ffi, + proto::update_metadata::{mod_InstallOperation::Type, DeltaArchiveManifest}, +}; +use base::{ + error, ffi::Utf8CStrRef, LoggedError, LoggedResult, ReadSeekExt, ResultExt, Utf8CStr, WriteExt, +}; macro_rules! bad_payload { ($msg:literal) => {{ @@ -178,28 +180,23 @@ fn do_extract_boot_from_payload( } pub fn extract_boot_from_payload( - in_path: *const c_char, - partition: *const c_char, - out_path: *const c_char, + in_path: Utf8CStrRef, + partition: Utf8CStrRef, + out_path: Utf8CStrRef, ) -> bool { - fn inner( - in_path: *const c_char, - partition: *const c_char, - out_path: *const c_char, - ) -> LoggedResult<()> { - let in_path = unsafe { Utf8CStr::from_ptr(in_path) }?; - let partition = match unsafe { Utf8CStr::from_ptr(partition) } { - Ok(s) => Some(s), - Err(StrErr::NullPointerError) => None, - Err(e) => Err(e)?, + let res: LoggedResult<()> = try { + let partition = if partition.is_empty() { + None + } else { + Some(partition) }; - let out_path = match unsafe { Utf8CStr::from_ptr(out_path) } { - Ok(s) => Some(s), - Err(StrErr::NullPointerError) => None, - Err(e) => Err(e)?, + let out_path = if out_path.is_empty() { + None + } else { + Some(out_path) }; - do_extract_boot_from_payload(in_path, partition, out_path) - .log_with_msg(|w| w.write_str("Failed to extract from payload")) - } - inner(in_path, partition, out_path).is_ok() + do_extract_boot_from_payload(in_path, partition, out_path)? + }; + res.log_with_msg(|w| w.write_str("Failed to extract from payload")) + .is_ok() } diff --git a/native/src/boot/sign.rs b/native/src/boot/sign.rs index da9b8c1e99b3..89245ec8592d 100644 --- a/native/src/boot/sign.rs +++ b/native/src/boot/sign.rs @@ -254,7 +254,7 @@ impl BootSignature { } pub fn verify_boot_image(img: &BootImage, cert: *const c_char) -> bool { - fn inner(img: &BootImage, cert: *const c_char) -> LoggedResult<()> { + let res: LoggedResult<()> = try { let tail = img.tail(); // Don't use BootSignature::from_der because tail might have trailing zeros let mut reader = SliceReader::new(tail)?; @@ -268,9 +268,8 @@ pub fn verify_boot_image(img: &BootImage, cert: *const c_char) -> bool { Err(e) => Err(e)?, }; sig.verify(img.payload())?; - Ok(()) - } - inner(img, cert).is_ok() + }; + res.is_ok() } enum Bytes { @@ -296,12 +295,7 @@ pub fn sign_boot_image( cert: *const c_char, key: *const c_char, ) -> Vec { - fn inner( - payload: &[u8], - name: *const c_char, - cert: *const c_char, - key: *const c_char, - ) -> LoggedResult> { + let res: LoggedResult> = try { // Process arguments let name = unsafe { Utf8CStr::from_ptr(name) }?; let cert = match unsafe { Utf8CStr::from_ptr(cert) } { @@ -337,7 +331,7 @@ pub fn sign_boot_image( authenticated_attributes: attr, signature: OctetString::new(sig)?, }; - sig.to_der().log() - } - inner(payload, name, cert, key).unwrap_or_default() + sig.to_der()? + }; + res.unwrap_or_default() } diff --git a/native/src/core/mount.rs b/native/src/core/mount.rs index 344b6e65869f..e4472930da96 100644 --- a/native/src/core/mount.rs +++ b/native/src/core/mount.rs @@ -106,11 +106,7 @@ pub fn clean_mounts() { let module_mnt = FsPathBuf::new(&mut buf).join(magisk_tmp).join(MODULEMNT); let _: LoggedResult<()> = try { unsafe { - libc::umount2( - module_mnt.as_ptr(), - libc::MNT_DETACH, - ) - .as_os_err()?; + libc::umount2(module_mnt.as_ptr(), libc::MNT_DETACH).as_os_err()?; } }; @@ -125,11 +121,7 @@ pub fn clean_mounts() { ptr::null(), ) .as_os_err()?; - libc::umount2( - worker_dir.as_ptr(), - libc::MNT_DETACH, - ) - .as_os_err()?; + libc::umount2(worker_dir.as_ptr(), libc::MNT_DETACH).as_os_err()?; } }; } diff --git a/native/src/core/package.rs b/native/src/core/package.rs index 5033856b3c8e..fa4698c7e582 100644 --- a/native/src/core/package.rs +++ b/native/src/core/package.rs @@ -52,7 +52,7 @@ macro_rules! bad_apk { * within the APK v2 signature block. */ fn read_certificate(apk: &mut File, version: i32) -> Vec { - fn inner(apk: &mut File, version: i32) -> io::Result> { + let res: io::Result> = try { let mut u32_val = 0u32; let mut u64_val = 0u64; @@ -71,7 +71,7 @@ fn read_certificate(apk: &mut File, version: i32) -> Vec { } } if i == 0xffff { - return Err(bad_apk!("invalid APK format")); + Err(bad_apk!("invalid APK format"))?; } } @@ -98,7 +98,7 @@ fn read_certificate(apk: &mut File, version: i32) -> Vec { } }); if version > apk_ver { - return Err(bad_apk!("APK version too low")); + Err(bad_apk!("APK version too low"))?; } } @@ -108,7 +108,7 @@ fn read_certificate(apk: &mut File, version: i32) -> Vec { let mut magic = [0u8; 16]; apk.read_exact(&mut magic)?; if magic != APK_SIGNING_BLOCK_MAGIC { - return Err(bad_apk!("invalid signing block magic")); + Err(bad_apk!("invalid signing block magic"))?; } let mut signing_blk_sz = 0u64; apk.seek(SeekFrom::Current( @@ -116,14 +116,14 @@ fn read_certificate(apk: &mut File, version: i32) -> Vec { ))?; apk.read_pod(&mut signing_blk_sz)?; if signing_blk_sz != u64_val { - return Err(bad_apk!("invalid signing block size")); + Err(bad_apk!("invalid signing block size"))?; } // Finally, we are now at the beginning of the id-value pair sequence loop { apk.read_pod(&mut u64_val)?; // id-value pair length if u64_val == signing_blk_sz { - break; + Err(bad_apk!("cannot find certificate"))?; } let mut id = 0u32; @@ -140,7 +140,7 @@ fn read_certificate(apk: &mut File, version: i32) -> Vec { let mut cert = vec![0; u32_val as usize]; apk.read_exact(cert.as_mut())?; - return Ok(cert); + break cert; } else { // Skip this id-value pair apk.seek(SeekFrom::Current( @@ -148,10 +148,8 @@ fn read_certificate(apk: &mut File, version: i32) -> Vec { ))?; } } - - Err(bad_apk!("cannot find certificate")) - } - inner(apk, version).log().unwrap_or(vec![]) + }; + res.log().unwrap_or(vec![]) } fn find_apk_path(pkg: &str, buf: &mut dyn Utf8CStrBuf) -> io::Result<()> { diff --git a/native/src/core/resetprop/persist.rs b/native/src/core/resetprop/persist.rs index 51d4e61d29b0..1eff1b93f22a 100644 --- a/native/src/core/resetprop/persist.rs +++ b/native/src/core/resetprop/persist.rs @@ -141,8 +141,8 @@ fn proto_write_props(props: &PersistentProperties) -> LoggedResult<()> { Ok(()) } -pub unsafe fn persist_get_prop(name: &Utf8CStr, prop_cb: Pin<&mut PropCb>) { - fn inner(name: &Utf8CStr, mut prop_cb: Pin<&mut PropCb>) -> LoggedResult<()> { +pub fn persist_get_prop(name: &Utf8CStr, mut prop_cb: Pin<&mut PropCb>) { + let res: LoggedResult<()> = try { if check_proto() { let mut props = proto_read_props()?; let prop = props.find(name)?; @@ -158,13 +158,12 @@ pub unsafe fn persist_get_prop(name: &Utf8CStr, prop_cb: Pin<&mut PropCb>) { prop_cb.exec(name, Utf8CStr::from_string(&mut value)); debug!("resetprop: found prop [{}] = [{}]", name, value); } - Ok(()) - } - inner(name, prop_cb).ok(); + }; + res.ok(); } -pub unsafe fn persist_get_props(prop_cb: Pin<&mut PropCb>) { - fn inner(mut prop_cb: Pin<&mut PropCb>) -> LoggedResult<()> { +pub fn persist_get_props(mut prop_cb: Pin<&mut PropCb>) { + let res: LoggedResult<()> = try { if check_proto() { let mut props = proto_read_props()?; props.iter_mut().for_each(|prop| { @@ -190,27 +189,26 @@ pub unsafe fn persist_get_props(prop_cb: Pin<&mut PropCb>) { Ok(WalkResult::Skip) })?; } - Ok(()) - } - inner(prop_cb).ok(); + }; + res.ok(); } -pub unsafe fn persist_delete_prop(name: &Utf8CStr) -> bool { - fn inner(name: &Utf8CStr) -> LoggedResult<()> { +pub fn persist_delete_prop(name: &Utf8CStr) -> bool { + let res: LoggedResult<()> = try { if check_proto() { let mut props = proto_read_props()?; let idx = props.find_index(name).silent()?; props.remove(idx); - proto_write_props(&props) + proto_write_props(&props)?; } else { - file_set_prop(name, None) + file_set_prop(name, None)?; } - } - inner(name).is_ok() + }; + res.is_ok() } -pub unsafe fn persist_set_prop(name: &Utf8CStr, value: &Utf8CStr) -> bool { - unsafe fn inner(name: &Utf8CStr, value: &Utf8CStr) -> LoggedResult<()> { +pub fn persist_set_prop(name: &Utf8CStr, value: &Utf8CStr) -> bool { + let res: LoggedResult<()> = try { if check_proto() { let mut props = proto_read_props()?; match props.find_index(name) { @@ -223,10 +221,10 @@ pub unsafe fn persist_set_prop(name: &Utf8CStr, value: &Utf8CStr) -> bool { }, ), } - proto_write_props(&props) + proto_write_props(&props)?; } else { - file_set_prop(name, Some(value)) + file_set_prop(name, Some(value))?; } - } - inner(name, value).is_ok() + }; + res.is_ok() } diff --git a/native/src/init/lib.rs b/native/src/init/lib.rs index 00ec0c1c5497..fc50dc54fd40 100644 --- a/native/src/init/lib.rs +++ b/native/src/init/lib.rs @@ -1,9 +1,10 @@ #![feature(format_args_nl)] #![feature(once_cell_try)] +#![feature(try_blocks)] use logging::setup_klog; use mount::{is_device_mounted, switch_root}; -use rootdir::{inject_magisk_rc, collect_overlay_contexts, reset_overlay_contexts}; +use rootdir::{collect_overlay_contexts, inject_magisk_rc, reset_overlay_contexts}; // Has to be pub so all symbols in that crate is included pub use magiskpolicy; diff --git a/native/src/init/mount.rs b/native/src/init/mount.rs index 147465e22219..b23d8653f111 100644 --- a/native/src/init/mount.rs +++ b/native/src/init/mount.rs @@ -14,7 +14,7 @@ use base::{ }; pub fn switch_root(path: &Utf8CStr) { - fn inner(path: &Utf8CStr) -> LoggedResult<()> { + let res: LoggedResult<()> = try { debug!("Switch root to {}", path); let mut mounts = BTreeSet::new(); let mut rootfs = Directory::open(cstr!("/"))?; @@ -55,9 +55,8 @@ pub fn switch_root(path: &Utf8CStr) { debug!("Cleaning rootfs"); rootfs.remove_all()?; - Ok(()) - } - inner(path).ok(); + }; + res.ok(); } pub fn is_device_mounted(dev: u64, target: Pin<&mut CxxString>) -> bool {