You've already forked Magisk
mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-09-06 06:36:58 +00:00
Compare commits
6 Commits
2c39d0234d
...
5cbaf2ae11
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5cbaf2ae11 | ||
|
|
8ebc6207b4 | ||
|
|
7848ee616b | ||
|
|
fd193c3cae | ||
|
|
36d33c7a85 | ||
|
|
5caf28d27c |
@@ -23,32 +23,29 @@ pub type LoggedResult<T> = Result<T, LoggedError>;
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! log_err {
|
||||
() => {{
|
||||
Err($crate::LoggedError::default())
|
||||
}};
|
||||
($($args:tt)+) => {{
|
||||
$crate::error!($($args)+);
|
||||
$crate::LoggedError::default()
|
||||
Err($crate::LoggedError::default())
|
||||
}};
|
||||
}
|
||||
|
||||
// Any result or option can be silenced
|
||||
pub trait SilentResultExt<T> {
|
||||
pub trait SilentLogExt<T> {
|
||||
fn silent(self) -> LoggedResult<T>;
|
||||
}
|
||||
|
||||
impl<T, E> SilentResultExt<T> for Result<T, E> {
|
||||
impl<T, E> SilentLogExt<T> for Result<T, E> {
|
||||
fn silent(self) -> LoggedResult<T> {
|
||||
match self {
|
||||
Ok(v) => Ok(v),
|
||||
Err(_) => Err(LoggedError::default()),
|
||||
}
|
||||
self.map_err(|_| LoggedError::default())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> SilentResultExt<T> for Option<T> {
|
||||
impl<T> SilentLogExt<T> for Option<T> {
|
||||
fn silent(self) -> LoggedResult<T> {
|
||||
match self {
|
||||
Some(v) => Ok(v),
|
||||
None => Err(LoggedError::default()),
|
||||
}
|
||||
self.ok_or_else(LoggedError::default)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,142 +61,170 @@ pub(crate) trait CxxResultExt<T> {
|
||||
fn log_cxx(self) -> LoggedResult<T>;
|
||||
}
|
||||
|
||||
trait Loggable<T> {
|
||||
fn do_log(self, level: LogLevel, caller: Option<&'static Location>) -> LoggedResult<T>;
|
||||
// Public API for converting Option to LoggedResult
|
||||
pub trait OptionExt<T> {
|
||||
fn ok_or_log(self) -> LoggedResult<T>;
|
||||
fn ok_or_log_msg<F: FnOnce(Formatter) -> fmt::Result>(self, f: F) -> LoggedResult<T>;
|
||||
}
|
||||
|
||||
impl<T> OptionExt<T> for Option<T> {
|
||||
#[inline(always)]
|
||||
fn ok_or_log(self) -> LoggedResult<T> {
|
||||
self.ok_or_else(LoggedError::default)
|
||||
}
|
||||
|
||||
#[cfg(not(debug_assertions))]
|
||||
fn ok_or_log_msg<F: FnOnce(Formatter) -> fmt::Result>(self, f: F) -> LoggedResult<T> {
|
||||
self.ok_or_else(|| {
|
||||
do_log_msg(LogLevel::Error, None, f);
|
||||
LoggedError::default()
|
||||
})
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
#[cfg(debug_assertions)]
|
||||
fn ok_or_log_msg<F: FnOnce(Formatter) -> fmt::Result>(self, f: F) -> LoggedResult<T> {
|
||||
let caller = Some(Location::caller());
|
||||
self.ok_or_else(|| {
|
||||
do_log_msg(LogLevel::Error, caller, f);
|
||||
LoggedError::default()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
trait Loggable {
|
||||
fn do_log(self, level: LogLevel, caller: Option<&'static Location>) -> LoggedError;
|
||||
fn do_log_msg<F: FnOnce(Formatter) -> fmt::Result>(
|
||||
self,
|
||||
level: LogLevel,
|
||||
caller: Option<&'static Location>,
|
||||
f: F,
|
||||
) -> LoggedResult<T>;
|
||||
) -> LoggedError;
|
||||
}
|
||||
|
||||
impl<T, R: Loggable<T>> CxxResultExt<T> for R {
|
||||
impl<T, E: Loggable> CxxResultExt<T> for Result<T, E> {
|
||||
fn log_cxx(self) -> LoggedResult<T> {
|
||||
self.do_log(LogLevel::ErrorCxx, None)
|
||||
self.map_err(|e| e.do_log(LogLevel::ErrorCxx, None))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, R: Loggable<T>> ResultExt<T> for R {
|
||||
impl<T, E: Loggable> ResultExt<T> for Result<T, E> {
|
||||
#[cfg(not(debug_assertions))]
|
||||
fn log(self) -> LoggedResult<T> {
|
||||
self.do_log(LogLevel::Error, None)
|
||||
self.map_err(|e| e.do_log(LogLevel::Error, None))
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
#[cfg(debug_assertions)]
|
||||
fn log(self) -> LoggedResult<T> {
|
||||
self.do_log(LogLevel::Error, Some(Location::caller()))
|
||||
let caller = Some(Location::caller());
|
||||
self.map_err(|e| e.do_log(LogLevel::Error, caller))
|
||||
}
|
||||
|
||||
#[cfg(not(debug_assertions))]
|
||||
fn log_with_msg<F: FnOnce(Formatter) -> fmt::Result>(self, f: F) -> LoggedResult<T> {
|
||||
self.do_log_msg(LogLevel::Error, None, f)
|
||||
self.map_err(|e| e.do_log_msg(LogLevel::Error, None, f))
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
#[cfg(debug_assertions)]
|
||||
fn log_with_msg<F: FnOnce(Formatter) -> fmt::Result>(self, f: F) -> LoggedResult<T> {
|
||||
self.do_log_msg(LogLevel::Error, Some(Location::caller()), f)
|
||||
let caller = Some(Location::caller());
|
||||
self.map_err(|e| e.do_log_msg(LogLevel::Error, caller, f))
|
||||
}
|
||||
|
||||
#[cfg(not(debug_assertions))]
|
||||
fn log_ok(self) {
|
||||
self.log().ok();
|
||||
self.map_err(|e| e.do_log(LogLevel::Error, None)).ok();
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
#[cfg(debug_assertions)]
|
||||
fn log_ok(self) {
|
||||
self.do_log(LogLevel::Error, Some(Location::caller())).ok();
|
||||
let caller = Some(Location::caller());
|
||||
self.map_err(|e| e.do_log(LogLevel::Error, caller)).ok();
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Loggable<T> for LoggedResult<T> {
|
||||
fn do_log(self, _: LogLevel, _: Option<&'static Location>) -> LoggedResult<T> {
|
||||
impl<T> ResultExt<T> for LoggedResult<T> {
|
||||
fn log(self) -> LoggedResult<T> {
|
||||
self
|
||||
}
|
||||
|
||||
fn do_log_msg<F: FnOnce(Formatter) -> fmt::Result>(
|
||||
self,
|
||||
level: LogLevel,
|
||||
caller: Option<&'static Location>,
|
||||
f: F,
|
||||
) -> LoggedResult<T> {
|
||||
match self {
|
||||
Ok(v) => Ok(v),
|
||||
Err(_) => {
|
||||
log_with_formatter(level, |w| {
|
||||
if let Some(caller) = caller {
|
||||
write!(w, "[{}:{}] ", caller.file(), caller.line())?;
|
||||
}
|
||||
f(w)?;
|
||||
w.write_char('\n')
|
||||
});
|
||||
Err(LoggedError::default())
|
||||
}
|
||||
}
|
||||
#[cfg(not(debug_assertions))]
|
||||
fn log_with_msg<F: FnOnce(Formatter) -> fmt::Result>(self, f: F) -> LoggedResult<T> {
|
||||
do_log_msg(LogLevel::Error, None, f);
|
||||
self
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
#[cfg(debug_assertions)]
|
||||
fn log_with_msg<F: FnOnce(Formatter) -> fmt::Result>(self, f: F) -> LoggedResult<T> {
|
||||
let caller = Some(Location::caller());
|
||||
do_log_msg(LogLevel::Error, caller, f);
|
||||
self
|
||||
}
|
||||
|
||||
fn log_ok(self) {}
|
||||
}
|
||||
|
||||
impl<T, E: Display> Loggable<T> for Result<T, E> {
|
||||
fn do_log(self, level: LogLevel, caller: Option<&'static Location>) -> LoggedResult<T> {
|
||||
match self {
|
||||
Ok(v) => Ok(v),
|
||||
Err(e) => {
|
||||
if let Some(caller) = caller {
|
||||
log_with_args!(level, "[{}:{}] {:#}", caller.file(), caller.line(), e);
|
||||
} else {
|
||||
log_with_args!(level, "{:#}", e);
|
||||
}
|
||||
Err(LoggedError::default())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn do_log_msg<F: FnOnce(Formatter) -> fmt::Result>(
|
||||
self,
|
||||
level: LogLevel,
|
||||
caller: Option<&'static Location>,
|
||||
f: F,
|
||||
) -> LoggedResult<T> {
|
||||
match self {
|
||||
Ok(v) => Ok(v),
|
||||
Err(e) => {
|
||||
log_with_formatter(level, |w| {
|
||||
if let Some(caller) = caller {
|
||||
write!(w, "[{}:{}] ", caller.file(), caller.line())?;
|
||||
}
|
||||
f(w)?;
|
||||
writeln!(w, ": {e:#}")
|
||||
});
|
||||
Err(LoggedError::default())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Automatically convert all printable errors to LoggedError to support `?` operator
|
||||
impl<T: Display> From<T> for LoggedError {
|
||||
// Allow converting Loggable errors to LoggedError to support `?` operator
|
||||
impl<T: Loggable> From<T> for LoggedError {
|
||||
#[cfg(not(debug_assertions))]
|
||||
fn from(e: T) -> Self {
|
||||
log_with_args!(LogLevel::Error, "{:#}", e);
|
||||
LoggedError::default()
|
||||
e.do_log(LogLevel::Error, None)
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
#[cfg(debug_assertions)]
|
||||
fn from(e: T) -> Self {
|
||||
let caller = Location::caller();
|
||||
log_with_args!(
|
||||
LogLevel::Error,
|
||||
"[{}:{}] {:#}",
|
||||
caller.file(),
|
||||
caller.line(),
|
||||
e
|
||||
);
|
||||
let caller = Some(Location::caller());
|
||||
e.do_log(LogLevel::Error, caller)
|
||||
}
|
||||
}
|
||||
|
||||
// Actual logging implementation
|
||||
|
||||
// Make all printable objects Loggable
|
||||
impl<T: Display> Loggable for T {
|
||||
fn do_log(self, level: LogLevel, caller: Option<&'static Location>) -> LoggedError {
|
||||
if let Some(caller) = caller {
|
||||
log_with_args!(level, "[{}:{}] {:#}", caller.file(), caller.line(), self);
|
||||
} else {
|
||||
log_with_args!(level, "{:#}", self);
|
||||
}
|
||||
LoggedError::default()
|
||||
}
|
||||
|
||||
fn do_log_msg<F: FnOnce(Formatter) -> fmt::Result>(
|
||||
self,
|
||||
level: LogLevel,
|
||||
caller: Option<&'static Location>,
|
||||
f: F,
|
||||
) -> LoggedError {
|
||||
log_with_formatter(level, |w| {
|
||||
if let Some(caller) = caller {
|
||||
write!(w, "[{}:{}] ", caller.file(), caller.line())?;
|
||||
}
|
||||
f(w)?;
|
||||
writeln!(w, ": {self:#}")
|
||||
});
|
||||
LoggedError::default()
|
||||
}
|
||||
}
|
||||
|
||||
fn do_log_msg<F: FnOnce(Formatter) -> fmt::Result>(
|
||||
level: LogLevel,
|
||||
caller: Option<&'static Location>,
|
||||
f: F,
|
||||
) {
|
||||
log_with_formatter(level, |w| {
|
||||
if let Some(caller) = caller {
|
||||
write!(w, "[{}:{}] ", caller.file(), caller.line())?;
|
||||
}
|
||||
f(w)?;
|
||||
w.write_char('\n')
|
||||
});
|
||||
}
|
||||
|
||||
// Check libc return value and map to Result
|
||||
|
||||
@@ -5,8 +5,6 @@
|
||||
#include <bitset>
|
||||
#include <cxx.h>
|
||||
|
||||
#include "format.hpp"
|
||||
|
||||
/******************
|
||||
* Special Headers
|
||||
*****************/
|
||||
|
||||
@@ -296,156 +296,145 @@ fn sign_cmd(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn boot_main(cmds: CmdArgs) -> LoggedResult<i32> {
|
||||
let mut cmds = cmds.0;
|
||||
if cmds.len() < 2 {
|
||||
print_usage(cmds.first().unwrap_or(&"magiskboot"));
|
||||
return log_err!();
|
||||
}
|
||||
|
||||
if cmds[1].starts_with("--") {
|
||||
cmds[1] = &cmds[1][2..];
|
||||
}
|
||||
|
||||
if let Some(fmt) = str::strip_prefix(cmds[1], "compress=") {
|
||||
cmds.insert(1, "compress");
|
||||
cmds.insert(2, "-f");
|
||||
cmds[3] = fmt;
|
||||
}
|
||||
|
||||
let mut cli = Cli::from_args(&[cmds[0]], &cmds[1..]).on_early_exit(|| match cmds.get(1) {
|
||||
Some(&"dtb") => print_dtb_usage(),
|
||||
Some(&"cpio") => print_cpio_usage(),
|
||||
_ => print_usage(cmds[0]),
|
||||
});
|
||||
match cli.action {
|
||||
Action::Unpack(Unpack {
|
||||
no_decompress,
|
||||
dump_header,
|
||||
ref mut img,
|
||||
}) => {
|
||||
return Ok(unpack(
|
||||
Utf8CStr::from_string(img),
|
||||
no_decompress,
|
||||
dump_header,
|
||||
));
|
||||
}
|
||||
Action::Repack(Repack {
|
||||
no_compress,
|
||||
mut img,
|
||||
mut out,
|
||||
}) => {
|
||||
repack(
|
||||
Utf8CStr::from_string(&mut img),
|
||||
Utf8CStr::from_string(&mut out),
|
||||
no_compress,
|
||||
);
|
||||
}
|
||||
Action::Verify(Verify { mut img, mut cert }) => {
|
||||
if !verify_cmd(
|
||||
Utf8CStr::from_string(&mut img),
|
||||
cert.as_mut().map(Utf8CStr::from_string),
|
||||
) {
|
||||
return log_err!();
|
||||
}
|
||||
}
|
||||
Action::Sign(Sign { mut img, mut args }) => {
|
||||
let mut iter = args.iter_mut();
|
||||
sign_cmd(
|
||||
Utf8CStr::from_string(&mut img),
|
||||
iter.next().map(Utf8CStr::from_string),
|
||||
iter.next().map(Utf8CStr::from_string),
|
||||
iter.next().map(Utf8CStr::from_string),
|
||||
)?;
|
||||
}
|
||||
Action::Extract(Extract { payload, args }) => {
|
||||
if args.len() > 2 {
|
||||
log_err!("Too many arguments")?;
|
||||
}
|
||||
extract_boot_from_payload(
|
||||
&payload,
|
||||
args.first().map(|x| x.as_str()),
|
||||
args.get(1).map(|x| x.as_str()),
|
||||
)
|
||||
.log_with_msg(|w| w.write_str("Failed to extract from payload"))?;
|
||||
}
|
||||
Action::HexPatch(HexPatch {
|
||||
mut file,
|
||||
mut src,
|
||||
mut dest,
|
||||
}) => {
|
||||
if !hexpatch(
|
||||
&mut file,
|
||||
Utf8CStr::from_string(&mut src),
|
||||
Utf8CStr::from_string(&mut dest),
|
||||
) {
|
||||
log_err!("Failed to patch")?;
|
||||
}
|
||||
}
|
||||
Action::Cpio(Cpio { mut file, mut cmds }) => {
|
||||
cpio_commands(Utf8CStr::from_string(&mut file), &mut cmds)
|
||||
.log_with_msg(|w| w.write_str("Failed to process cpio"))?;
|
||||
}
|
||||
Action::Dtb(Dtb { mut file, action }) => {
|
||||
return dtb_commands(Utf8CStr::from_string(&mut file), &action)
|
||||
.map(|b| if b { 0 } else { 1 })
|
||||
.log_with_msg(|w| w.write_str("Failed to process dtb"));
|
||||
}
|
||||
Action::Split(Split {
|
||||
no_decompress,
|
||||
mut file,
|
||||
}) => {
|
||||
return Ok(split_image_dtb(
|
||||
Utf8CStr::from_string(&mut file),
|
||||
no_decompress,
|
||||
));
|
||||
}
|
||||
Action::Sha1(Sha1 { mut file }) => {
|
||||
let file = MappedFile::open(Utf8CStr::from_string(&mut file))?;
|
||||
let mut sha1 = [0u8; 20];
|
||||
sha1_hash(file.as_ref(), &mut sha1);
|
||||
for byte in &sha1 {
|
||||
print!("{byte:02x}");
|
||||
}
|
||||
println!();
|
||||
}
|
||||
Action::Cleanup(_) => {
|
||||
eprintln!("Cleaning up...");
|
||||
cleanup();
|
||||
}
|
||||
Action::Decompress(Decompress { mut file, mut out }) => {
|
||||
decompress(&mut file, out.as_mut())?;
|
||||
}
|
||||
Action::Compress(Compress {
|
||||
ref mut file,
|
||||
ref format,
|
||||
ref mut out,
|
||||
}) => {
|
||||
compress(
|
||||
FileFormat::from_str(format).unwrap_or(FileFormat::UNKNOWN),
|
||||
file,
|
||||
out.as_mut(),
|
||||
)?;
|
||||
}
|
||||
}
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn main(argc: i32, argv: *const *const c_char, _envp: *const *const c_char) -> i32 {
|
||||
cmdline_logging();
|
||||
unsafe { umask(0) };
|
||||
let res: LoggedResult<()> = try {
|
||||
let mut cmds = CmdArgs::new(argc, argv).0;
|
||||
if argc < 2 {
|
||||
print_usage(cmds.first().unwrap_or(&"magiskboot"));
|
||||
return 1;
|
||||
}
|
||||
|
||||
if cmds[1].starts_with("--") {
|
||||
cmds[1] = &cmds[1][2..];
|
||||
}
|
||||
|
||||
if let Some(fmt) = str::strip_prefix(cmds[1], "compress=") {
|
||||
cmds.insert(1, "compress");
|
||||
cmds.insert(2, "-f");
|
||||
cmds[3] = fmt;
|
||||
}
|
||||
|
||||
let mut cli = Cli::from_args(&[cmds[0]], &cmds[1..]).on_early_exit(|| match cmds.get(1) {
|
||||
Some(&"dtb") => print_dtb_usage(),
|
||||
Some(&"cpio") => print_cpio_usage(),
|
||||
_ => print_usage(cmds[0]),
|
||||
});
|
||||
match cli.action {
|
||||
Action::Unpack(Unpack {
|
||||
no_decompress,
|
||||
dump_header,
|
||||
ref mut img,
|
||||
}) => return unpack(Utf8CStr::from_string(img), no_decompress, dump_header),
|
||||
Action::Repack(Repack {
|
||||
no_compress,
|
||||
ref mut img,
|
||||
ref mut out,
|
||||
}) => {
|
||||
repack(
|
||||
Utf8CStr::from_string(img),
|
||||
Utf8CStr::from_string(out),
|
||||
no_compress,
|
||||
);
|
||||
}
|
||||
Action::Verify(Verify { mut img, mut cert }) => {
|
||||
return if verify_cmd(
|
||||
Utf8CStr::from_string(&mut img),
|
||||
cert.as_mut().map(Utf8CStr::from_string),
|
||||
) {
|
||||
0
|
||||
} else {
|
||||
1
|
||||
};
|
||||
}
|
||||
Action::Sign(Sign { mut img, mut args }) => {
|
||||
let mut iter = args.iter_mut();
|
||||
sign_cmd(
|
||||
Utf8CStr::from_string(&mut img),
|
||||
iter.next().map(Utf8CStr::from_string),
|
||||
iter.next().map(Utf8CStr::from_string),
|
||||
iter.next().map(Utf8CStr::from_string),
|
||||
)?;
|
||||
}
|
||||
Action::Extract(Extract {
|
||||
ref payload,
|
||||
ref args,
|
||||
}) => {
|
||||
if args.len() > 2 {
|
||||
Err(log_err!("Too many arguments"))?;
|
||||
}
|
||||
extract_boot_from_payload(
|
||||
payload,
|
||||
args.first().map(|x| x.as_str()),
|
||||
args.get(1).map(|x| x.as_str()),
|
||||
)
|
||||
.log_with_msg(|w| w.write_str("Failed to extract from payload"))?;
|
||||
}
|
||||
Action::HexPatch(HexPatch {
|
||||
ref mut file,
|
||||
ref mut src,
|
||||
ref mut dest,
|
||||
}) => {
|
||||
if !hexpatch(
|
||||
file,
|
||||
Utf8CStr::from_string(src),
|
||||
Utf8CStr::from_string(dest),
|
||||
) {
|
||||
Err(log_err!("Failed to patch"))?;
|
||||
}
|
||||
}
|
||||
Action::Cpio(Cpio {
|
||||
ref mut file,
|
||||
ref mut cmds,
|
||||
}) => {
|
||||
return if cpio_commands(file, cmds)
|
||||
.log_with_msg(|w| w.write_str("Failed to process cpio"))?
|
||||
{
|
||||
0
|
||||
} else {
|
||||
1
|
||||
};
|
||||
}
|
||||
Action::Dtb(Dtb {
|
||||
ref mut file,
|
||||
ref action,
|
||||
}) => {
|
||||
return if dtb_commands(file, action)
|
||||
.log_with_msg(|w| w.write_str("Failed to process dtb"))?
|
||||
{
|
||||
0
|
||||
} else {
|
||||
1
|
||||
};
|
||||
}
|
||||
Action::Split(Split {
|
||||
no_decompress,
|
||||
ref mut file,
|
||||
}) => {
|
||||
return split_image_dtb(Utf8CStr::from_string(file), no_decompress);
|
||||
}
|
||||
Action::Sha1(Sha1 { ref mut file }) => {
|
||||
let file = MappedFile::open(Utf8CStr::from_string(file))?;
|
||||
let mut sha1 = [0u8; 20];
|
||||
sha1_hash(file.as_ref(), &mut sha1);
|
||||
for byte in &sha1 {
|
||||
print!("{byte:02x}");
|
||||
}
|
||||
println!();
|
||||
}
|
||||
Action::Cleanup(_) => {
|
||||
eprintln!("Cleaning up...");
|
||||
cleanup();
|
||||
}
|
||||
Action::Decompress(Decompress {
|
||||
ref mut file,
|
||||
ref mut out,
|
||||
}) => {
|
||||
decompress(file, out.as_mut())?;
|
||||
}
|
||||
Action::Compress(Compress {
|
||||
ref mut file,
|
||||
ref format,
|
||||
ref mut out,
|
||||
}) => {
|
||||
compress(
|
||||
FileFormat::from_str(format).unwrap_or(FileFormat::UNKNOWN),
|
||||
file,
|
||||
out.as_mut(),
|
||||
)?;
|
||||
}
|
||||
}
|
||||
};
|
||||
if res.is_ok() { 0 } else { 1 }
|
||||
let cmds = CmdArgs::new(argc, argv);
|
||||
boot_main(cmds).unwrap_or(1)
|
||||
}
|
||||
|
||||
@@ -10,11 +10,11 @@ use lz4::{
|
||||
};
|
||||
use std::cell::Cell;
|
||||
use std::fs::File;
|
||||
use std::io::{BufWriter, Read, Stdin, Stdout, Write, stdin, stdout};
|
||||
use std::io::{BufWriter, Read, Write, stdin, stdout};
|
||||
use std::mem::ManuallyDrop;
|
||||
use std::num::NonZeroU64;
|
||||
use std::ops::DerefMut;
|
||||
use std::os::fd::{AsRawFd, FromRawFd, RawFd};
|
||||
use std::os::fd::{AsFd, AsRawFd, FromRawFd, RawFd};
|
||||
use xz2::{
|
||||
stream::{Check as LzmaCheck, Filters as LzmaFilters, LzmaOptions, Stream as LzmaStream},
|
||||
write::{XzDecoder, XzEncoder},
|
||||
@@ -426,59 +426,46 @@ pub fn decompress_bytes(format: FileFormat, in_bytes: &[u8], out_fd: RawFd) {
|
||||
};
|
||||
}
|
||||
|
||||
enum AsRawFdFile {
|
||||
Stdin(Stdin),
|
||||
Stdout(Stdout),
|
||||
File(File),
|
||||
}
|
||||
|
||||
impl AsRawFd for AsRawFdFile {
|
||||
fn as_raw_fd(&self) -> RawFd {
|
||||
match self {
|
||||
AsRawFdFile::Stdin(stdin) => stdin.as_raw_fd(),
|
||||
AsRawFdFile::Stdout(stdout) => stdout.as_raw_fd(),
|
||||
AsRawFdFile::File(file) => file.as_raw_fd(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn decompress(infile: &mut String, outfile: Option<&mut String>) -> LoggedResult<()> {
|
||||
let in_std = infile == "-";
|
||||
let mut rm_in = false;
|
||||
|
||||
let raw_in = if in_std {
|
||||
AsRawFdFile::Stdin(stdin())
|
||||
} else {
|
||||
AsRawFdFile::File(Utf8CStr::from_string(infile).open(O_RDONLY)?)
|
||||
};
|
||||
|
||||
let mut buf = [0u8; 4096];
|
||||
|
||||
let mut in_file = unsafe { File::from_raw_fd(raw_in.as_raw_fd()) };
|
||||
let _ = in_file.read(&mut buf)?;
|
||||
let raw_in = if in_std {
|
||||
super let mut stdin = stdin();
|
||||
let _ = stdin.read(&mut buf)?;
|
||||
stdin.as_fd()
|
||||
} else {
|
||||
super let mut infile = Utf8CStr::from_string(infile).open(O_RDONLY)?;
|
||||
let _ = infile.read(&mut buf)?;
|
||||
infile.as_fd()
|
||||
};
|
||||
|
||||
let format = check_fmt(&buf);
|
||||
|
||||
eprintln!("Detected format: {format}");
|
||||
|
||||
if !format.is_compressed() {
|
||||
return Err(log_err!("Input file is not a supported type!"));
|
||||
return log_err!("Input file is not a supported type!");
|
||||
}
|
||||
|
||||
let raw_out = if let Some(outfile) = outfile {
|
||||
if outfile == "-" {
|
||||
AsRawFdFile::Stdout(stdout())
|
||||
super let stdout = stdout();
|
||||
stdout.as_fd()
|
||||
} else {
|
||||
AsRawFdFile::File(Utf8CStr::from_string(outfile).create(O_WRONLY | O_TRUNC, 0o644)?)
|
||||
super let outfile = Utf8CStr::from_string(outfile).create(O_WRONLY | O_TRUNC, 0o644)?;
|
||||
outfile.as_fd()
|
||||
}
|
||||
} else if in_std {
|
||||
AsRawFdFile::Stdout(stdout())
|
||||
super let stdout = stdout();
|
||||
stdout.as_fd()
|
||||
} else {
|
||||
// strip the extension
|
||||
rm_in = true;
|
||||
let mut outfile = if let Some((outfile, ext)) = infile.rsplit_once('.') {
|
||||
if ext != format.ext() {
|
||||
Err(log_err!("Input file is not a supported type!"))?;
|
||||
log_err!("Input file is not a supported type!")?;
|
||||
}
|
||||
outfile.to_owned()
|
||||
} else {
|
||||
@@ -486,7 +473,8 @@ pub(crate) fn decompress(infile: &mut String, outfile: Option<&mut String>) -> L
|
||||
};
|
||||
eprintln!("Decompressing to [{outfile}]");
|
||||
|
||||
AsRawFdFile::File(Utf8CStr::from_string(&mut outfile).create(O_WRONLY | O_TRUNC, 0o644)?)
|
||||
super let outfile = Utf8CStr::from_string(&mut outfile).create(O_WRONLY | O_TRUNC, 0o644)?;
|
||||
outfile.as_fd()
|
||||
};
|
||||
|
||||
decompress_bytes_fd(format, &buf, raw_in.as_raw_fd(), raw_out.as_raw_fd());
|
||||
@@ -511,24 +499,30 @@ pub(crate) fn compress(
|
||||
let mut rm_in = false;
|
||||
|
||||
let raw_in = if in_std {
|
||||
AsRawFdFile::Stdin(stdin())
|
||||
super let stdin = stdin();
|
||||
stdin.as_fd()
|
||||
} else {
|
||||
AsRawFdFile::File(Utf8CStr::from_string(infile).open(O_RDONLY)?)
|
||||
super let infile = Utf8CStr::from_string(infile).open(O_RDONLY)?;
|
||||
infile.as_fd()
|
||||
};
|
||||
|
||||
let raw_out = if let Some(outfile) = outfile {
|
||||
if outfile == "-" {
|
||||
AsRawFdFile::Stdout(stdout())
|
||||
super let stdout = stdout();
|
||||
stdout.as_fd()
|
||||
} else {
|
||||
AsRawFdFile::File(Utf8CStr::from_string(outfile).create(O_WRONLY | O_TRUNC, 0o644)?)
|
||||
super let outfile = Utf8CStr::from_string(outfile).create(O_WRONLY | O_TRUNC, 0o644)?;
|
||||
outfile.as_fd()
|
||||
}
|
||||
} else if in_std {
|
||||
AsRawFdFile::Stdout(stdout())
|
||||
super let stdout = stdout();
|
||||
stdout.as_fd()
|
||||
} else {
|
||||
let mut outfile = format!("{infile}.{}", method.ext());
|
||||
eprintln!("Compressing to [{outfile}]");
|
||||
rm_in = true;
|
||||
AsRawFdFile::File(Utf8CStr::from_string(&mut outfile).create(O_WRONLY | O_TRUNC, 0o644)?)
|
||||
super let outfile = Utf8CStr::from_string(&mut outfile).create(O_WRONLY | O_TRUNC, 0o644)?;
|
||||
outfile.as_fd()
|
||||
};
|
||||
|
||||
compress_fd(method, raw_in.as_raw_fd(), raw_out.as_raw_fd());
|
||||
|
||||
@@ -20,8 +20,8 @@ use base::libc::{
|
||||
dev_t, gid_t, major, makedev, minor, mknod, mode_t, uid_t,
|
||||
};
|
||||
use base::{
|
||||
BytesExt, EarlyExitExt, LoggedResult, MappedFile, ResultExt, Utf8CStr, Utf8CStrBuf, WriteExt,
|
||||
cstr, log_err,
|
||||
BytesExt, EarlyExitExt, LoggedResult, MappedFile, OptionExt, ResultExt, Utf8CStr, Utf8CStrBuf,
|
||||
WriteExt, cstr, log_err,
|
||||
};
|
||||
|
||||
use crate::check_env;
|
||||
@@ -227,7 +227,7 @@ impl Cpio {
|
||||
let hdr_sz = size_of::<CpioHeader>();
|
||||
let hdr = from_bytes::<CpioHeader>(&data[pos..(pos + hdr_sz)]);
|
||||
if &hdr.magic != b"070701" {
|
||||
return Err(log_err!("invalid cpio magic"));
|
||||
return log_err!("invalid cpio magic");
|
||||
}
|
||||
pos += hdr_sz;
|
||||
let name_sz = x8u(&hdr.namesize)? as usize;
|
||||
@@ -331,7 +331,7 @@ impl Cpio {
|
||||
let entry = self
|
||||
.entries
|
||||
.get(path)
|
||||
.ok_or_else(|| log_err!("No such file"))?;
|
||||
.ok_or_log_msg(|w| w.write_str("No such file"))?;
|
||||
eprintln!("Extracting entry [{path}] to [{out}]");
|
||||
|
||||
let out = Utf8CStr::from_string(out);
|
||||
@@ -362,7 +362,7 @@ impl Cpio {
|
||||
unsafe { mknod(out.as_ptr().cast(), entry.mode, dev) };
|
||||
}
|
||||
_ => {
|
||||
return Err(log_err!("unknown entry type"));
|
||||
return log_err!("unknown entry type");
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
@@ -389,7 +389,7 @@ impl Cpio {
|
||||
|
||||
fn add(&mut self, mode: mode_t, path: &str, file: &mut String) -> LoggedResult<()> {
|
||||
if path.ends_with('/') {
|
||||
return Err(log_err!("path cannot end with / for add"));
|
||||
return log_err!("path cannot end with / for add");
|
||||
}
|
||||
let file = Utf8CStr::from_string(file);
|
||||
let attr = file.get_attr()?;
|
||||
@@ -412,7 +412,7 @@ impl Cpio {
|
||||
} else if attr.is_char_device() {
|
||||
mode | S_IFCHR
|
||||
} else {
|
||||
return Err(log_err!("unsupported file type"));
|
||||
return log_err!("unsupported file type");
|
||||
}
|
||||
};
|
||||
|
||||
@@ -465,7 +465,7 @@ impl Cpio {
|
||||
let entry = self
|
||||
.entries
|
||||
.remove(&norm_path(from))
|
||||
.ok_or_else(|| log_err!("no such entry {}", from))?;
|
||||
.ok_or_log_msg(|w| w.write_fmt(format_args!("No such entry {from}")))?;
|
||||
self.entries.insert(norm_path(to), entry);
|
||||
eprintln!("Move [{from}] -> [{to}]");
|
||||
Ok(())
|
||||
@@ -753,8 +753,7 @@ impl Display for CpioEntry {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn cpio_commands(file: &mut String, cmds: &mut Vec<String>) -> LoggedResult<bool> {
|
||||
let file = Utf8CStr::from_string(file);
|
||||
pub(crate) fn cpio_commands(file: &Utf8CStr, cmds: &mut Vec<String>) -> LoggedResult<()> {
|
||||
let mut cpio = if file.exists() {
|
||||
Cpio::load_from_file(file)?
|
||||
} else {
|
||||
@@ -779,7 +778,11 @@ pub(crate) fn cpio_commands(file: &mut String, cmds: &mut Vec<String>) -> Logged
|
||||
CpioAction::Restore(_) => cpio.restore()?,
|
||||
CpioAction::Patch(_) => cpio.patch(),
|
||||
CpioAction::Exists(Exists { path }) => {
|
||||
return Ok(cpio.exists(path));
|
||||
return if cpio.exists(path) {
|
||||
Ok(())
|
||||
} else {
|
||||
log_err!()
|
||||
};
|
||||
}
|
||||
CpioAction::Backup(Backup {
|
||||
origin,
|
||||
@@ -792,19 +795,19 @@ pub(crate) fn cpio_commands(file: &mut String, cmds: &mut Vec<String>) -> Logged
|
||||
CpioAction::Add(Add { mode, path, file }) => cpio.add(*mode, path, file)?,
|
||||
CpioAction::Extract(Extract { paths }) => {
|
||||
if !paths.is_empty() && paths.len() != 2 {
|
||||
Err(log_err!("invalid arguments"))?;
|
||||
log_err!("invalid arguments")?;
|
||||
}
|
||||
let mut it = paths.iter_mut();
|
||||
cpio.extract(it.next(), it.next())?;
|
||||
}
|
||||
CpioAction::List(List { path, recursive }) => {
|
||||
cpio.ls(path.as_str(), *recursive);
|
||||
return Ok(true);
|
||||
return Ok(());
|
||||
}
|
||||
};
|
||||
}
|
||||
cpio.dump(file)?;
|
||||
Ok(true)
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn x8u(x: &[u8; 8]) -> LoggedResult<u32> {
|
||||
@@ -812,7 +815,9 @@ fn x8u(x: &[u8; 8]) -> LoggedResult<u32> {
|
||||
let mut ret = 0u32;
|
||||
let s = str::from_utf8(x).log_with_msg(|w| w.write_str("bad cpio header"))?;
|
||||
for c in s.chars() {
|
||||
ret = ret * 16 + c.to_digit(16).ok_or_else(|| log_err!("bad cpio header"))?;
|
||||
ret = ret * 16
|
||||
+ c.to_digit(16)
|
||||
.ok_or_log_msg(|w| w.write_str("bad cpio header"))?;
|
||||
}
|
||||
Ok(ret)
|
||||
}
|
||||
|
||||
@@ -264,8 +264,7 @@ fn dtb_patch(file: &Utf8CStr) -> LoggedResult<bool> {
|
||||
Ok(patched)
|
||||
}
|
||||
|
||||
pub(crate) fn dtb_commands(file: &mut String, action: &DtbAction) -> LoggedResult<bool> {
|
||||
let file = Utf8CStr::from_string(file);
|
||||
pub(crate) fn dtb_commands(file: &Utf8CStr, action: &DtbAction) -> LoggedResult<bool> {
|
||||
match action {
|
||||
DtbAction::Print(Print { fstab }) => {
|
||||
dtb_print(file, *fstab)?;
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
enum class FileFormat : ::std::uint8_t;
|
||||
|
||||
#define BUFFER_MATCH(buf, s) (memcmp(buf, s, sizeof(s) - 1) == 0)
|
||||
#define BUFFER_CONTAIN(buf, sz, s) (memmem(buf, sz, s, sizeof(s) - 1) != nullptr)
|
||||
#define CHECKED_MATCH(s) (len >= (sizeof(s) - 1) && BUFFER_MATCH(buf, s))
|
||||
|
||||
#define BOOT_MAGIC "ANDROID!"
|
||||
#define VENDOR_BOOT_MAGIC "VNDRBOOT"
|
||||
#define CHROMEOS_MAGIC "CHROMEOS"
|
||||
#define GZIP1_MAGIC "\x1f\x8b"
|
||||
#define GZIP2_MAGIC "\x1f\x9e"
|
||||
#define LZOP_MAGIC "\x89""LZO"
|
||||
#define XZ_MAGIC "\xfd""7zXZ"
|
||||
#define BZIP_MAGIC "BZh"
|
||||
#define LZ4_LEG_MAGIC "\x02\x21\x4c\x18"
|
||||
#define LZ41_MAGIC "\x03\x21\x4c\x18"
|
||||
#define LZ42_MAGIC "\x04\x22\x4d\x18"
|
||||
#define MTK_MAGIC "\x88\x16\x88\x58"
|
||||
#define DTB_MAGIC "\xd0\x0d\xfe\xed"
|
||||
#define LG_BUMP_MAGIC "\x41\xa9\xe4\x67\x74\x4d\x1d\x1b\xa4\x29\xf2\xec\xea\x65\x52\x79"
|
||||
#define DHTB_MAGIC "\x44\x48\x54\x42\x01\x00\x00\x00"
|
||||
#define SEANDROID_MAGIC "SEANDROIDENFORCE"
|
||||
#define TEGRABLOB_MAGIC "-SIGNED-BY-SIGNBLOB-"
|
||||
#define NOOKHD_RL_MAGIC "Red Loader"
|
||||
#define NOOKHD_GL_MAGIC "Green Loader"
|
||||
#define NOOKHD_GR_MAGIC "Green Recovery"
|
||||
#define NOOKHD_EB_MAGIC "eMMC boot.img+secondloader"
|
||||
#define NOOKHD_ER_MAGIC "eMMC recovery.img+secondloader"
|
||||
#define NOOKHD_PRE_HEADER_SZ 1048576
|
||||
#define ACCLAIM_MAGIC "BauwksBoot"
|
||||
#define ACCLAIM_PRE_HEADER_SZ 262144
|
||||
#define AMONET_MICROLOADER_MAGIC "microloader"
|
||||
#define AMONET_MICROLOADER_SZ 1024
|
||||
#define AVB_FOOTER_MAGIC "AVBf"
|
||||
#define AVB_MAGIC "AVB0"
|
||||
#define ZIMAGE_MAGIC "\x18\x28\x6f\x01"
|
||||
|
||||
FileFormat check_fmt(const void *buf, size_t len);
|
||||
|
||||
static inline FileFormat check_fmt(rust::Slice<const uint8_t> bytes) {
|
||||
return check_fmt(bytes.data(), bytes.size());
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
#![feature(btree_extract_if)]
|
||||
#![feature(iter_intersperse)]
|
||||
#![feature(try_blocks)]
|
||||
#![feature(super_let)]
|
||||
|
||||
pub use base;
|
||||
use compress::{compress_bytes, decompress_bytes};
|
||||
@@ -57,14 +58,12 @@ pub mod ffi {
|
||||
}
|
||||
|
||||
unsafe extern "C++" {
|
||||
include!("format.hpp");
|
||||
fn check_fmt(buf: &[u8]) -> FileFormat;
|
||||
|
||||
include!("magiskboot.hpp");
|
||||
fn cleanup();
|
||||
fn unpack(image: Utf8CStrRef, skip_decomp: bool, hdr: bool) -> i32;
|
||||
fn repack(src_img: Utf8CStrRef, out_img: Utf8CStrRef, skip_comp: bool);
|
||||
fn split_image_dtb(filename: Utf8CStrRef, skip_decomp: bool) -> i32;
|
||||
fn check_fmt(buf: &[u8]) -> FileFormat;
|
||||
}
|
||||
|
||||
extern "Rust" {
|
||||
|
||||
@@ -12,7 +12,49 @@
|
||||
#define BOOTCONFIG_FILE "bootconfig"
|
||||
#define NEW_BOOT "new-boot.img"
|
||||
|
||||
#define BUFFER_MATCH(buf, s) (memcmp(buf, s, sizeof(s) - 1) == 0)
|
||||
#define BUFFER_CONTAIN(buf, sz, s) (memmem(buf, sz, s, sizeof(s) - 1) != nullptr)
|
||||
#define CHECKED_MATCH(s) (len >= (sizeof(s) - 1) && BUFFER_MATCH(buf, s))
|
||||
|
||||
#define BOOT_MAGIC "ANDROID!"
|
||||
#define VENDOR_BOOT_MAGIC "VNDRBOOT"
|
||||
#define CHROMEOS_MAGIC "CHROMEOS"
|
||||
#define GZIP1_MAGIC "\x1f\x8b"
|
||||
#define GZIP2_MAGIC "\x1f\x9e"
|
||||
#define LZOP_MAGIC "\x89""LZO"
|
||||
#define XZ_MAGIC "\xfd""7zXZ"
|
||||
#define BZIP_MAGIC "BZh"
|
||||
#define LZ4_LEG_MAGIC "\x02\x21\x4c\x18"
|
||||
#define LZ41_MAGIC "\x03\x21\x4c\x18"
|
||||
#define LZ42_MAGIC "\x04\x22\x4d\x18"
|
||||
#define MTK_MAGIC "\x88\x16\x88\x58"
|
||||
#define DTB_MAGIC "\xd0\x0d\xfe\xed"
|
||||
#define LG_BUMP_MAGIC "\x41\xa9\xe4\x67\x74\x4d\x1d\x1b\xa4\x29\xf2\xec\xea\x65\x52\x79"
|
||||
#define DHTB_MAGIC "\x44\x48\x54\x42\x01\x00\x00\x00"
|
||||
#define SEANDROID_MAGIC "SEANDROIDENFORCE"
|
||||
#define TEGRABLOB_MAGIC "-SIGNED-BY-SIGNBLOB-"
|
||||
#define NOOKHD_RL_MAGIC "Red Loader"
|
||||
#define NOOKHD_GL_MAGIC "Green Loader"
|
||||
#define NOOKHD_GR_MAGIC "Green Recovery"
|
||||
#define NOOKHD_EB_MAGIC "eMMC boot.img+secondloader"
|
||||
#define NOOKHD_ER_MAGIC "eMMC recovery.img+secondloader"
|
||||
#define NOOKHD_PRE_HEADER_SZ 1048576
|
||||
#define ACCLAIM_MAGIC "BauwksBoot"
|
||||
#define ACCLAIM_PRE_HEADER_SZ 262144
|
||||
#define AMONET_MICROLOADER_MAGIC "microloader"
|
||||
#define AMONET_MICROLOADER_SZ 1024
|
||||
#define AVB_FOOTER_MAGIC "AVBf"
|
||||
#define AVB_MAGIC "AVB0"
|
||||
#define ZIMAGE_MAGIC "\x18\x28\x6f\x01"
|
||||
|
||||
enum class FileFormat : ::std::uint8_t;
|
||||
|
||||
int unpack(rust::Utf8CStr image, bool skip_decomp = false, bool hdr = false);
|
||||
void repack(rust::Utf8CStr src_img, rust::Utf8CStr out_img, bool skip_comp = false);
|
||||
int split_image_dtb(rust::Utf8CStr filename, bool skip_decomp = false);
|
||||
void cleanup();
|
||||
FileFormat check_fmt(const void *buf, size_t len);
|
||||
|
||||
static inline FileFormat check_fmt(rust::Slice<const uint8_t> bytes) {
|
||||
return check_fmt(bytes.data(), bytes.size());
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ use x509_cert::der::Any;
|
||||
use x509_cert::der::asn1::{OctetString, PrintableString};
|
||||
use x509_cert::spki::AlgorithmIdentifier;
|
||||
|
||||
use base::{LoggedError, LoggedResult, MappedFile, ResultExt, Utf8CStr, cstr, log_err};
|
||||
use base::{LoggedResult, MappedFile, ResultExt, Utf8CStr, cstr, log_err};
|
||||
|
||||
use crate::ffi::BootImage;
|
||||
|
||||
@@ -116,7 +116,7 @@ impl Verifier {
|
||||
digest = Box::<Sha512>::default();
|
||||
VerifyingKey::SHA521withECDSA(ec)
|
||||
} else {
|
||||
return Err(log_err!("Unsupported private key"));
|
||||
return log_err!("Unsupported private key");
|
||||
};
|
||||
Ok(Verifier { digest, key })
|
||||
}
|
||||
@@ -177,7 +177,7 @@ impl Signer {
|
||||
SigningKey::SHA521withECDSA(ec)
|
||||
}
|
||||
_ => {
|
||||
return Err(log_err!("Unsupported private key"));
|
||||
return log_err!("Unsupported private key");
|
||||
}
|
||||
},
|
||||
},
|
||||
@@ -248,7 +248,7 @@ struct BootSignature {
|
||||
impl BootSignature {
|
||||
fn verify(self, payload: &[u8]) -> LoggedResult<()> {
|
||||
if self.authenticated_attributes.length as usize != payload.len() {
|
||||
return Err(log_err!("Invalid image size"));
|
||||
return log_err!("Invalid image size");
|
||||
}
|
||||
let mut verifier = Verifier::from_public_key(
|
||||
self.certificate
|
||||
@@ -268,7 +268,7 @@ impl BootImage {
|
||||
pub fn verify(&self, cert: Option<&Utf8CStr>) -> LoggedResult<()> {
|
||||
let tail = self.tail();
|
||||
if tail.starts_with(b"AVB0") {
|
||||
return Err(LoggedError::default());
|
||||
return log_err!();
|
||||
}
|
||||
|
||||
// Don't use BootSignature::from_der because tail might have trailing zeros
|
||||
|
||||
@@ -307,7 +307,7 @@ pub fn daemon_entry() {
|
||||
|
||||
// Remove all pre-init overlay files to free-up memory
|
||||
tmp_path.append_path(ROOTOVL);
|
||||
tmp_path.remove_all().log_ok();
|
||||
tmp_path.remove_all().ok();
|
||||
tmp_path.truncate(magisk_tmp.len());
|
||||
|
||||
let magiskd = MagiskD {
|
||||
|
||||
@@ -4,8 +4,8 @@ use crate::ffi::{ModuleInfo, exec_module_scripts, exec_script, get_magisk_tmp, l
|
||||
use crate::mount::setup_module_mount;
|
||||
use base::{
|
||||
DirEntry, Directory, FsPathBuilder, LibcReturn, LoggedResult, OsResultStatic, ResultExt,
|
||||
Utf8CStr, Utf8CStrBuf, Utf8CString, WalkResult, clone_attr, cstr, debug, error, info, libc,
|
||||
raw_cstr, warn,
|
||||
SilentLogExt, Utf8CStr, Utf8CStrBuf, Utf8CString, WalkResult, clone_attr, cstr, debug, error,
|
||||
info, libc, raw_cstr, warn,
|
||||
};
|
||||
use libc::{AT_REMOVEDIR, MS_RDONLY, O_CLOEXEC, O_CREAT, O_RDONLY};
|
||||
use std::collections::BTreeMap;
|
||||
@@ -556,7 +556,7 @@ fn inject_zygisk_bins(name: &str, system: &mut FsNode) {
|
||||
}
|
||||
|
||||
fn upgrade_modules() -> LoggedResult<()> {
|
||||
let mut upgrade = Directory::open(cstr!(MODULEUPGRADE))?;
|
||||
let mut upgrade = Directory::open(cstr!(MODULEUPGRADE)).silent()?;
|
||||
let ufd = upgrade.as_raw_fd();
|
||||
let root = Directory::open(cstr!(MODULEROOT))?;
|
||||
while let Some(e) = upgrade.read()? {
|
||||
|
||||
@@ -16,7 +16,7 @@ use crate::resetprop::proto::persistent_properties::{
|
||||
use base::const_format::concatcp;
|
||||
use base::libc::{O_CLOEXEC, O_RDONLY};
|
||||
use base::{
|
||||
Directory, FsPathBuilder, LibcReturn, LoggedResult, MappedFile, SilentResultExt, Utf8CStr,
|
||||
Directory, FsPathBuilder, LibcReturn, LoggedResult, MappedFile, SilentLogExt, Utf8CStr,
|
||||
Utf8CStrBuf, WalkResult, clone_attr, cstr, debug, libc::mkstemp,
|
||||
};
|
||||
|
||||
|
||||
@@ -6,8 +6,8 @@ use crate::ffi::{
|
||||
use crate::socket::{IpcRead, UnixSocketExt};
|
||||
use base::libc::{O_CLOEXEC, O_CREAT, O_RDONLY, STDOUT_FILENO};
|
||||
use base::{
|
||||
Directory, FsPathBuilder, LoggedError, LoggedResult, ResultExt, Utf8CStr, WriteExt, cstr,
|
||||
fork_dont_care, libc, raw_cstr, warn,
|
||||
Directory, FsPathBuilder, LoggedResult, ResultExt, Utf8CStr, WriteExt, cstr, fork_dont_care,
|
||||
libc, log_err, raw_cstr, warn,
|
||||
};
|
||||
use std::fmt::Write;
|
||||
use std::os::fd::{AsRawFd, FromRawFd, RawFd};
|
||||
@@ -101,7 +101,7 @@ impl ZygiskState {
|
||||
local.send_fds(&module_fds)?;
|
||||
}
|
||||
if local.read_decodable::<i32>()? != 0 {
|
||||
Err(LoggedError::default())?;
|
||||
return log_err!();
|
||||
}
|
||||
local
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use base::{
|
||||
LOGGER, LogLevel, Logger, SilentResultExt, Utf8CStr, cstr,
|
||||
LOGGER, LogLevel, Logger, SilentLogExt, Utf8CStr, cstr,
|
||||
libc::{
|
||||
O_CLOEXEC, O_RDWR, O_WRONLY, S_IFCHR, STDERR_FILENO, STDIN_FILENO, STDOUT_FILENO, SYS_dup3,
|
||||
makedev, mknod, syscall,
|
||||
|
||||
@@ -92,10 +92,10 @@ pub unsafe extern "C" fn main(
|
||||
(None, true, false) => SePolicy::from_split(),
|
||||
(None, false, true) => SePolicy::compile_split(),
|
||||
(None, false, false) => SePolicy::from_file(cstr!("/sys/fs/selinux/policy")),
|
||||
_ => Err(log_err!("Multiple load source supplied"))?,
|
||||
_ => log_err!("Multiple load source supplied")?,
|
||||
};
|
||||
if sepol._impl.is_null() {
|
||||
Err(log_err!("Cannot load policy"))?;
|
||||
log_err!("Cannot load policy")?;
|
||||
}
|
||||
|
||||
if cli.print_rules {
|
||||
@@ -105,7 +105,7 @@ pub unsafe extern "C" fn main(
|
||||
|| cli.live
|
||||
|| cli.save.is_some()
|
||||
{
|
||||
Err(log_err!("Cannot print rules with other options"))?;
|
||||
log_err!("Cannot print rules with other options")?;
|
||||
}
|
||||
sepol.print_rules();
|
||||
return 0;
|
||||
@@ -124,12 +124,12 @@ pub unsafe extern "C" fn main(
|
||||
}
|
||||
|
||||
if cli.live && !sepol.to_file(cstr!("/sys/fs/selinux/load")) {
|
||||
Err(log_err!("Cannot apply policy"))?;
|
||||
log_err!("Cannot apply policy")?;
|
||||
}
|
||||
|
||||
if let Some(file) = &mut cli.save {
|
||||
if !sepol.to_file(Utf8CStr::from_string(file)) {
|
||||
Err(log_err!("Cannot dump policy to {}", file))?;
|
||||
log_err!("Cannot dump policy to {}", file)?;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user