Replace rust inner functions to try blocks

This commit is contained in:
LoveSy 2025-02-01 22:27:36 +08:00 committed by John Wu
parent 88628fdf3c
commit 3981c9665e
12 changed files with 99 additions and 116 deletions

View File

@ -755,9 +755,9 @@ impl Display for CpioEntry {
} }
pub fn cpio_commands(argc: i32, argv: *const *const c_char) -> bool { 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 { if argc < 1 {
return Err(log_err!("No arguments")); Err(log_err!("No arguments"))?;
} }
let cmds = map_args(argc, argv)?; 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::Add(Add { mode, path, file }) => cpio.add(*mode, path, file)?,
CpioAction::Extract(Extract { paths }) => { CpioAction::Extract(Extract { paths }) => {
if !paths.is_empty() && paths.len() != 2 { if !paths.is_empty() && paths.len() != 2 {
return Err(log_err!("invalid arguments")); Err(log_err!("invalid arguments"))?;
} }
let mut it = paths.iter_mut(); let mut it = paths.iter_mut();
cpio.extract(it.next(), it.next())?; 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)?; cpio.dump(file)?;
Ok(()) };
} res.log_with_msg(|w| w.write_str("Failed to process cpio"))
inner(argc, argv)
.log_with_msg(|w| w.write_str("Failed to process cpio"))
.is_ok() .is_ok()
} }

View File

@ -273,9 +273,9 @@ fn dtb_patch(file: &Utf8CStr) -> LoggedResult<bool> {
} }
pub fn dtb_commands(argc: i32, argv: *const *const c_char) -> bool { 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 { if argc < 1 {
return Err(log_err!("No arguments")); Err(log_err!("No arguments"))?;
} }
let cmds = map_args(argc, argv)?; let cmds = map_args(argc, argv)?;
@ -299,9 +299,7 @@ pub fn dtb_commands(argc: i32, argv: *const *const c_char) -> bool {
} }
} }
} }
Ok(()) };
} res.log_with_msg(|w| w.write_str("Failed to process dtb"))
inner(argc, argv)
.log_with_msg(|w| w.write_str("Failed to process dtb"))
.is_ok() .is_ok()
} }

View File

@ -1,6 +1,7 @@
#![feature(format_args_nl)] #![feature(format_args_nl)]
#![feature(btree_extract_if)] #![feature(btree_extract_if)]
#![feature(iter_intersperse)] #![feature(iter_intersperse)]
#![feature(try_blocks)]
pub use base; pub use base;
use cpio::cpio_commands; use cpio::cpio_commands;
@ -21,6 +22,14 @@ mod sign;
#[cxx::bridge] #[cxx::bridge]
pub mod ffi { 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++" { unsafe extern "C++" {
include!("compress.hpp"); include!("compress.hpp");
fn decompress(buf: &[u8], fd: i32) -> bool; fn decompress(buf: &[u8], fd: i32) -> bool;
@ -51,10 +60,10 @@ pub mod ffi {
#[namespace = "rust"] #[namespace = "rust"]
#[allow(unused_unsafe)] #[allow(unused_unsafe)]
extern "Rust" { extern "Rust" {
unsafe fn extract_boot_from_payload( fn extract_boot_from_payload(
partition: *const c_char, partition: Utf8CStrRef,
in_path: *const c_char, in_path: Utf8CStrRef,
out_path: *const c_char, out_path: Utf8CStrRef,
) -> bool; ) -> bool;
unsafe fn cpio_commands(argc: i32, argv: *const *const c_char) -> 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; unsafe fn verify_boot_image(img: &BootImage, cert: *const c_char) -> bool;

View File

@ -217,8 +217,8 @@ int main(int argc, char *argv[]) {
} else if (argc > 2 && action == "extract") { } else if (argc > 2 && action == "extract") {
return rust::extract_boot_from_payload( return rust::extract_boot_from_payload(
argv[2], argv[2],
argc > 3 ? argv[3] : nullptr, argc > 3 ? argv[3] : "",
argc > 4 ? argv[4] : nullptr argc > 4 ? argv[4] : ""
) ? 0 : 1; ) ? 0 : 1;
} else { } else {
usage(argv[0]); usage(argv[0]);

View File

@ -101,7 +101,7 @@ fn hex2byte(hex: &[u8]) -> Vec<u8> {
} }
pub fn hexpatch(file: &[u8], from: &[u8], to: &[u8]) -> bool { pub fn hexpatch(file: &[u8], from: &[u8], to: &[u8]) -> bool {
fn inner(file: &[u8], from: &[u8], to: &[u8]) -> LoggedResult<bool> { let res: LoggedResult<bool> = try {
let file = Utf8CStr::from_bytes(file)?; let file = Utf8CStr::from_bytes(file)?;
let from = Utf8CStr::from_bytes(from)?; let from = Utf8CStr::from_bytes(from)?;
let to = Utf8CStr::from_bytes(to)?; let to = Utf8CStr::from_bytes(to)?;
@ -114,8 +114,7 @@ pub fn hexpatch(file: &[u8], from: &[u8], to: &[u8]) -> bool {
for off in &v { for off in &v {
eprintln!("Patch @ {:#010X} [{}] -> [{}]", off, from, to); eprintln!("Patch @ {:#010X} [{}] -> [{}]", off, from, to);
} }
!v.is_empty()
Ok(!v.is_empty()) };
} res.unwrap_or(false)
inner(file, from, to).unwrap_or(false)
} }

View File

@ -1,17 +1,19 @@
use std::fs::File; use std::{
use std::io::{BufReader, Read, Seek, SeekFrom, Write}; fs::File,
use std::os::fd::{AsRawFd, FromRawFd}; io::{BufReader, Read, Seek, SeekFrom, Write},
os::fd::{AsRawFd, FromRawFd},
};
use byteorder::{BigEndian, ReadBytesExt}; use byteorder::{BigEndian, ReadBytesExt};
use quick_protobuf::{BytesReader, MessageRead}; use quick_protobuf::{BytesReader, MessageRead};
use base::libc::c_char; use crate::{
use base::{error, LoggedError, LoggedResult, ReadSeekExt, StrErr, Utf8CStr}; ffi,
use base::{ResultExt, WriteExt}; proto::update_metadata::{mod_InstallOperation::Type, DeltaArchiveManifest},
};
use crate::ffi; use base::{
use crate::proto::update_metadata::mod_InstallOperation::Type; error, ffi::Utf8CStrRef, LoggedError, LoggedResult, ReadSeekExt, ResultExt, Utf8CStr, WriteExt,
use crate::proto::update_metadata::DeltaArchiveManifest; };
macro_rules! bad_payload { macro_rules! bad_payload {
($msg:literal) => {{ ($msg:literal) => {{
@ -178,28 +180,23 @@ fn do_extract_boot_from_payload(
} }
pub fn extract_boot_from_payload( pub fn extract_boot_from_payload(
in_path: *const c_char, in_path: Utf8CStrRef,
partition: *const c_char, partition: Utf8CStrRef,
out_path: *const c_char, out_path: Utf8CStrRef,
) -> bool { ) -> bool {
fn inner( let res: LoggedResult<()> = try {
in_path: *const c_char, let partition = if partition.is_empty() {
partition: *const c_char, None
out_path: *const c_char, } else {
) -> LoggedResult<()> { Some(partition)
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 out_path = match unsafe { Utf8CStr::from_ptr(out_path) } { let out_path = if out_path.is_empty() {
Ok(s) => Some(s), None
Err(StrErr::NullPointerError) => None, } else {
Err(e) => Err(e)?, Some(out_path)
}; };
do_extract_boot_from_payload(in_path, partition, out_path) do_extract_boot_from_payload(in_path, partition, out_path)?
.log_with_msg(|w| w.write_str("Failed to extract from payload")) };
} res.log_with_msg(|w| w.write_str("Failed to extract from payload"))
inner(in_path, partition, out_path).is_ok() .is_ok()
} }

View File

@ -254,7 +254,7 @@ impl BootSignature {
} }
pub fn verify_boot_image(img: &BootImage, cert: *const c_char) -> bool { 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(); let tail = img.tail();
// Don't use BootSignature::from_der because tail might have trailing zeros // Don't use BootSignature::from_der because tail might have trailing zeros
let mut reader = SliceReader::new(tail)?; 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)?, Err(e) => Err(e)?,
}; };
sig.verify(img.payload())?; sig.verify(img.payload())?;
Ok(()) };
} res.is_ok()
inner(img, cert).is_ok()
} }
enum Bytes { enum Bytes {
@ -296,12 +295,7 @@ pub fn sign_boot_image(
cert: *const c_char, cert: *const c_char,
key: *const c_char, key: *const c_char,
) -> Vec<u8> { ) -> Vec<u8> {
fn inner( let res: LoggedResult<Vec<u8>> = try {
payload: &[u8],
name: *const c_char,
cert: *const c_char,
key: *const c_char,
) -> LoggedResult<Vec<u8>> {
// Process arguments // Process arguments
let name = unsafe { Utf8CStr::from_ptr(name) }?; let name = unsafe { Utf8CStr::from_ptr(name) }?;
let cert = match unsafe { Utf8CStr::from_ptr(cert) } { let cert = match unsafe { Utf8CStr::from_ptr(cert) } {
@ -337,7 +331,7 @@ pub fn sign_boot_image(
authenticated_attributes: attr, authenticated_attributes: attr,
signature: OctetString::new(sig)?, signature: OctetString::new(sig)?,
}; };
sig.to_der().log() sig.to_der()?
} };
inner(payload, name, cert, key).unwrap_or_default() res.unwrap_or_default()
} }

View File

@ -106,11 +106,7 @@ pub fn clean_mounts() {
let module_mnt = FsPathBuf::new(&mut buf).join(magisk_tmp).join(MODULEMNT); let module_mnt = FsPathBuf::new(&mut buf).join(magisk_tmp).join(MODULEMNT);
let _: LoggedResult<()> = try { let _: LoggedResult<()> = try {
unsafe { unsafe {
libc::umount2( libc::umount2(module_mnt.as_ptr(), libc::MNT_DETACH).as_os_err()?;
module_mnt.as_ptr(),
libc::MNT_DETACH,
)
.as_os_err()?;
} }
}; };
@ -125,11 +121,7 @@ pub fn clean_mounts() {
ptr::null(), ptr::null(),
) )
.as_os_err()?; .as_os_err()?;
libc::umount2( libc::umount2(worker_dir.as_ptr(), libc::MNT_DETACH).as_os_err()?;
worker_dir.as_ptr(),
libc::MNT_DETACH,
)
.as_os_err()?;
} }
}; };
} }

View File

@ -52,7 +52,7 @@ macro_rules! bad_apk {
* within the APK v2 signature block. * within the APK v2 signature block.
*/ */
fn read_certificate(apk: &mut File, version: i32) -> Vec<u8> { fn read_certificate(apk: &mut File, version: i32) -> Vec<u8> {
fn inner(apk: &mut File, version: i32) -> io::Result<Vec<u8>> { let res: io::Result<Vec<u8>> = try {
let mut u32_val = 0u32; let mut u32_val = 0u32;
let mut u64_val = 0u64; let mut u64_val = 0u64;
@ -71,7 +71,7 @@ fn read_certificate(apk: &mut File, version: i32) -> Vec<u8> {
} }
} }
if i == 0xffff { 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<u8> {
} }
}); });
if version > apk_ver { 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<u8> {
let mut magic = [0u8; 16]; let mut magic = [0u8; 16];
apk.read_exact(&mut magic)?; apk.read_exact(&mut magic)?;
if magic != APK_SIGNING_BLOCK_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; let mut signing_blk_sz = 0u64;
apk.seek(SeekFrom::Current( apk.seek(SeekFrom::Current(
@ -116,14 +116,14 @@ fn read_certificate(apk: &mut File, version: i32) -> Vec<u8> {
))?; ))?;
apk.read_pod(&mut signing_blk_sz)?; apk.read_pod(&mut signing_blk_sz)?;
if signing_blk_sz != u64_val { 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 // Finally, we are now at the beginning of the id-value pair sequence
loop { loop {
apk.read_pod(&mut u64_val)?; // id-value pair length apk.read_pod(&mut u64_val)?; // id-value pair length
if u64_val == signing_blk_sz { if u64_val == signing_blk_sz {
break; Err(bad_apk!("cannot find certificate"))?;
} }
let mut id = 0u32; let mut id = 0u32;
@ -140,7 +140,7 @@ fn read_certificate(apk: &mut File, version: i32) -> Vec<u8> {
let mut cert = vec![0; u32_val as usize]; let mut cert = vec![0; u32_val as usize];
apk.read_exact(cert.as_mut())?; apk.read_exact(cert.as_mut())?;
return Ok(cert); break cert;
} else { } else {
// Skip this id-value pair // Skip this id-value pair
apk.seek(SeekFrom::Current( apk.seek(SeekFrom::Current(
@ -148,10 +148,8 @@ fn read_certificate(apk: &mut File, version: i32) -> Vec<u8> {
))?; ))?;
} }
} }
};
Err(bad_apk!("cannot find certificate")) res.log().unwrap_or(vec![])
}
inner(apk, version).log().unwrap_or(vec![])
} }
fn find_apk_path(pkg: &str, buf: &mut dyn Utf8CStrBuf) -> io::Result<()> { fn find_apk_path(pkg: &str, buf: &mut dyn Utf8CStrBuf) -> io::Result<()> {

View File

@ -141,8 +141,8 @@ fn proto_write_props(props: &PersistentProperties) -> LoggedResult<()> {
Ok(()) Ok(())
} }
pub unsafe fn persist_get_prop(name: &Utf8CStr, prop_cb: Pin<&mut PropCb>) { pub fn persist_get_prop(name: &Utf8CStr, mut prop_cb: Pin<&mut PropCb>) {
fn inner(name: &Utf8CStr, mut prop_cb: Pin<&mut PropCb>) -> LoggedResult<()> { let res: LoggedResult<()> = try {
if check_proto() { if check_proto() {
let mut props = proto_read_props()?; let mut props = proto_read_props()?;
let prop = props.find(name)?; 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)); prop_cb.exec(name, Utf8CStr::from_string(&mut value));
debug!("resetprop: found prop [{}] = [{}]", name, value); debug!("resetprop: found prop [{}] = [{}]", name, value);
} }
Ok(()) };
} res.ok();
inner(name, prop_cb).ok();
} }
pub unsafe fn persist_get_props(prop_cb: Pin<&mut PropCb>) { pub fn persist_get_props(mut prop_cb: Pin<&mut PropCb>) {
fn inner(mut prop_cb: Pin<&mut PropCb>) -> LoggedResult<()> { let res: LoggedResult<()> = try {
if check_proto() { if check_proto() {
let mut props = proto_read_props()?; let mut props = proto_read_props()?;
props.iter_mut().for_each(|prop| { 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(WalkResult::Skip)
})?; })?;
} }
Ok(()) };
} res.ok();
inner(prop_cb).ok();
} }
pub unsafe fn persist_delete_prop(name: &Utf8CStr) -> bool { pub fn persist_delete_prop(name: &Utf8CStr) -> bool {
fn inner(name: &Utf8CStr) -> LoggedResult<()> { let res: LoggedResult<()> = try {
if check_proto() { if check_proto() {
let mut props = proto_read_props()?; let mut props = proto_read_props()?;
let idx = props.find_index(name).silent()?; let idx = props.find_index(name).silent()?;
props.remove(idx); props.remove(idx);
proto_write_props(&props) proto_write_props(&props)?;
} else { } 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 { pub fn persist_set_prop(name: &Utf8CStr, value: &Utf8CStr) -> bool {
unsafe fn inner(name: &Utf8CStr, value: &Utf8CStr) -> LoggedResult<()> { let res: LoggedResult<()> = try {
if check_proto() { if check_proto() {
let mut props = proto_read_props()?; let mut props = proto_read_props()?;
match props.find_index(name) { 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 { } else {
file_set_prop(name, Some(value)) file_set_prop(name, Some(value))?;
} }
} };
inner(name, value).is_ok() res.is_ok()
} }

View File

@ -1,9 +1,10 @@
#![feature(format_args_nl)] #![feature(format_args_nl)]
#![feature(once_cell_try)] #![feature(once_cell_try)]
#![feature(try_blocks)]
use logging::setup_klog; use logging::setup_klog;
use mount::{is_device_mounted, switch_root}; 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 // Has to be pub so all symbols in that crate is included
pub use magiskpolicy; pub use magiskpolicy;

View File

@ -14,7 +14,7 @@ use base::{
}; };
pub fn switch_root(path: &Utf8CStr) { pub fn switch_root(path: &Utf8CStr) {
fn inner(path: &Utf8CStr) -> LoggedResult<()> { let res: LoggedResult<()> = try {
debug!("Switch root to {}", path); debug!("Switch root to {}", path);
let mut mounts = BTreeSet::new(); let mut mounts = BTreeSet::new();
let mut rootfs = Directory::open(cstr!("/"))?; let mut rootfs = Directory::open(cstr!("/"))?;
@ -55,9 +55,8 @@ pub fn switch_root(path: &Utf8CStr) {
debug!("Cleaning rootfs"); debug!("Cleaning rootfs");
rootfs.remove_all()?; rootfs.remove_all()?;
Ok(()) };
} res.ok();
inner(path).ok();
} }
pub fn is_device_mounted(dev: u64, target: Pin<&mut CxxString>) -> bool { pub fn is_device_mounted(dev: u64, target: Pin<&mut CxxString>) -> bool {