Fix compile errors and cleanup

This commit is contained in:
topjohnwu 2023-06-10 17:11:02 -07:00 committed by John Wu
parent e58f98e844
commit 6b21091fe2
10 changed files with 66 additions and 57 deletions

View File

@ -1,8 +1,8 @@
#pragma once #pragma once
#include "../missing.hpp"
#include "../xwrap.hpp" #include "../xwrap.hpp"
#include "../files.hpp" #include "../files.hpp"
#include "../misc.hpp" #include "../misc.hpp"
#include "../logging.hpp" #include "../logging.hpp"
#include "../missing.hpp"
#include "../base-rs.hpp" #include "../base-rs.hpp"

View File

@ -179,10 +179,8 @@ struct byte_data : public byte_view {
byte_data() = default; byte_data() = default;
byte_data(void *buf, size_t sz) : byte_view(buf, sz) {} byte_data(void *buf, size_t sz) : byte_view(buf, sz) {}
// We don't want mutable references to be copied or moved around; pass bytes as byte_view // byte_data, or any of its subclass, can be copied as byte_data
// Subclasses are free to implement their own constructors byte_data(const byte_data &o) : byte_data(o._buf, o._sz) {}
byte_data(const byte_data &) = delete;
byte_data(byte_data &&) = delete;
// Transparent conversion from common C++ types to mutable byte references // Transparent conversion from common C++ types to mutable byte references
byte_data(std::string &s, bool with_nul = true) byte_data(std::string &s, bool with_nul = true)
@ -194,9 +192,7 @@ struct byte_data : public byte_view {
operator rust::Slice<uint8_t>() { return rust::Slice<uint8_t>(_buf, _sz); } operator rust::Slice<uint8_t>() { return rust::Slice<uint8_t>(_buf, _sz); }
using byte_view::buf; using byte_view::buf;
using byte_view::sz;
uint8_t *buf() { return _buf; } uint8_t *buf() { return _buf; }
size_t &sz() { return _sz; }
void swap(byte_data &o); void swap(byte_data &o);
std::vector<size_t> patch(byte_view from, byte_view to); std::vector<size_t> patch(byte_view from, byte_view to);

View File

@ -10,7 +10,7 @@ static inline int fexecve(int fd, char* const* argv, char* const* envp) {
syscall(__NR_execveat, fd, "", argv, envp, AT_EMPTY_PATH); syscall(__NR_execveat, fd, "", argv, envp, AT_EMPTY_PATH);
if (errno == ENOSYS) { if (errno == ENOSYS) {
char buf[256]; char buf[256];
std::snprintf(buf, sizeof(buf), "/proc/self/fd/%d", fd); ssprintf(buf, sizeof(buf), "/proc/self/fd/%d", fd);
execve(buf, argv, envp); execve(buf, argv, envp);
} }
return -1; return -1;

View File

@ -132,7 +132,7 @@ void chunk_out_stream::finalize() {
} }
ssize_t byte_channel::read(void *buf, size_t len) { ssize_t byte_channel::read(void *buf, size_t len) {
len = std::min((size_t) len, _data.sz() - _pos); len = std::min((size_t) len, _data._sz- _pos);
memcpy(buf, _data.buf() + _pos, len); memcpy(buf, _data.buf() + _pos, len);
_pos += len; _pos += len;
return len; return len;
@ -142,7 +142,7 @@ bool byte_channel::write(const void *buf, size_t len) {
resize(_pos + len); resize(_pos + len);
memcpy(_data.buf() + _pos, buf, len); memcpy(_data.buf() + _pos, buf, len);
_pos += len; _pos += len;
_data.sz() = std::max(_data.sz(), _pos); _data._sz= std::max(_data.sz(), _pos);
return true; return true;
} }
@ -153,7 +153,7 @@ off_t byte_channel::seek(off_t off, int whence) {
np = _pos + off; np = _pos + off;
break; break;
case SEEK_END: case SEEK_END:
np = _data.sz() + off; np = _data._sz+ off;
break; break;
case SEEK_SET: case SEEK_SET:
np = off; np = off;

View File

@ -1,13 +1,3 @@
use crate::ramdisk::MagiskCpio;
use anyhow::{anyhow, Context};
use base::libc::{
c_char, dev_t, gid_t, major, makedev, minor, mknod, mmap, mode_t, munmap, uid_t, MAP_FAILED,
MAP_PRIVATE, PROT_READ, S_IFBLK, S_IFCHR, S_IFDIR, S_IFLNK, S_IFMT, S_IFREG, S_IRGRP, S_IROTH,
S_IRUSR, S_IWGRP, S_IWOTH, S_IWUSR, S_IXGRP, S_IXOTH, S_IXUSR,
};
use base::{ptr_to_str_result, ResultExt, WriteExt};
use clap::{Parser, Subcommand};
use size::{Base, Size, Style};
use std::collections::BTreeMap; use std::collections::BTreeMap;
use std::ffi::CStr; use std::ffi::CStr;
use std::fmt::{Display, Formatter}; use std::fmt::{Display, Formatter};
@ -19,6 +9,19 @@ 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 anyhow::{anyhow, Context};
use clap::{Parser, Subcommand};
use size::{Base, Size, Style};
use base::libc::{
c_char, dev_t, gid_t, major, makedev, minor, mknod, mmap, mode_t, munmap, uid_t, MAP_FAILED,
MAP_PRIVATE, PROT_READ, S_IFBLK, S_IFCHR, S_IFDIR, S_IFLNK, S_IFMT, S_IFREG, S_IRGRP, S_IROTH,
S_IRUSR, S_IWGRP, S_IWOTH, S_IWUSR, S_IXGRP, S_IXOTH, S_IXUSR,
};
use base::{ptr_to_str_result, ResultExt, WriteExt};
use crate::ramdisk::MagiskCpio;
#[derive(Parser)] #[derive(Parser)]
struct CpioCli { struct CpioCli {
#[command(subcommand)] #[command(subcommand)]
@ -108,6 +111,7 @@ impl Cpio {
entries: BTreeMap::new(), entries: BTreeMap::new(),
} }
} }
fn load_from_data(data: &[u8]) -> anyhow::Result<Self> { fn load_from_data(data: &[u8]) -> anyhow::Result<Self> {
let mut cpio = Cpio::new(); let mut cpio = Cpio::new();
let mut pos = 0usize; let mut pos = 0usize;
@ -147,6 +151,7 @@ impl Cpio {
} }
Ok(cpio) Ok(cpio)
} }
pub(crate) fn load_from_file(path: &str) -> anyhow::Result<Self> { pub(crate) fn load_from_file(path: &str) -> anyhow::Result<Self> {
eprintln!("Loading cpio: [{}]", path); eprintln!("Loading cpio: [{}]", path);
let file = File::open(path)?; let file = File::open(path)?;
@ -173,6 +178,7 @@ impl Cpio {
} }
Ok(cpio) Ok(cpio)
} }
fn dump(&self, path: &str) -> anyhow::Result<()> { fn dump(&self, path: &str) -> anyhow::Result<()> {
eprintln!("Dumping cpio: [{}]", path); eprintln!("Dumping cpio: [{}]", path);
let mut file = File::create(path)?; let mut file = File::create(path)?;
@ -215,6 +221,7 @@ impl Cpio {
file.write_zeros(align_4(pos) - pos)?; file.write_zeros(align_4(pos) - pos)?;
Ok(()) Ok(())
} }
pub(crate) fn rm(&mut self, path: &str, recursive: bool) -> anyhow::Result<()> { pub(crate) fn rm(&mut self, path: &str, recursive: bool) -> anyhow::Result<()> {
let path = norm_path(path); let path = norm_path(path);
let entry = self let entry = self
@ -242,6 +249,7 @@ impl Cpio {
} }
Ok(()) Ok(())
} }
fn extract_entry(&self, path: &str, out: &Path) -> anyhow::Result<()> { fn extract_entry(&self, path: &str, out: &Path) -> anyhow::Result<()> {
let entry = self.entries.get(path).ok_or(anyhow!("No such file"))?; let entry = self.entries.get(path).ok_or(anyhow!("No such file"))?;
eprintln!("Extracting entry [{}] to [{}]", path, out.to_string_lossy()); eprintln!("Extracting entry [{}] to [{}]", path, out.to_string_lossy());
@ -280,6 +288,7 @@ impl Cpio {
} }
Ok(()) Ok(())
} }
fn extract(&self, path: Option<&str>, out: Option<&str>) -> anyhow::Result<()> { fn extract(&self, path: Option<&str>, out: Option<&str>) -> anyhow::Result<()> {
let path = path.map(norm_path); let path = path.map(norm_path);
let out = out.map(Path::new); let out = out.map(Path::new);
@ -295,9 +304,11 @@ impl Cpio {
} }
Ok(()) Ok(())
} }
pub(crate) fn exists(&self, path: &str) -> bool { pub(crate) fn exists(&self, path: &str) -> bool {
self.entries.contains_key(&norm_path(path)) self.entries.contains_key(&norm_path(path))
} }
fn add(&mut self, mode: &mode_t, path: &str, file: &str) -> anyhow::Result<()> { fn add(&mut self, mode: &mode_t, path: &str, file: &str) -> anyhow::Result<()> {
if path.ends_with('/') { if path.ends_with('/') {
return Err(anyhow!("path cannot end with / for add")); return Err(anyhow!("path cannot end with / for add"));
@ -334,6 +345,7 @@ impl Cpio {
eprintln!("Add file [{}] ({:04o})", path, mode); eprintln!("Add file [{}] ({:04o})", path, mode);
Ok(()) Ok(())
} }
fn mkdir(&mut self, mode: &mode_t, dir: &str) { fn mkdir(&mut self, mode: &mode_t, dir: &str) {
self.entries.insert( self.entries.insert(
norm_path(dir), norm_path(dir),
@ -348,6 +360,7 @@ impl Cpio {
); );
eprintln!("Create directory [{}] ({:04o})", dir, mode); eprintln!("Create directory [{}] ({:04o})", dir, mode);
} }
fn ln(&mut self, src: &str, dst: &str) { fn ln(&mut self, src: &str, dst: &str) {
self.entries.insert( self.entries.insert(
norm_path(dst), norm_path(dst),
@ -362,6 +375,7 @@ impl Cpio {
); );
eprintln!("Create symlink [{}] -> [{}]", dst, src); eprintln!("Create symlink [{}] -> [{}]", dst, src);
} }
fn mv(&mut self, from: &str, to: &str) -> anyhow::Result<()> { fn mv(&mut self, from: &str, to: &str) -> anyhow::Result<()> {
let entry = self let entry = self
.entries .entries
@ -371,6 +385,7 @@ impl Cpio {
eprintln!("Move [{}] -> [{}]", from, to); eprintln!("Move [{}] -> [{}]", from, to);
Ok(()) Ok(())
} }
fn ls(&self, path: Option<&str>, recursive: bool) { fn ls(&self, path: Option<&str>, recursive: bool) {
let path = path let path = path
.map(norm_path) .map(norm_path)
@ -489,10 +504,7 @@ pub fn cpio_commands(argc: i32, argv: *const *const c_char) -> bool {
.is_ok() .is_ok()
} }
fn x8u<U>(x: &[u8; 8]) -> anyhow::Result<U> fn x8u<U: TryFrom<u32>>(x: &[u8; 8]) -> anyhow::Result<U> {
where
U: TryFrom<u32>,
{
// parse hex // parse hex
let mut ret = 0u32; let mut ret = 0u32;
for i in x { for i in x {

View File

@ -151,7 +151,7 @@ static bool dtb_patch(const char *file) {
int len; int len;
char *value = (char *) fdt_getprop(fdt, node, "fsmgr_flags", &len); char *value = (char *) fdt_getprop(fdt, node, "fsmgr_flags", &len);
byte_data data(value, len); byte_data data(value, len);
patched |= patch_verity(data); patched |= (patch_verity(data) != len);
} }
} }
} }
@ -224,9 +224,10 @@ static bool fdt_patch(void *fdt) {
int len; int len;
const void *value = fdt_getprop(fdt, node, "fsmgr_flags", &len); const void *value = fdt_getprop(fdt, node, "fsmgr_flags", &len);
heap_data copy = byte_view(value, len).clone(); heap_data copy = byte_view(value, len).clone();
if (patch_verity(copy)) { auto patched_sz = patch_verity(copy);
if (patched_sz != len) {
modified = true; modified = true;
fdt_setprop(fdt, node, "fsmgr_flags", copy.buf(), copy.sz()); fdt_setprop(fdt, node, "fsmgr_flags", copy.buf(), patched_sz);
} }
if (name == "system"sv) { if (name == "system"sv) {
fprintf(stderr, "Setting [mnt_point] to [/system_root]\n"); fprintf(stderr, "Setting [mnt_point] to [/system_root]\n");

View File

@ -20,8 +20,8 @@ pub mod ffi {
include!("compress.hpp"); include!("compress.hpp");
include!("magiskboot.hpp"); include!("magiskboot.hpp");
fn decompress(buf: &[u8], fd: i32) -> bool; fn decompress(buf: &[u8], fd: i32) -> bool;
fn patch_encryption(buf: &mut [u8]); fn patch_encryption(buf: &mut [u8]) -> usize;
fn patch_verity(buf: &mut [u8]); fn patch_verity(buf: &mut [u8]) -> usize;
} }
#[namespace = "rust"] #[namespace = "rust"]

View File

@ -18,15 +18,12 @@ int unpack(const char *image, bool skip_decomp = false, bool hdr = false);
void repack(const char *src_img, const char *out_img, bool skip_comp = false); void repack(const char *src_img, const char *out_img, bool skip_comp = false);
int split_image_dtb(const char *filename); int split_image_dtb(const char *filename);
int hexpatch(const char *file, std::string_view from, std::string_view to); int hexpatch(const char *file, std::string_view from, std::string_view to);
int cpio_commands(int argc, char *argv[]);
int dtb_commands(int argc, char *argv[]); int dtb_commands(int argc, char *argv[]);
bool patch_verity(byte_data data); size_t patch_verity(rust::Slice<uint8_t> data);
void patch_verity(rust::Slice<uint8_t> data); size_t patch_encryption(rust::Slice<uint8_t> data);
bool patch_encryption(byte_data data);
void patch_encryption(rust::Slice<uint8_t> data);
inline bool check_env(const char *name) { static inline bool check_env(const char *name) {
using namespace std::string_view_literals; using namespace std::string_view_literals;
const char *val = getenv(name); const char *val = getenv(name);
return val != nullptr && val == "true"sv; return val != nullptr && val == "true"sv;

View File

@ -39,36 +39,28 @@ static int skip_encryption_pattern(const char *s) {
return skip; return skip;
} }
static bool remove_pattern(byte_data &data, int(*pattern_skip)(const char *)) { static size_t remove_pattern(byte_data data, int(*pattern_skip)(const char *)) {
char *src = reinterpret_cast<char *>(data.buf()); char *src = reinterpret_cast<char *>(data.buf());
size_t orig_sz = data.sz(); size_t sz = data.sz();
int write = 0; int write = 0;
int read = 0; int read = 0;
while (read < orig_sz) { while (read < data.sz()) {
if (int skip = pattern_skip(src + read); skip > 0) { if (int skip = pattern_skip(src + read); skip > 0) {
fprintf(stderr, "Remove pattern [%.*s]\n", skip, src + read); fprintf(stderr, "Remove pattern [%.*s]\n", skip, src + read);
data.sz() -= skip; sz -= skip;
read += skip; read += skip;
} else { } else {
src[write++] = src[read++]; src[write++] = src[read++];
} }
} }
memset(src + write, 0, orig_sz - write); memset(src + write, 0, data.sz() - write);
return data.sz() != orig_sz; return sz;
} }
bool patch_verity(byte_data data) { size_t patch_verity(rust::Slice<uint8_t> data) {
return remove_pattern(data, skip_verity_pattern); return remove_pattern(data, skip_verity_pattern);
} }
void patch_verity(rust::Slice<uint8_t> data) { size_t patch_encryption(rust::Slice<uint8_t> data) {
patch_verity(byte_data{data.data(), data.size()});
}
bool patch_encryption(byte_data data) {
return remove_pattern(data, skip_encryption_pattern); return remove_pattern(data, skip_encryption_pattern);
} }
void patch_encryption(rust::Slice<uint8_t> data) {
patch_encryption(byte_data{data.data(), data.size()});
}

View File

@ -1,11 +1,13 @@
use crate::cpio::{Cpio, CpioEntry};
use crate::ffi::{patch_encryption, patch_verity};
use base::libc::{S_IFDIR, S_IFMT, S_IFREG};
use std::cmp::Ordering; use std::cmp::Ordering;
use std::collections::HashMap; use std::collections::HashMap;
use std::env; use std::env;
use std::str::from_utf8; use std::str::from_utf8;
use base::libc::{S_IFDIR, S_IFMT, S_IFREG};
use crate::cpio::{Cpio, CpioEntry};
use crate::ffi::{patch_encryption, patch_verity};
pub trait MagiskCpio { pub trait MagiskCpio {
fn patch(&mut self); fn patch(&mut self);
fn test(&self) -> i32; fn test(&self) -> i32;
@ -40,17 +42,24 @@ impl MagiskCpio for Cpio {
if !keep_verity { if !keep_verity {
if fstab { if fstab {
eprintln!("Found fstab file [{}]", name); eprintln!("Found fstab file [{}]", name);
patch_verity(entry.data.as_mut_slice()); let len = patch_verity(entry.data.as_mut_slice());
if len != entry.data.len() {
entry.data.resize(len, 0);
}
} else if name == "verity_key" { } else if name == "verity_key" {
return false; return false;
} }
} }
if !keep_force_encrypt && fstab { if !keep_force_encrypt && fstab {
patch_encryption(entry.data.as_mut_slice()); let len = patch_encryption(entry.data.as_mut_slice());
if len != entry.data.len() {
entry.data.resize(len, 0);
}
} }
true true
}); });
} }
fn test(&self) -> i32 { fn test(&self) -> i32 {
let mut ret = 0; let mut ret = 0;
for file in [ for file in [
@ -78,6 +87,7 @@ impl MagiskCpio for Cpio {
} }
ret ret
} }
fn restore(&mut self) -> anyhow::Result<()> { fn restore(&mut self) -> anyhow::Result<()> {
let mut backups = HashMap::<String, CpioEntry>::new(); let mut backups = HashMap::<String, CpioEntry>::new();
let mut rm_list = String::new(); let mut rm_list = String::new();
@ -106,6 +116,7 @@ impl MagiskCpio for Cpio {
Ok(()) Ok(())
} }
fn backup(&mut self, origin: &str) -> anyhow::Result<()> { fn backup(&mut self, origin: &str) -> anyhow::Result<()> {
let mut backups = HashMap::<String, CpioEntry>::new(); let mut backups = HashMap::<String, CpioEntry>::new();
let mut rm_list = String::new(); let mut rm_list = String::new();