From dda8cc85c967e4cdb1ca935fcfe97fe6cf870a19 Mon Sep 17 00:00:00 2001 From: topjohnwu Date: Thu, 14 Sep 2023 13:10:09 -0700 Subject: [PATCH] Use bytemuck --- native/src/Cargo.lock | 22 +++++++++++++++++++ native/src/Cargo.toml | 1 + native/src/base/Cargo.toml | 1 + native/src/base/files.rs | 9 ++++---- native/src/base/misc.rs | 30 +------------------------ native/src/core/Cargo.toml | 1 + native/src/core/cert.rs | 33 +++++++++++++++------------- native/src/core/logging.rs | 14 ++++++------ native/src/core/resetprop/persist.rs | 1 + 9 files changed, 57 insertions(+), 55 deletions(-) diff --git a/native/src/Cargo.lock b/native/src/Cargo.lock index c52dad264..23998ee5d 100644 --- a/native/src/Cargo.lock +++ b/native/src/Cargo.lock @@ -70,6 +70,7 @@ name = "base" version = "0.0.0" dependencies = [ "argh", + "bytemuck", "cfg-if", "cxx", "cxx-gen", @@ -104,6 +105,26 @@ dependencies = [ "generic-array", ] +[[package]] +name = "bytemuck" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "374d28ec25809ee0e23827c2ab573d729e293f281dfe393500e7ad618baa61c6" +dependencies = [ + "bytemuck_derive", +] + +[[package]] +name = "bytemuck_derive" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "965ab7eb5f8f97d2a083c799f3a1b994fc397b2fe2da5d1da1626ce15a39f2b1" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "byteorder" version = "1.4.3" @@ -420,6 +441,7 @@ name = "magisk" version = "0.0.0" dependencies = [ "base", + "bytemuck", "cxx", "cxx-gen", "num-derive", diff --git a/native/src/Cargo.toml b/native/src/Cargo.toml index de4be01dc..84f5322cd 100644 --- a/native/src/Cargo.toml +++ b/native/src/Cargo.toml @@ -21,6 +21,7 @@ p384 = "0.13" rsa = "0.9" x509-cert = "0.2" der = "0.7" +bytemuck = "1.14" [workspace.dependencies.argh] git = "https://github.com/topjohnwu/argh.git" diff --git a/native/src/base/Cargo.toml b/native/src/base/Cargo.toml index bfb8e57f8..67c124b7b 100644 --- a/native/src/base/Cargo.toml +++ b/native/src/base/Cargo.toml @@ -15,3 +15,4 @@ libc = { workspace = true } cfg-if = { workspace = true } thiserror = { workspace = true } argh = { workspace = true } +bytemuck = { workspace = true } diff --git a/native/src/base/files.rs b/native/src/base/files.rs index b9220d04f..7b1f44fda 100644 --- a/native/src/base/files.rs +++ b/native/src/base/files.rs @@ -10,12 +10,13 @@ use std::os::unix::fs::FileTypeExt; use std::os::unix::io::{AsRawFd, FromRawFd, OwnedFd, RawFd}; use std::{io, mem, ptr, slice}; +use bytemuck::{bytes_of_mut, Pod}; use libc::{ c_char, c_uint, dirent, mode_t, EEXIST, ENOENT, F_OK, O_CLOEXEC, O_PATH, O_RDONLY, O_RDWR, }; use crate::{ - copy_cstr, cstr, errno, error, FlatData, FsPath, FsPathBuf, LibcReturn, Utf8CStr, Utf8CStrArr, + copy_cstr, cstr, errno, error, FsPath, FsPathBuf, LibcReturn, Utf8CStr, Utf8CStrArr, Utf8CStrBuf, }; @@ -52,7 +53,7 @@ pub fn fd_path(fd: RawFd, buf: &mut dyn Utf8CStrBuf) -> io::Result<()> { pub trait ReadExt { fn skip(&mut self, len: usize) -> io::Result<()>; - fn read_flat_data(&mut self, data: &mut F) -> io::Result<()>; + fn read_pod(&mut self, data: &mut F) -> io::Result<()>; } impl ReadExt for T { @@ -67,8 +68,8 @@ impl ReadExt for T { Ok(()) } - fn read_flat_data(&mut self, data: &mut F) -> io::Result<()> { - self.read_exact(data.as_raw_bytes_mut()) + fn read_pod(&mut self, data: &mut F) -> io::Result<()> { + self.read_exact(bytes_of_mut(data)) } } diff --git a/native/src/base/misc.rs b/native/src/base/misc.rs index 1a39dd6ef..fd87e2d01 100644 --- a/native/src/base/misc.rs +++ b/native/src/base/misc.rs @@ -1,5 +1,5 @@ use std::process::exit; -use std::{io, mem, slice, str}; +use std::{io, slice, str}; use argh::EarlyExit; use libc::c_char; @@ -30,34 +30,6 @@ pub unsafe fn slice_from_ptr_mut<'a, T>(buf: *mut T, len: usize) -> &'a mut [T] } } -pub trait FlatData -where - Self: Sized, -{ - fn as_raw_bytes(&self) -> &[u8] { - unsafe { - let self_ptr = self as *const Self as *const u8; - slice::from_raw_parts(self_ptr, mem::size_of::()) - } - } - fn as_raw_bytes_mut(&mut self) -> &mut [u8] { - unsafe { - let self_ptr = self as *mut Self as *mut u8; - slice::from_raw_parts_mut(self_ptr, mem::size_of::()) - } - } - - fn bytes_size(&self) -> usize { - mem::size_of::() - } -} - -macro_rules! impl_flat_data { - ($($t:ty)*) => ($(impl FlatData for $t {})*) -} - -impl_flat_data!(usize u8 u16 u32 u64 isize i8 i16 i32 i64); - // Check libc return value and map to Result pub trait LibcReturn where diff --git a/native/src/core/Cargo.toml b/native/src/core/Cargo.toml index 15cfc1d3f..e112161b6 100644 --- a/native/src/core/Cargo.toml +++ b/native/src/core/Cargo.toml @@ -17,3 +17,4 @@ cxx = { workspace = true } num-traits = { workspace = true } num-derive = { workspace = true } quick-protobuf = { workspace = true } +bytemuck = { workspace = true, features = ["derive"] } diff --git a/native/src/core/cert.rs b/native/src/core/cert.rs index 409012886..57134a95b 100644 --- a/native/src/core/cert.rs +++ b/native/src/core/cert.rs @@ -1,6 +1,7 @@ use std::fs::File; use std::io; use std::io::{Cursor, Read, Seek, SeekFrom}; +use std::mem::size_of_val; use std::os::fd::{FromRawFd, RawFd}; use base::*; @@ -45,13 +46,13 @@ pub fn read_certificate(fd: RawFd, version: i32) -> Vec { // Find EOCD for i in 0u16.. { let mut comment_sz = 0u16; - apk.seek(SeekFrom::End(-(comment_sz.bytes_size() as i64) - i as i64))?; - apk.read_flat_data(&mut comment_sz)?; + apk.seek(SeekFrom::End(-(size_of_val(&comment_sz) as i64) - i as i64))?; + apk.read_pod(&mut comment_sz)?; if comment_sz == i { apk.seek(SeekFrom::Current(-22))?; let mut magic = 0u32; - apk.read_flat_data(&mut magic)?; + apk.read_pod(&mut magic)?; if magic == EOCD_MAGIC { break; } @@ -65,12 +66,12 @@ pub fn read_certificate(fd: RawFd, version: i32) -> Vec { // Seek and read central_dir_off to find the start of the central directory let mut central_dir_off = 0u32; apk.seek(SeekFrom::Current(12))?; - apk.read_flat_data(&mut central_dir_off)?; + apk.read_pod(&mut central_dir_off)?; // Code for parse APK comment to get version code if version >= 0 { let mut comment_sz = 0u16; - apk.read_flat_data(&mut comment_sz)?; + apk.read_pod(&mut comment_sz)?; let mut comment = vec![0u8; comment_sz as usize]; apk.read_exact(&mut comment)?; let mut comment = Cursor::new(&comment); @@ -90,7 +91,7 @@ pub fn read_certificate(fd: RawFd, version: i32) -> Vec { // Next, find the start of the APK signing block apk.seek(SeekFrom::Start((central_dir_off - 24) as u64))?; - apk.read_flat_data(&mut u64_val)?; // u64_value = block_sz_ + apk.read_pod(&mut u64_val)?; // u64_value = block_sz_ let mut magic = [0u8; 16]; apk.read_exact(&mut magic)?; if magic != APK_SIGNING_BLOCK_MAGIC { @@ -98,38 +99,40 @@ pub fn read_certificate(fd: RawFd, version: i32) -> Vec { } let mut signing_blk_sz = 0u64; apk.seek(SeekFrom::Current( - -(u64_val as i64) - (signing_blk_sz.bytes_size() as i64), + -(u64_val as i64) - (size_of_val(&signing_blk_sz) as i64), ))?; - apk.read_flat_data(&mut signing_blk_sz)?; + apk.read_pod(&mut signing_blk_sz)?; if signing_blk_sz != u64_val { return Err(bad_apk!("invalid signing block size")); } // Finally, we are now at the beginning of the id-value pair sequence loop { - apk.read_flat_data(&mut u64_val)?; // id-value pair length + apk.read_pod(&mut u64_val)?; // id-value pair length if u64_val == signing_blk_sz { break; } let mut id = 0u32; - apk.read_flat_data(&mut id)?; + apk.read_pod(&mut id)?; if id == SIGNATURE_SCHEME_V2_MAGIC { // Skip [signer sequence length] + [1st signer length] + [signed data length] - apk.seek(SeekFrom::Current((u32_val.bytes_size() * 3) as i64))?; + apk.seek(SeekFrom::Current((size_of_val(&u32_val) * 3) as i64))?; - apk.read_flat_data(&mut u32_val)?; // digest sequence length + apk.read_pod(&mut u32_val)?; // digest sequence length apk.seek(SeekFrom::Current(u32_val as i64))?; // skip all digests - apk.seek(SeekFrom::Current(u32_val.bytes_size() as i64))?; // cert sequence length - apk.read_flat_data(&mut u32_val)?; // 1st cert length + apk.seek(SeekFrom::Current(size_of_val(&u32_val) as i64))?; // cert sequence length + apk.read_pod(&mut u32_val)?; // 1st cert length let mut cert = vec![0; u32_val as usize]; apk.read_exact(cert.as_mut())?; return Ok(cert); } else { // Skip this id-value pair - apk.seek(SeekFrom::Current(u64_val as i64 - (id.bytes_size() as i64)))?; + apk.seek(SeekFrom::Current( + u64_val as i64 - (size_of_val(&id) as i64), + ))?; } } diff --git a/native/src/core/logging.rs b/native/src/core/logging.rs index 045b642f8..c09cfffe2 100644 --- a/native/src/core/logging.rs +++ b/native/src/core/logging.rs @@ -7,6 +7,7 @@ use std::os::fd::{AsRawFd, FromRawFd, RawFd}; use std::ptr::null_mut; use std::{fs, io}; +use bytemuck::{bytes_of, bytes_of_mut, write_zeroes, Pod, Zeroable}; use num_derive::{FromPrimitive, ToPrimitive}; use num_traits::FromPrimitive; @@ -110,7 +111,7 @@ pub fn zygisk_logging() { } } -#[derive(Default)] +#[derive(Copy, Clone, Pod, Zeroable)] #[repr(C)] struct LogMeta { prio: i32, @@ -133,7 +134,7 @@ fn write_log_to_pipe(logd: &mut File, prio: i32, msg: &Utf8CStr) -> io::Result { } } -impl FlatData for LogMeta {} - extern "C" fn logfile_writer(arg: *mut c_void) -> *mut c_void { fn writer_loop(pipefd: RawFd) -> io::Result<()> { let mut pipe = unsafe { File::from_raw_fd(pipefd) }; let mut tmp = Vec::new(); let mut logfile: LogFile = Buffer(&mut tmp); - let mut meta = LogMeta::default(); + let mut meta = LogMeta::zeroed(); let mut msg_buf = [0u8; MAX_MSG_LEN]; let mut aux = Utf8CStrArr::<64>::new(); loop { // Read request - pipe.read_exact(meta.as_raw_bytes_mut())?; + write_zeroes(&mut meta); + pipe.read_exact(bytes_of_mut(&mut meta))?; if meta.prio < 0 { if matches!(logfile, LogFile::Buffer(_)) { @@ -369,6 +369,6 @@ impl MagiskD { tid: 0, }; - logd.write_all(meta.as_raw_bytes()).ok(); + logd.write_all(bytes_of(&meta)).ok(); } } diff --git a/native/src/core/resetprop/persist.rs b/native/src/core/resetprop/persist.rs index 27cc7079d..0b90fa865 100644 --- a/native/src/core/resetprop/persist.rs +++ b/native/src/core/resetprop/persist.rs @@ -216,6 +216,7 @@ pub unsafe fn persist_delete_prop(name: *const c_char) -> bool { } inner(name).is_ok() } + pub unsafe fn persist_set_prop(name: *const c_char, value: *const c_char) -> bool { unsafe fn inner(name: *const c_char, value: *const c_char) -> LoggedResult<()> { let name = Utf8CStr::from_ptr(name)?;