mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-12-22 07:57:39 +00:00
Handle cpio commands properly
This commit is contained in:
parent
43b9a09c9b
commit
5ee6daf126
1
native/src/Cargo.lock
generated
1
native/src/Cargo.lock
generated
@ -69,6 +69,7 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
|||||||
name = "base"
|
name = "base"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"argh",
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"cxx",
|
"cxx",
|
||||||
"cxx-gen",
|
"cxx-gen",
|
||||||
|
@ -14,3 +14,4 @@ cxx = { workspace = true }
|
|||||||
libc = { workspace = true }
|
libc = { workspace = true }
|
||||||
cfg-if = { workspace = true }
|
cfg-if = { workspace = true }
|
||||||
thiserror = { workspace = true }
|
thiserror = { workspace = true }
|
||||||
|
argh = { workspace = true }
|
||||||
|
@ -3,9 +3,11 @@ use std::ffi::{CStr, FromBytesWithNulError, OsStr};
|
|||||||
use std::fmt::{Arguments, Debug, Display, Formatter};
|
use std::fmt::{Arguments, Debug, Display, Formatter};
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
use std::process::exit;
|
||||||
use std::str::Utf8Error;
|
use std::str::Utf8Error;
|
||||||
use std::{fmt, io, mem, slice, str};
|
use std::{fmt, io, mem, slice, str};
|
||||||
|
|
||||||
|
use argh::EarlyExit;
|
||||||
use libc::c_char;
|
use libc::c_char;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
@ -297,18 +299,18 @@ where
|
|||||||
fn as_raw_bytes(&self) -> &[u8] {
|
fn as_raw_bytes(&self) -> &[u8] {
|
||||||
unsafe {
|
unsafe {
|
||||||
let self_ptr = self as *const Self as *const u8;
|
let self_ptr = self as *const Self as *const u8;
|
||||||
slice::from_raw_parts(self_ptr, std::mem::size_of::<Self>())
|
slice::from_raw_parts(self_ptr, mem::size_of::<Self>())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn as_raw_bytes_mut(&mut self) -> &mut [u8] {
|
fn as_raw_bytes_mut(&mut self) -> &mut [u8] {
|
||||||
unsafe {
|
unsafe {
|
||||||
let self_ptr = self as *mut Self as *mut u8;
|
let self_ptr = self as *mut Self as *mut u8;
|
||||||
slice::from_raw_parts_mut(self_ptr, std::mem::size_of::<Self>())
|
slice::from_raw_parts_mut(self_ptr, mem::size_of::<Self>())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bytes_size(&self) -> usize {
|
fn bytes_size(&self) -> usize {
|
||||||
std::mem::size_of::<Self>()
|
mem::size_of::<Self>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -369,3 +371,34 @@ impl<T: AsMut<[u8]>> MutBytesExt for T {
|
|||||||
ffi::mut_u8_patch(self.as_mut(), from, to)
|
ffi::mut_u8_patch(self.as_mut(), from, to)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SAFETY: libc guarantees argc and argv is properly setup
|
||||||
|
#[allow(clippy::not_unsafe_ptr_arg_deref)]
|
||||||
|
pub fn map_args<'a>(argc: i32, argv: *const *const c_char) -> Result<Vec<&'a Utf8CStr>, StrErr> {
|
||||||
|
unsafe { slice::from_raw_parts(argv, argc as usize) }
|
||||||
|
.iter()
|
||||||
|
.map(|s| unsafe { Utf8CStr::from_ptr(*s) })
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait EarlyExitExt<T> {
|
||||||
|
fn early_exit(self) -> T;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> EarlyExitExt<T> for Result<T, EarlyExit> {
|
||||||
|
fn early_exit(self) -> T {
|
||||||
|
match self {
|
||||||
|
Ok(t) => t,
|
||||||
|
Err(EarlyExit { output, status }) => match status {
|
||||||
|
Ok(_) => {
|
||||||
|
eprintln!("{}", output);
|
||||||
|
exit(0)
|
||||||
|
}
|
||||||
|
Err(_) => {
|
||||||
|
eprintln!("{}", output);
|
||||||
|
exit(1)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -7,9 +7,8 @@ use std::mem::size_of;
|
|||||||
use std::os::unix::fs::{symlink, DirBuilderExt, FileTypeExt, MetadataExt};
|
use std::os::unix::fs::{symlink, DirBuilderExt, FileTypeExt, MetadataExt};
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::process::exit;
|
use std::process::exit;
|
||||||
use std::slice;
|
|
||||||
|
|
||||||
use argh::{EarlyExit, FromArgs};
|
use argh::FromArgs;
|
||||||
use size::{Base, Size, Style};
|
use size::{Base, Size, Style};
|
||||||
|
|
||||||
use base::libc::{
|
use base::libc::{
|
||||||
@ -17,7 +16,9 @@ use base::libc::{
|
|||||||
S_IFLNK, S_IFMT, S_IFREG, S_IRGRP, S_IROTH, S_IRUSR, S_IWGRP, S_IWOTH, S_IWUSR, S_IXGRP,
|
S_IFLNK, S_IFMT, S_IFREG, S_IRGRP, S_IROTH, S_IRUSR, S_IWGRP, S_IWOTH, S_IWUSR, S_IXGRP,
|
||||||
S_IXOTH, S_IXUSR,
|
S_IXOTH, S_IXUSR,
|
||||||
};
|
};
|
||||||
use base::{log_err, LoggedResult, MappedFile, ResultExt, StrErr, Utf8CStr, WriteExt};
|
use base::{
|
||||||
|
log_err, map_args, EarlyExitExt, LoggedResult, MappedFile, ResultExt, Utf8CStr, WriteExt,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::ramdisk::MagiskCpio;
|
use crate::ramdisk::MagiskCpio;
|
||||||
|
|
||||||
@ -525,12 +526,7 @@ pub fn cpio_commands(argc: i32, argv: *const *const c_char) -> bool {
|
|||||||
return Err(log_err!("no arguments"));
|
return Err(log_err!("no arguments"));
|
||||||
}
|
}
|
||||||
|
|
||||||
let cmds: Result<Vec<&Utf8CStr>, StrErr> =
|
let cmds = map_args(argc, argv)?;
|
||||||
unsafe { slice::from_raw_parts(argv, argc as usize) }
|
|
||||||
.iter()
|
|
||||||
.map(|s| unsafe { Utf8CStr::from_ptr(*s) })
|
|
||||||
.collect();
|
|
||||||
let cmds = cmds?;
|
|
||||||
|
|
||||||
let file = cmds[0];
|
let file = cmds[0];
|
||||||
let mut cpio = if Path::new(file).exists() {
|
let mut cpio = if Path::new(file).exists() {
|
||||||
@ -538,26 +534,20 @@ pub fn cpio_commands(argc: i32, argv: *const *const c_char) -> bool {
|
|||||||
} else {
|
} else {
|
||||||
Cpio::new()
|
Cpio::new()
|
||||||
};
|
};
|
||||||
|
|
||||||
for cmd in &cmds[1..] {
|
for cmd in &cmds[1..] {
|
||||||
if cmd.starts_with('#') {
|
if cmd.starts_with('#') {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let mut cli = match CpioCli::from_args(
|
let mut cli = CpioCli::from_args(
|
||||||
&["magiskboot", "cpio", file],
|
&["magiskboot", "cpio", file],
|
||||||
cmd.split(' ')
|
cmd.split(' ')
|
||||||
.filter(|x| !x.is_empty())
|
.filter(|x| !x.is_empty())
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
.as_slice(),
|
.as_slice(),
|
||||||
) {
|
)
|
||||||
Ok(cli) => cli,
|
.early_exit();
|
||||||
Err(EarlyExit { output, status }) => match status {
|
|
||||||
Ok(_) => {
|
|
||||||
eprintln!("{}", output);
|
|
||||||
exit(0)
|
|
||||||
}
|
|
||||||
Err(_) => return Err(log_err!(output)),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
match &mut cli.command {
|
match &mut cli.command {
|
||||||
CpioCommands::Test(Test {}) => exit(cpio.test()),
|
CpioCommands::Test(Test {}) => exit(cpio.test()),
|
||||||
CpioCommands::Restore(Restore {}) => cpio.restore()?,
|
CpioCommands::Restore(Restore {}) => cpio.restore()?,
|
||||||
@ -590,7 +580,7 @@ pub fn cpio_commands(argc: i32, argv: *const *const c_char) -> bool {
|
|||||||
cpio.ls(path.as_str(), *recursive);
|
cpio.ls(path.as_str(), *recursive);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
cpio.dump(file)?;
|
cpio.dump(file)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -177,9 +177,8 @@ int main(int argc, char *argv[]) {
|
|||||||
compress(action[8] == '=' ? &action[9] : "gzip", argv[2], argv[3]);
|
compress(action[8] == '=' ? &action[9] : "gzip", argv[2], argv[3]);
|
||||||
} else if (argc > 4 && action == "hexpatch") {
|
} else if (argc > 4 && action == "hexpatch") {
|
||||||
return hexpatch(byte_view(argv[2]), byte_view(argv[3]), byte_view(argv[4])) ? 0 : 1;
|
return hexpatch(byte_view(argv[2]), byte_view(argv[3]), byte_view(argv[4])) ? 0 : 1;
|
||||||
} else if (argc > 2 && action == "cpio"sv) {
|
} else if (argc > 2 && action == "cpio") {
|
||||||
if (!rust::cpio_commands(argc - 2, argv + 2))
|
return rust::cpio_commands(argc - 2, argv + 2) ? 0 : 1;
|
||||||
usage(argv[0]);
|
|
||||||
} else if (argc > 3 && action == "dtb") {
|
} else if (argc > 3 && action == "dtb") {
|
||||||
if (dtb_commands(argc - 2, argv + 2))
|
if (dtb_commands(argc - 2, argv + 2))
|
||||||
usage(argv[0]);
|
usage(argv[0]);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user