diff --git a/native/src/base/cstr.rs b/native/src/base/cstr.rs index 36f79eb6f..c30295b17 100644 --- a/native/src/base/cstr.rs +++ b/native/src/base/cstr.rs @@ -11,8 +11,7 @@ use std::str::Utf8Error; use std::{fmt, mem, slice, str}; use thiserror::Error; -use crate::slice_from_ptr_mut; - +use crate::{FsPath, FsPathMnt, slice_from_ptr_mut}; // Utf8CStr types are UTF-8 validated and null terminated strings. // // Several Utf8CStr types: @@ -415,32 +414,6 @@ const_assert_eq!(align_of::<&Utf8CStr>(), align_of::<[usize; 2]>()); // File system path extensions types -#[repr(transparent)] -pub struct FsPath(Utf8CStr); - -impl FsPath { - #[inline(always)] - pub fn from + ?Sized>(value: &T) -> &FsPath { - unsafe { mem::transmute(value.as_ref()) } - } - - #[inline(always)] - pub const fn __from_utfcstr(value: &Utf8CStr) -> &FsPath { - unsafe { mem::transmute(value) } - } - - pub fn follow_link(&self) -> &FsPathFollow { - unsafe { mem::transmute(self) } - } -} - -impl AsUtf8CStr for FsPath { - #[inline(always)] - fn as_utf8_cstr(&self) -> &Utf8CStr { - &self.0 - } -} - #[repr(transparent)] pub struct FsPathFollow(Utf8CStr); @@ -502,11 +475,10 @@ impl FsPathBuf<'_, N> { } } -impl Deref for FsPathBuf<'_, N> { - type Target = FsPath; - - fn deref(&self) -> &FsPath { - FsPath::from(self.0.deref()) +impl AsUtf8CStr for FsPathBuf<'_, N> { + #[inline(always)] + fn as_utf8_cstr(&self) -> &Utf8CStr { + &self.0 } } @@ -525,11 +497,11 @@ macro_rules! impl_cstr_deref { } impl_cstr_deref!( - (FsPath,) - (FsPathFollow,) (Utf8CStrBufRef<'_>,) (Utf8CStrBufArr, const N: usize) (Utf8CString,) + (FsPathFollow,) + (FsPathBuf<'_, N>, const N: usize) ); // impl> BoilerPlate for T { ... } @@ -612,12 +584,11 @@ macro_rules! impl_cstr_misc { impl_cstr_misc!( (Utf8CStr,) - (FsPath,) - (FsPathFollow,) - (FsPathBuf<'_, N>, const N: usize) (Utf8CStrBufRef<'_>,) (Utf8CStrBufArr, const N: usize) (Utf8CString,) + (FsPathFollow,) + (FsPathBuf<'_, N>, const N: usize) ); fn copy_cstr_truncate(dest: &mut [u8], src: &[u8]) -> usize { @@ -703,6 +674,23 @@ impl_cstr_buf_write!( (Utf8CString,) ); +// impl> FsPath for T {} +// impl> FsPathMnt for T {} +macro_rules! impl_fs_path { + ($( ($t:ty, $($g:tt)*) )*) => {$( + impl<$($g)*> FsPath for $t {} + impl<$($g)*> FsPathMnt for $t {} + )*} +} + +impl_fs_path!( + (&Utf8CStr,) + (Utf8CStrBufRef<'_>,) + (Utf8CStrBufArr, const N: usize) + (Utf8CString,) + (FsPathBuf<'_, N>, const N: usize) +); + #[macro_export] macro_rules! cstr { ($str:expr) => {{ @@ -718,8 +706,3 @@ macro_rules! cstr { macro_rules! raw_cstr { ($str:expr) => {{ $crate::cstr!($str).as_ptr() }}; } - -#[macro_export] -macro_rules! path { - ($str:expr) => {{ $crate::FsPath::__from_utfcstr($crate::cstr!($str)) }}; -} diff --git a/native/src/base/cxx_extern.rs b/native/src/base/cxx_extern.rs index 92bbad720..14da77db8 100644 --- a/native/src/base/cxx_extern.rs +++ b/native/src/base/cxx_extern.rs @@ -23,11 +23,11 @@ pub(crate) fn fd_path_for_cxx(fd: RawFd, buf: &mut [u8]) -> isize { unsafe extern "C" fn canonical_path(path: *const c_char, buf: *mut u8, bufsz: usize) -> isize { unsafe { match Utf8CStr::from_ptr(path) { - Ok(p) => { + Ok(path) => { let mut buf = cstr_buf::wrap_ptr(buf, bufsz); - FsPath::from(p) - .realpath(&mut buf) - .map_or(-1, |_| buf.len() as isize) + path.realpath(&mut buf) + .log_cxx() + .map_or(-1_isize, |_| buf.len() as isize) } Err(_) => -1, } @@ -38,7 +38,7 @@ unsafe extern "C" fn canonical_path(path: *const c_char, buf: *mut u8, bufsz: us unsafe extern "C" fn mkdirs_for_cxx(path: *const c_char, mode: mode_t) -> i32 { unsafe { match Utf8CStr::from_ptr(path) { - Ok(p) => FsPath::from(p).mkdirs(mode).map_or(-1, |_| 0), + Ok(path) => path.mkdirs(mode).map_or(-1, |_| 0), Err(_) => -1, } } @@ -48,7 +48,7 @@ unsafe extern "C" fn mkdirs_for_cxx(path: *const c_char, mode: mode_t) -> i32 { unsafe extern "C" fn rm_rf_for_cxx(path: *const c_char) -> bool { unsafe { match Utf8CStr::from_ptr(path) { - Ok(p) => FsPath::from(p).remove_all().is_ok(), + Ok(path) => path.remove_all().is_ok(), Err(_) => false, } } @@ -114,8 +114,6 @@ unsafe extern "C" fn cp_afc_for_cxx(src: *const c_char, dest: *const c_char) -> unsafe { if let Ok(src) = Utf8CStr::from_ptr(src) { if let Ok(dest) = Utf8CStr::from_ptr(dest) { - let src = FsPath::from(src); - let dest = FsPath::from(dest); return src.copy_to(dest).log_cxx().is_ok(); } } @@ -128,8 +126,6 @@ unsafe extern "C" fn mv_path_for_cxx(src: *const c_char, dest: *const c_char) -> unsafe { if let Ok(src) = Utf8CStr::from_ptr(src) { if let Ok(dest) = Utf8CStr::from_ptr(dest) { - let src = FsPath::from(src); - let dest = FsPath::from(dest); return src.move_to(dest).log_cxx().is_ok(); } } @@ -142,8 +138,6 @@ unsafe extern "C" fn link_path_for_cxx(src: *const c_char, dest: *const c_char) unsafe { if let Ok(src) = Utf8CStr::from_ptr(src) { if let Ok(dest) = Utf8CStr::from_ptr(dest) { - let src = FsPath::from(src); - let dest = FsPath::from(dest); return src.link_to(dest).log_cxx().is_ok(); } } @@ -156,8 +150,6 @@ unsafe extern "C" fn clone_attr_for_cxx(src: *const c_char, dest: *const c_char) unsafe { if let Ok(src) = Utf8CStr::from_ptr(src) { if let Ok(dest) = Utf8CStr::from_ptr(dest) { - let src = FsPath::from(src); - let dest = FsPath::from(dest); return clone_attr(src, dest).log_cxx().is_ok(); } } diff --git a/native/src/base/dir.rs b/native/src/base/dir.rs index d2f8102b0..7de8a36b0 100644 --- a/native/src/base/dir.rs +++ b/native/src/base/dir.rs @@ -1,7 +1,7 @@ use crate::cxx_extern::readlinkat; use crate::{ - FileAttr, FsPathBuf, LibcReturn, OsError, OsResult, OsResultStatic, Utf8CStr, Utf8CStrBuf, - cstr_buf, errno, fd_path, fd_set_attr, + FileAttr, FsPath, FsPathBuf, LibcReturn, OsError, OsResult, OsResultStatic, Utf8CStr, + Utf8CStrBuf, cstr_buf, errno, fd_path, fd_set_attr, }; use libc::{EEXIST, O_CLOEXEC, O_CREAT, O_RDONLY, O_TRUNC, O_WRONLY, dirent, mode_t}; use std::fs::File; diff --git a/native/src/base/files.rs b/native/src/base/files.rs index 46c4584cb..0e033d264 100644 --- a/native/src/base/files.rs +++ b/native/src/base/files.rs @@ -1,6 +1,6 @@ use crate::{ - Directory, FsPath, FsPathBuf, FsPathFollow, LibcReturn, OsError, OsResult, OsResultStatic, - Utf8CStr, Utf8CStrBuf, cstr_buf, errno, error, + Directory, FsPathBuf, FsPathFollow, LibcReturn, OsError, OsResult, OsResultStatic, Utf8CStr, + Utf8CStrBuf, cstr_buf, errno, error, }; use bytemuck::{Pod, bytes_of, bytes_of_mut}; use libc::{ @@ -13,6 +13,7 @@ use std::cmp::min; use std::ffi::CStr; use std::fs::File; use std::io::{BufRead, BufReader, Read, Seek, SeekFrom, Write}; +use std::ops::Deref; use std::os::fd::{AsFd, BorrowedFd}; use std::os::unix::ffi::OsStrExt; use std::os::unix::io::{AsRawFd, FromRawFd, OwnedFd, RawFd}; @@ -193,23 +194,27 @@ impl FileAttr { const XATTR_NAME_SELINUX: &CStr = c"security.selinux"; -impl FsPath { - pub fn open(&self, flags: i32) -> OsResult { +pub trait FsPath: Deref { + fn follow_link(&self) -> &FsPathFollow { + unsafe { mem::transmute(self.deref()) } + } + + fn open(&self, flags: i32) -> OsResult { Ok(File::from(open_fd!(self, flags)?)) } - pub fn create(&self, flags: i32, mode: mode_t) -> OsResult { + fn create(&self, flags: i32, mode: mode_t) -> OsResult { Ok(File::from(open_fd!(self, O_CREAT | flags, mode)?)) } - pub fn exists(&self) -> bool { + fn exists(&self) -> bool { unsafe { let mut st: stat = mem::zeroed(); libc::lstat(self.as_ptr(), &mut st) == 0 } } - pub fn rename_to<'a>(&'a self, name: &'a FsPath) -> OsResult<'a, ()> { + fn rename_to<'a>(&'a self, name: &'a Utf8CStr) -> OsResult<'a, ()> { unsafe { libc::rename(self.as_ptr(), name.as_ptr()).check_os_err( "rename", @@ -219,11 +224,11 @@ impl FsPath { } } - pub fn remove(&self) -> OsResult<()> { + fn remove(&self) -> OsResult<()> { unsafe { libc::remove(self.as_ptr()).check_os_err("remove", Some(self), None) } } - pub fn remove_all(&self) -> OsResultStatic<()> { + fn remove_all(&self) -> OsResultStatic<()> { let attr = self.get_attr()?; if attr.is_dir() { let mut dir = Directory::try_from(open_fd!(self, O_RDONLY | O_CLOEXEC)?)?; @@ -233,7 +238,7 @@ impl FsPath { } #[allow(clippy::unnecessary_cast)] - pub fn read_link(&self, buf: &mut dyn Utf8CStrBuf) -> OsResult<()> { + fn read_link(&self, buf: &mut dyn Utf8CStrBuf) -> OsResult<()> { buf.clear(); unsafe { let r = libc::readlink(self.as_ptr(), buf.as_mut_ptr(), buf.capacity() - 1) @@ -244,7 +249,7 @@ impl FsPath { Ok(()) } - pub fn mkdir(&self, mode: mode_t) -> OsResult<()> { + fn mkdir(&self, mode: mode_t) -> OsResult<()> { unsafe { if libc::mkdir(self.as_ptr(), mode) < 0 { if *errno() == EEXIST { @@ -257,7 +262,7 @@ impl FsPath { Ok(()) } - pub fn mkdirs(&self, mode: mode_t) -> OsResultStatic<()> { + fn mkdirs(&self, mode: mode_t) -> OsResultStatic<()> { if self.is_empty() { return Ok(()); } @@ -282,7 +287,7 @@ impl FsPath { } // Inspired by https://android.googlesource.com/platform/bionic/+/master/libc/bionic/realpath.cpp - pub fn realpath(&self, buf: &mut dyn Utf8CStrBuf) -> OsResult<()> { + fn realpath(&self, buf: &mut dyn Utf8CStrBuf) -> OsResult<()> { let fd = open_fd!(self, O_PATH | O_CLOEXEC)?; let mut st1: libc::stat; let mut st2: libc::stat; @@ -306,7 +311,7 @@ impl FsPath { Ok(()) } - pub fn get_attr(&self) -> OsResult { + fn get_attr(&self) -> OsResult { let mut attr = FileAttr::new(); unsafe { libc::lstat(self.as_ptr(), &mut attr.st).check_os_err("lstat", Some(self), None)?; @@ -317,7 +322,7 @@ impl FsPath { Ok(attr) } - pub fn set_attr<'a>(&'a self, attr: &'a FileAttr) -> OsResult<'a, ()> { + fn set_attr<'a>(&'a self, attr: &'a FileAttr) -> OsResult<'a, ()> { unsafe { if !attr.is_symlink() { libc::chmod(self.as_ptr(), (attr.st.st_mode & 0o777).as_()).check_os_err( @@ -340,7 +345,7 @@ impl FsPath { Ok(()) } - pub fn get_secontext(&self, con: &mut dyn Utf8CStrBuf) -> OsResult<()> { + fn get_secontext(&self, con: &mut dyn Utf8CStrBuf) -> OsResult<()> { unsafe { let sz = libc::lgetxattr( self.as_ptr(), @@ -360,7 +365,7 @@ impl FsPath { Ok(()) } - pub fn set_secontext<'a>(&'a self, con: &'a Utf8CStr) -> OsResult<'a, ()> { + fn set_secontext<'a>(&'a self, con: &'a Utf8CStr) -> OsResult<'a, ()> { unsafe { libc::lsetxattr( self.as_ptr(), @@ -373,7 +378,7 @@ impl FsPath { } } - pub fn copy_to(&self, path: &FsPath) -> OsResultStatic<()> { + fn copy_to(&self, path: &Utf8CStr) -> OsResultStatic<()> { let attr = self.get_attr()?; if attr.is_dir() { path.mkdir(0o777)?; @@ -403,7 +408,7 @@ impl FsPath { Ok(()) } - pub fn move_to(&self, path: &FsPath) -> OsResultStatic<()> { + fn move_to(&self, path: &Utf8CStr) -> OsResultStatic<()> { if path.exists() { let attr = path.get_attr()?; if attr.is_dir() { @@ -418,7 +423,7 @@ impl FsPath { Ok(()) } - pub fn parent(&self, buf: &mut dyn Utf8CStrBuf) -> bool { + fn parent(&self, buf: &mut dyn Utf8CStrBuf) -> bool { buf.clear(); if let Some(parent) = Path::new(self.as_str()).parent() { let bytes = parent.as_os_str().as_bytes(); @@ -432,7 +437,7 @@ impl FsPath { } // ln self path - pub fn link_to(&self, path: &FsPath) -> OsResultStatic<()> { + fn link_to(&self, path: &Utf8CStr) -> OsResultStatic<()> { let attr = self.get_attr()?; if attr.is_dir() { path.mkdir(0o777)?; @@ -453,7 +458,7 @@ impl FsPath { } // ln -s target self - pub fn create_symlink_to<'a>(&'a self, target: &'a FsPath) -> OsResult<'a, ()> { + fn create_symlink_to<'a>(&'a self, target: &'a Utf8CStr) -> OsResult<'a, ()> { unsafe { libc::symlink(target.as_ptr(), self.as_ptr()).check_os_err( "symlink", @@ -463,17 +468,21 @@ impl FsPath { } } - pub fn mkfifo(&self, mode: mode_t) -> OsResult<()> { + fn mkfifo(&self, mode: mode_t) -> OsResult<()> { unsafe { libc::mkfifo(self.as_ptr(), mode).check_os_err("mkfifo", Some(self), None) } } } -impl FsPathFollow { - pub fn exists(&self) -> bool { +impl FsPath for FsPathFollow { + fn follow_link(&self) -> &FsPathFollow { + self + } + + fn exists(&self) -> bool { unsafe { libc::access(self.as_ptr(), F_OK) == 0 } } - pub fn get_attr(&self) -> OsResult { + fn get_attr(&self) -> OsResult { let mut attr = FileAttr::new(); unsafe { libc::stat(self.as_ptr(), &mut attr.st).check_os_err("stat", Some(self), None)?; @@ -484,7 +493,7 @@ impl FsPathFollow { Ok(attr) } - pub fn set_attr<'a>(&'a self, attr: &'a FileAttr) -> OsResult<'a, ()> { + fn set_attr<'a>(&'a self, attr: &'a FileAttr) -> OsResult<'a, ()> { unsafe { libc::chmod(self.as_ptr(), (attr.st.st_mode & 0o777).as_()).check_os_err( "chmod", @@ -505,7 +514,7 @@ impl FsPathFollow { Ok(()) } - pub fn get_secontext(&self, con: &mut dyn Utf8CStrBuf) -> OsResult<()> { + fn get_secontext(&self, con: &mut dyn Utf8CStrBuf) -> OsResult<()> { unsafe { let sz = libc::getxattr( self.as_ptr(), @@ -525,7 +534,7 @@ impl FsPathFollow { Ok(()) } - pub fn set_secontext<'a>(&'a self, con: &'a Utf8CStr) -> OsResult<'a, ()> { + fn set_secontext<'a>(&'a self, con: &'a Utf8CStr) -> OsResult<'a, ()> { unsafe { libc::setxattr( self.as_ptr(), @@ -595,8 +604,8 @@ pub fn fd_set_secontext(fd: RawFd, con: &Utf8CStr) -> OsResult<()> { } } -pub fn clone_attr<'a>(a: &'a FsPath, b: &'a FsPath) -> OsResult<'a, ()> { - let attr = a.get_attr()?; +pub fn clone_attr<'a>(a: &'a Utf8CStr, b: &'a Utf8CStr) -> OsResult<'a, ()> { + let attr = a.get_attr().map_err(|e| e.set_args(Some(a), None))?; b.set_attr(&attr).map_err(|e| e.set_args(Some(b), None)) } diff --git a/native/src/base/lib.rs b/native/src/base/lib.rs index e042e3d6f..b6fae92cf 100644 --- a/native/src/base/lib.rs +++ b/native/src/base/lib.rs @@ -13,6 +13,7 @@ pub use ffi::fork_dont_care; pub use files::*; pub use logging::*; pub use misc::*; +pub use mount::*; pub use result::*; mod cstr; diff --git a/native/src/base/mount.rs b/native/src/base/mount.rs index c35dd648b..e7ec789c0 100644 --- a/native/src/base/mount.rs +++ b/native/src/base/mount.rs @@ -1,9 +1,10 @@ -use crate::{FsPath, LibcReturn, OsResult, Utf8CStr}; +use crate::{LibcReturn, OsResult, Utf8CStr}; use libc::c_ulong; +use std::ops::Deref; use std::ptr; -impl FsPath { - pub fn bind_mount_to<'a>(&'a self, path: &'a FsPath) -> OsResult<'a, ()> { +pub trait FsPathMnt: Deref { + fn bind_mount_to<'a>(&'a self, path: &'a Utf8CStr) -> OsResult<'a, ()> { unsafe { libc::mount( self.as_ptr(), @@ -16,7 +17,7 @@ impl FsPath { } } - pub fn remount_with_flags(&self, flags: c_ulong) -> OsResult<()> { + fn remount_with_flags(&self, flags: c_ulong) -> OsResult<()> { unsafe { libc::mount( ptr::null(), @@ -29,7 +30,7 @@ impl FsPath { } } - pub fn remount_with_data(&self, data: &Utf8CStr) -> OsResult<()> { + fn remount_with_data(&self, data: &Utf8CStr) -> OsResult<()> { unsafe { libc::mount( ptr::null(), @@ -42,7 +43,7 @@ impl FsPath { } } - pub fn move_mount_to<'a>(&'a self, path: &'a FsPath) -> OsResult<'a, ()> { + fn move_mount_to<'a>(&'a self, path: &'a Utf8CStr) -> OsResult<'a, ()> { unsafe { libc::mount( self.as_ptr(), @@ -55,13 +56,13 @@ impl FsPath { } } - pub fn unmount(&self) -> OsResult<()> { + fn unmount(&self) -> OsResult<()> { unsafe { libc::umount2(self.as_ptr(), libc::MNT_DETACH).check_os_err("unmount", Some(self), None) } } - pub fn set_mount_private(&self, recursive: bool) -> OsResult<()> { + fn set_mount_private(&self, recursive: bool) -> OsResult<()> { let flag = if recursive { libc::MS_REC } else { 0 }; unsafe { libc::mount( diff --git a/native/src/base/xwrap.rs b/native/src/base/xwrap.rs index f38912b0f..f82b18d2a 100644 --- a/native/src/base/xwrap.rs +++ b/native/src/base/xwrap.rs @@ -29,10 +29,9 @@ fn ptr_to_str<'a>(ptr: *const c_char) -> Option<&'a str> { unsafe extern "C" fn xrealpath(path: *const c_char, buf: *mut u8, bufsz: usize) -> isize { unsafe { match Utf8CStr::from_ptr(path) { - Ok(p) => { + Ok(path) => { let mut buf = cstr_buf::wrap_ptr(buf, bufsz); - FsPath::from(p) - .realpath(&mut buf) + path.realpath(&mut buf) .log_cxx() .map_or(-1, |_| buf.len() as isize) } @@ -45,10 +44,9 @@ unsafe extern "C" fn xrealpath(path: *const c_char, buf: *mut u8, bufsz: usize) unsafe extern "C" fn xreadlink(path: *const c_char, buf: *mut u8, bufsz: usize) -> isize { unsafe { match Utf8CStr::from_ptr(path) { - Ok(p) => { + Ok(path) => { let mut buf = cstr_buf::wrap_ptr(buf, bufsz); - FsPath::from(p) - .read_link(&mut buf) + path.read_link(&mut buf) .log_cxx() .map_or(-1, |_| buf.len() as isize) } @@ -343,7 +341,7 @@ unsafe extern "C" fn xrename(oldname: *const c_char, newname: *const c_char) -> unsafe extern "C" fn xmkdir(path: *const c_char, mode: mode_t) -> i32 { unsafe { match Utf8CStr::from_ptr(path) { - Ok(p) => FsPath::from(p).mkdir(mode).log_cxx().map_or(-1, |_| 0), + Ok(path) => path.mkdir(mode).log_cxx().map_or(-1, |_| 0), Err(_) => -1, } } @@ -353,7 +351,7 @@ unsafe extern "C" fn xmkdir(path: *const c_char, mode: mode_t) -> i32 { unsafe extern "C" fn xmkdirs(path: *const c_char, mode: mode_t) -> i32 { unsafe { match Utf8CStr::from_ptr(path) { - Ok(p) => FsPath::from(p).mkdirs(mode).log_cxx().map_or(-1, |_| 0), + Ok(path) => path.mkdirs(mode).log_cxx().map_or(-1, |_| 0), Err(_) => -1, } } diff --git a/native/src/boot/cpio.rs b/native/src/boot/cpio.rs index 287a9bbc7..8e3a31157 100644 --- a/native/src/boot/cpio.rs +++ b/native/src/boot/cpio.rs @@ -342,13 +342,12 @@ impl Cpio { eprintln!("Extracting entry [{}] to [{}]", path, out); let out = Utf8CStr::from_string(out); - let out = FsPath::from(out); let mut buf = cstr_buf::default(); // Make sure its parent directories exist if out.parent(&mut buf) { - FsPath::from(&buf).mkdirs(0o755)?; + buf.mkdirs(0o755)?; } let mode: mode_t = (entry.mode & 0o777).into(); @@ -362,7 +361,7 @@ impl Cpio { S_IFLNK => { buf.clear(); buf.push_str(str::from_utf8(entry.data.as_slice())?); - out.create_symlink_to(FsPath::from(&buf))?; + out.create_symlink_to(&buf)?; } S_IFBLK | S_IFCHR => { let dev = makedev(entry.rdevmajor.try_into()?, entry.rdevminor.try_into()?); @@ -399,7 +398,6 @@ impl Cpio { return Err(log_err!("path cannot end with / for add")); } let file = Utf8CStr::from_string(file); - let file = FsPath::from(&file); let attr = file.get_attr()?; let mut content = Vec::::new(); @@ -765,7 +763,7 @@ pub fn cpio_commands(argc: i32, argv: *const *const c_char) -> bool { CpioCli::from_args(&["magiskboot", "cpio"], &cmds).on_early_exit(print_cpio_usage); let file = Utf8CStr::from_string(&mut cli.file); - let mut cpio = if FsPath::from(file).exists() { + let mut cpio = if file.exists() { Cpio::load_from_file(file)? } else { Cpio::new() diff --git a/native/src/core/daemon.rs b/native/src/core/daemon.rs index eddec0098..ace43bbae 100644 --- a/native/src/core/daemon.rs +++ b/native/src/core/daemon.rs @@ -11,8 +11,8 @@ use crate::package::ManagerInfo; use crate::su::SuInfo; use base::libc::{O_CLOEXEC, O_RDONLY}; use base::{ - AtomicArc, BufReadExt, FsPathBuf, ResultExt, Utf8CStr, cstr, cstr_buf, error, info, libc, - open_fd, path, + AtomicArc, BufReadExt, FsPath, FsPathBuf, ResultExt, Utf8CStr, cstr, cstr_buf, error, info, + libc, open_fd, }; use std::fs::File; use std::io::BufReader; @@ -106,7 +106,7 @@ impl MagiskD { self.preserve_stub_apk(); // Check secure dir - let secure_dir = path!(SECURE_DIR); + let secure_dir = cstr!(SECURE_DIR); if !secure_dir.exists() { if self.sdk_int < 24 { secure_dir.mkdir(0o700).log_ok(); @@ -173,7 +173,7 @@ impl MagiskD { self.set_db_setting(DbEntryKey::BootloopCount, 0).log_ok(); // At this point it's safe to create the folder - let secure_dir = path!(SECURE_DIR); + let secure_dir = cstr!(SECURE_DIR); if !secure_dir.exists() { secure_dir.mkdir(0o700).log_ok(); } @@ -245,7 +245,7 @@ pub fn daemon_entry() { } let mut sdk_int = -1; - if let Ok(file) = path!("/system/build.prop").open(O_RDONLY | O_CLOEXEC) { + if let Ok(file) = cstr!("/system/build.prop").open(O_RDONLY | O_CLOEXEC) { let mut file = BufReader::new(file); file.foreach_props(|key, val| { if key == "ro.build.version.sdk" { diff --git a/native/src/core/mount.rs b/native/src/core/mount.rs index 75ad73d50..389eacd4b 100644 --- a/native/src/core/mount.rs +++ b/native/src/core/mount.rs @@ -7,8 +7,8 @@ use num_traits::AsPrimitive; use base::libc::{c_uint, dev_t}; use base::{ - FsPath, FsPathBuf, LibcReturn, LoggedResult, MountInfo, ResultExt, Utf8CStr, cstr, cstr_buf, - debug, info, libc, parse_mount_info, path, warn, + FsPath, FsPathBuf, FsPathMnt, LibcReturn, LoggedResult, MountInfo, ResultExt, Utf8CStr, cstr, + cstr_buf, debug, info, libc, parse_mount_info, warn, }; use crate::consts::{MODULEMNT, MODULEROOT, PREINITDEV, PREINITMIRR, WORKERDIR}; @@ -44,7 +44,6 @@ pub fn setup_mounts() { let target = Utf8CStr::from_string(&mut target); let mut preinit_dir = resolve_preinit_dir(target); let preinit_dir = Utf8CStr::from_string(&mut preinit_dir); - let preinit_dir = FsPath::from(preinit_dir); let r: LoggedResult<()> = try { preinit_dir.mkdir(0o700)?; mnt_path.mkdirs(0o755)?; @@ -70,7 +69,7 @@ pub fn setup_mounts() { let module_mnt = FsPathBuf::default().join(magisk_tmp).join(MODULEMNT); let _: LoggedResult<()> = try { module_mnt.mkdir(0o755)?; - path!(MODULEROOT).bind_mount_to(&module_mnt)?; + cstr!(MODULEROOT).bind_mount_to(&module_mnt)?; module_mnt.remount_with_flags(libc::MS_RDONLY)?; }; } @@ -182,7 +181,7 @@ pub fn find_preinit_device() -> String { && !tmp.is_empty() { let mut mirror_dir = FsPathBuf::default().join(&tmp).join(PREINITMIRR); - let preinit_dir = FsPath::from(Utf8CStr::from_string(&mut preinit_dir)); + let preinit_dir = Utf8CStr::from_string(&mut preinit_dir); let _: LoggedResult<()> = try { preinit_dir.mkdirs(0o700)?; mirror_dir.mkdirs(0o755)?; diff --git a/native/src/core/package.rs b/native/src/core/package.rs index f75b3990a..0a330c73f 100644 --- a/native/src/core/package.rs +++ b/native/src/core/package.rs @@ -273,11 +273,10 @@ impl ManagerInfo { } fn check_stub(&mut self, user: i32, pkg: &str) -> Status { - let mut arr = cstr_buf::default(); - if find_apk_path(pkg, &mut arr).is_err() { + let mut apk = cstr_buf::default(); + if find_apk_path(pkg, &mut apk).is_err() { return Status::NotInstalled; } - let apk = FsPath::from(&arr); let cert = match apk.open(O_RDONLY | O_CLOEXEC) { Ok(mut fd) => read_certificate(&mut fd, -1), @@ -286,7 +285,7 @@ impl ManagerInfo { if cert.is_empty() || (pkg == self.repackaged_pkg && cert != self.repackaged_cert) { error!("pkg: repackaged APK signature invalid: {}", apk); - uninstall_pkg(apk); + uninstall_pkg(&apk); return Status::CertMismatch; } @@ -298,11 +297,10 @@ impl ManagerInfo { } fn check_orig(&mut self, user: i32) -> Status { - let mut arr = cstr_buf::default(); - if find_apk_path(APP_PACKAGE_NAME, &mut arr).is_err() { + let mut apk = cstr_buf::default(); + if find_apk_path(APP_PACKAGE_NAME, &mut apk).is_err() { return Status::NotInstalled; } - let apk = FsPath::from(&arr); let cert = match apk.open(O_RDONLY | O_CLOEXEC) { Ok(mut fd) => read_certificate(&mut fd, MAGISK_VER_CODE), diff --git a/native/src/core/resetprop/persist.rs b/native/src/core/resetprop/persist.rs index e617f50d5..ea348e25a 100644 --- a/native/src/core/resetprop/persist.rs +++ b/native/src/core/resetprop/persist.rs @@ -16,8 +16,8 @@ use crate::resetprop::proto::persistent_properties::{ use base::const_format::concatcp; use base::libc::{O_CLOEXEC, O_RDONLY}; use base::{ - Directory, FsPathBuf, LibcReturn, LoggedResult, MappedFile, SilentResultExt, Utf8CStr, - WalkResult, clone_attr, cstr, debug, libc::mkstemp, path, + Directory, FsPath, FsPathBuf, LibcReturn, LoggedResult, MappedFile, SilentResultExt, Utf8CStr, + WalkResult, clone_attr, cstr, debug, libc::mkstemp, }; const PERSIST_PROP_DIR: &str = "/data/property"; @@ -64,7 +64,7 @@ impl PropExt for PersistentProperties { } fn check_proto() -> bool { - path!(PERSIST_PROP).exists() + cstr!(PERSIST_PROP).exists() } fn file_get_prop(name: &Utf8CStr) -> LoggedResult { @@ -121,8 +121,8 @@ fn proto_write_props(props: &PersistentProperties) -> LoggedResult<()> { debug!("resetprop: encode with protobuf [{}]", tmp); props.write_message(&mut Writer::new(BufWriter::new(f)))?; } - clone_attr(path!(PERSIST_PROP), &tmp)?; - tmp.rename_to(path!(PERSIST_PROP))?; + clone_attr(cstr!(PERSIST_PROP), &tmp)?; + tmp.rename_to(cstr!(PERSIST_PROP))?; Ok(()) } diff --git a/native/src/init/getinfo.rs b/native/src/init/getinfo.rs index 37b967c39..6c114c6b3 100644 --- a/native/src/init/getinfo.rs +++ b/native/src/init/getinfo.rs @@ -1,5 +1,5 @@ use crate::ffi::{BootConfig, MagiskInit, backup_init}; -use base::{BytesExt, MappedFile, path}; +use base::{BytesExt, FsPath, MappedFile, cstr}; impl BootConfig { #[allow(unused_imports, unused_unsafe)] @@ -37,11 +37,11 @@ impl BootConfig { impl MagiskInit { pub(crate) fn check_two_stage(&self) -> bool { - path!("/first_stage_ramdisk").exists() || - path!("/second_stage_resources").exists() || - path!("/system/bin/init").exists() || + cstr!("/first_stage_ramdisk").exists() || + cstr!("/second_stage_resources").exists() || + cstr!("/system/bin/init").exists() || // Use the apex folder to determine whether 2SI (Android 10+) - path!("/apex").exists() || + cstr!("/apex").exists() || // If we still have no indication, parse the original init and see what's up MappedFile::open(backup_init()) .map(|data| data.contains(b"selinux_setup")) diff --git a/native/src/init/init.rs b/native/src/init/init.rs index 11fca4075..02033f4fc 100644 --- a/native/src/init/init.rs +++ b/native/src/init/init.rs @@ -6,9 +6,9 @@ use crate::{ logging::setup_klog, }; use base::{ - FsPath, LibcReturn, LoggedResult, ResultExt, info, + FsPath, FsPathMnt, LibcReturn, LoggedResult, ResultExt, cstr, info, libc::{basename, getpid, mount, umask}, - path, raw_cstr, + raw_cstr, }; use std::{ ffi::{CStr, c_char}, @@ -41,7 +41,7 @@ impl MagiskInit { info!("First Stage Init"); self.prepare_data(); - if !path!("/sdcard").exists() && !path!("/first_stage_ramdisk/sdcard").exists() { + if !cstr!("/sdcard").exists() && !cstr!("/first_stage_ramdisk/sdcard").exists() { self.hijack_init_with_switch_root(); self.restore_ramdisk_init(); } else { @@ -54,9 +54,9 @@ impl MagiskInit { fn second_stage(&mut self) { info!("Second Stage Init"); - path!("/init").unmount().ok(); - path!("/system/bin/init").unmount().ok(); // just in case - path!("/data/init").remove().ok(); + cstr!("/init").unmount().ok(); + cstr!("/system/bin/init").unmount().ok(); // just in case + cstr!("/data/init").remove().ok(); unsafe { // Make sure init dmesg logs won't get messed up @@ -66,10 +66,10 @@ impl MagiskInit { // Some weird devices like meizu, uses 2SI but still have legacy rootfs if is_rootfs() { // We are still on rootfs, so make sure we will execute the init of the 2nd stage - let init_path = path!("/init"); + let init_path = cstr!("/init"); init_path.remove().ok(); init_path - .create_symlink_to(path!("/system/bin/init")) + .create_symlink_to(cstr!("/system/bin/init")) .log_ok(); self.patch_rw_root(); } else { @@ -98,29 +98,29 @@ impl MagiskInit { fn recovery(&self) { info!("Ramdisk is recovery, abort"); self.restore_ramdisk_init(); - path!("/.backup").remove_all().ok(); + cstr!("/.backup").remove_all().ok(); } fn restore_ramdisk_init(&self) { - path!("/init").remove().ok(); + cstr!("/init").remove().ok(); - let orig_init = FsPath::from(backup_init()); + let orig_init = backup_init(); if orig_init.exists() { - orig_init.rename_to(path!("/init")).log_ok(); + orig_init.rename_to(cstr!("/init")).log_ok(); } else { // If the backup init is missing, this means that the boot ramdisk // was created from scratch, and the real init is in a separate CPIO, // which is guaranteed to be placed at /system/bin/init. - path!("/init") - .create_symlink_to(path!("/system/bin/init")) + cstr!("/init") + .create_symlink_to(cstr!("/system/bin/init")) .log_ok(); } } fn start(&mut self) -> LoggedResult<()> { - if !path!("/proc/cmdline").exists() { - path!("/proc").mkdir(0o755)?; + if !cstr!("/proc/cmdline").exists() { + cstr!("/proc").mkdir(0o755)?; unsafe { mount( raw_cstr!("proc"), @@ -133,8 +133,8 @@ impl MagiskInit { .check_io_err()?; self.mount_list.push("/proc".to_string()); } - if !path!("/sys/block").exists() { - path!("/sys").mkdir(0o755)?; + if !cstr!("/sys/block").exists() { + cstr!("/sys").mkdir(0o755)?; unsafe { mount( raw_cstr!("sysfs"), @@ -159,7 +159,7 @@ impl MagiskInit { self.legacy_system_as_root(); } else if self.config.force_normal_boot { self.first_stage(); - } else if path!("/sbin/recovery").exists() || path!("/system/bin/recovery").exists() { + } else if cstr!("/sbin/recovery").exists() || cstr!("/system/bin/recovery").exists() { self.recovery(); } else if self.check_two_stage() { self.first_stage(); diff --git a/native/src/init/lib.rs b/native/src/init/lib.rs index a2d18df24..9034d0d56 100644 --- a/native/src/init/lib.rs +++ b/native/src/init/lib.rs @@ -3,7 +3,6 @@ #![feature(try_blocks)] #![allow(clippy::missing_safety_doc)] -use base::FsPath; use logging::setup_klog; // Has to be pub so all symbols in that crate is included pub use magiskpolicy; @@ -106,18 +105,3 @@ pub mod ffi { unsafe fn patch_fissiond(self: &mut MagiskInit, tmp_path: *const c_char); } } - -#[inline(always)] -fn preload_lib() -> &'static FsPath { - FsPath::from(ffi::preload_lib()) -} - -#[inline(always)] -fn preload_policy() -> &'static FsPath { - FsPath::from(ffi::preload_policy()) -} - -#[inline(always)] -fn preload_ack() -> &'static FsPath { - FsPath::from(ffi::preload_ack()) -} diff --git a/native/src/init/logging.rs b/native/src/init/logging.rs index 5f9220b6c..816db5d71 100644 --- a/native/src/init/logging.rs +++ b/native/src/init/logging.rs @@ -1,10 +1,10 @@ use base::{ - LOGGER, LogLevel, Logger, Utf8CStr, cstr, + FsPath, LOGGER, LogLevel, Logger, Utf8CStr, cstr, libc::{ O_CLOEXEC, O_RDWR, O_WRONLY, S_IFCHR, STDERR_FILENO, STDIN_FILENO, STDOUT_FILENO, SYS_dup3, makedev, mknod, syscall, }, - open_fd, path, raw_cstr, + open_fd, raw_cstr, }; use std::{ fs::File, @@ -23,7 +23,7 @@ pub fn setup_klog() { if fd.is_err() { mknod(raw_cstr!("/null"), S_IFCHR | 0o666, makedev(1, 3)); fd = open_fd!(cstr!("/null"), O_RDWR | O_CLOEXEC); - path!("/null").remove().ok(); + cstr!("/null").remove().ok(); } if let Ok(ref fd) = fd { syscall(SYS_dup3, fd, STDIN_FILENO, O_CLOEXEC); @@ -36,7 +36,7 @@ pub fn setup_klog() { if fd.is_err() { mknod(raw_cstr!("/kmsg"), S_IFCHR | 0o666, makedev(1, 11)); fd = open_fd!(cstr!("/kmsg"), O_WRONLY | O_CLOEXEC); - path!("/kmsg").remove().ok(); + cstr!("/kmsg").remove().ok(); } KMSG = fd.map(|fd| fd.into_raw_fd()).unwrap_or(-1); } diff --git a/native/src/init/mount.rs b/native/src/init/mount.rs index 7f8c6fb6e..e6625425f 100644 --- a/native/src/init/mount.rs +++ b/native/src/init/mount.rs @@ -1,9 +1,10 @@ use crate::ffi::MagiskInit; use base::libc::{TMPFS_MAGIC, statfs}; use base::{ - Directory, FsPath, FsPathBuf, LibcReturn, LoggedResult, ResultExt, Utf8CStr, cstr, debug, libc, + Directory, FsPath, FsPathBuf, FsPathMnt, LibcReturn, LoggedResult, ResultExt, Utf8CStr, cstr, + debug, libc, libc::{chdir, chroot, execve, exit, mount}, - parse_mount_info, path, raw_cstr, + parse_mount_info, raw_cstr, }; use cxx::CxxString; use std::ffi::c_long; @@ -36,7 +37,7 @@ pub(crate) fn switch_root(path: &Utf8CStr) { } let mut target = info.target.clone(); - let target = FsPath::from(Utf8CStr::from_string(&mut target)); + let target = Utf8CStr::from_string(&mut target); let new_path = FsPathBuf::default() .join(path) .join(info.target.trim_start_matches('/')); @@ -46,7 +47,7 @@ pub(crate) fn switch_root(path: &Utf8CStr) { } unsafe { chdir(path.as_ptr()).check_io_err()?; - FsPath::from(path).move_mount_to(path!("/"))?; + path.move_mount_to(cstr!("/"))?; chroot(raw_cstr!(".")); } @@ -79,7 +80,7 @@ pub(crate) fn is_rootfs() -> bool { impl MagiskInit { pub(crate) fn prepare_data(&self) { debug!("Setup data tmp"); - path!("/data").mkdir(0o755).log_ok(); + cstr!("/data").mkdir(0o755).log_ok(); unsafe { mount( raw_cstr!("magisk"), @@ -92,16 +93,16 @@ impl MagiskInit { .check_io_err() .log_ok(); - path!("/init").copy_to(path!("/data/magiskinit")).log_ok(); - path!("/.backup").copy_to(path!("/data/.backup")).log_ok(); - path!("/overlay.d") - .copy_to(path!("/data/overlay.d")) + cstr!("/init").copy_to(cstr!("/data/magiskinit")).log_ok(); + cstr!("/.backup").copy_to(cstr!("/data/.backup")).log_ok(); + cstr!("/overlay.d") + .copy_to(cstr!("/data/overlay.d")) .log_ok(); } pub(crate) fn exec_init(&mut self) { for path in self.mount_list.iter_mut().rev() { - let path = FsPath::from(Utf8CStr::from_string(path)); + let path = Utf8CStr::from_string(path); if path.unmount().log().is_ok() { debug!("Unmount [{}]", path); } diff --git a/native/src/init/rootdir.rs b/native/src/init/rootdir.rs index 86e744c1b..d06e2966c 100644 --- a/native/src/init/rootdir.rs +++ b/native/src/init/rootdir.rs @@ -2,8 +2,8 @@ use crate::consts::{ROOTMNT, ROOTOVL}; use crate::ffi::MagiskInit; use base::libc::{O_CREAT, O_RDONLY, O_WRONLY}; use base::{ - BufReadExt, Directory, FsPath, FsPathBuf, LoggedResult, ResultExt, Utf8CStr, Utf8CString, - clone_attr, cstr, cstr_buf, debug, path, + BufReadExt, Directory, FsPath, FsPathBuf, FsPathMnt, LoggedResult, ResultExt, Utf8CStr, + Utf8CString, clone_attr, cstr, cstr_buf, debug, }; use std::io::BufReader; use std::{ @@ -47,7 +47,7 @@ pub struct OverlayAttr(Utf8CString, Utf8CString); impl MagiskInit { pub(crate) fn parse_config_file(&mut self) { - if let Ok(fd) = path!("/data/.backup/.magisk").open(O_RDONLY) { + if let Ok(fd) = cstr!("/data/.backup/.magisk").open(O_RDONLY) { let mut reader = BufReader::new(fd); reader.foreach_props(|key, val| { if key == "PREINITDEVICE" { @@ -102,7 +102,7 @@ impl MagiskInit { let mut mount_list = String::new(); self.mount_impl(cstr!(ROOTOVL), dest, &mut mount_list) .log_ok(); - if let Ok(mut fd) = path!(ROOTMNT).create(O_CREAT | O_WRONLY, 0) { + if let Ok(mut fd) = cstr!(ROOTMNT).create(O_CREAT | O_WRONLY, 0) { fd.write(mount_list.as_bytes()).log_ok(); } } @@ -110,7 +110,7 @@ impl MagiskInit { pub(crate) fn restore_overlay_contexts(&self) { self.overlay_con.iter().for_each(|attr| { let OverlayAttr(path, con) = attr; - FsPath::from(path).set_secontext(con).log_ok(); + path.set_secontext(con).log_ok(); }) } } diff --git a/native/src/init/selinux.rs b/native/src/init/selinux.rs index 70fafd2dc..c1957950f 100644 --- a/native/src/init/selinux.rs +++ b/native/src/init/selinux.rs @@ -1,10 +1,9 @@ use crate::consts::{PREINITMIRR, SELINUXMOCK}; -use crate::ffi::{MagiskInit, split_plat_cil}; -use crate::{preload_ack, preload_lib, preload_policy}; +use crate::ffi::{MagiskInit, preload_ack, preload_lib, preload_policy, split_plat_cil}; use base::const_format::concatcp; use base::{ - BytesExt, FsPath, LibcReturn, LoggedResult, MappedFile, ResultExt, cstr, debug, error, info, - libc, path, raw_cstr, + BytesExt, FsPath, FsPathMnt, LibcReturn, LoggedResult, MappedFile, ResultExt, Utf8CStr, cstr, + debug, error, info, libc, raw_cstr, }; use magiskpolicy::ffi::SePolicy; use std::io::{Read, Write}; @@ -12,17 +11,17 @@ use std::ptr; use std::thread::sleep; use std::time::Duration; -const POLICY_VERSION: &FsPath = path!("/selinux_version"); +const POLICY_VERSION: &Utf8CStr = cstr!("/selinux_version"); -const MOCK_VERSION: &FsPath = path!(concatcp!(SELINUXMOCK, "/version")); -const MOCK_LOAD: &FsPath = path!(concatcp!(SELINUXMOCK, "/load")); -const MOCK_ENFORCE: &FsPath = path!(concatcp!(SELINUXMOCK, "/enforce")); -const MOCK_REQPROT: &FsPath = path!(concatcp!(SELINUXMOCK, "/checkreqprot")); +const MOCK_VERSION: &Utf8CStr = cstr!(concatcp!(SELINUXMOCK, "/version")); +const MOCK_LOAD: &Utf8CStr = cstr!(concatcp!(SELINUXMOCK, "/load")); +const MOCK_ENFORCE: &Utf8CStr = cstr!(concatcp!(SELINUXMOCK, "/enforce")); +const MOCK_REQPROT: &Utf8CStr = cstr!(concatcp!(SELINUXMOCK, "/checkreqprot")); const SELINUX_MNT: &str = "/sys/fs/selinux"; -const SELINUX_ENFORCE: &FsPath = path!(concatcp!(SELINUX_MNT, "/enforce")); -const SELINUX_LOAD: &FsPath = path!(concatcp!(SELINUX_MNT, "/load")); -const SELINUX_REQPROT: &FsPath = path!(concatcp!(SELINUX_MNT, "/checkreqprot")); +const SELINUX_ENFORCE: &Utf8CStr = cstr!(concatcp!(SELINUX_MNT, "/enforce")); +const SELINUX_LOAD: &Utf8CStr = cstr!(concatcp!(SELINUX_MNT, "/load")); +const SELINUX_REQPROT: &Utf8CStr = cstr!(concatcp!(SELINUX_MNT, "/checkreqprot")); enum SePatchStrategy { // 2SI, Android 10+ @@ -49,13 +48,13 @@ enum SePatchStrategy { // node, and because both has been replaced with FIFO files, init will block until we // handle it, effectively hijacking its control flow until the patched sepolicy is loaded. -fn mock_fifo(target: &FsPath, mock: &FsPath) -> LoggedResult<()> { +fn mock_fifo(target: &Utf8CStr, mock: &Utf8CStr) -> LoggedResult<()> { debug!("Hijack [{}]", target); mock.mkfifo(0o666)?; mock.bind_mount_to(target).log() } -fn mock_file(target: &FsPath, mock: &FsPath) -> LoggedResult<()> { +fn mock_file(target: &Utf8CStr, mock: &Utf8CStr) -> LoggedResult<()> { debug!("Hijack [{}]", target); drop(mock.create(libc::O_RDONLY, 0o666)?); mock.bind_mount_to(target).log() @@ -68,7 +67,7 @@ impl MagiskInit { fn cleanup_and_load(&self, rules: &str) { // Cleanup the hijacks - path!("/init").unmount().ok(); + cstr!("/init").unmount().ok(); SELINUX_LOAD.unmount().log_ok(); SELINUX_ENFORCE.unmount().ok(); SELINUX_REQPROT.unmount().ok(); @@ -79,7 +78,7 @@ impl MagiskInit { sepol.to_file(SELINUX_LOAD); // For some reason, restorecon on /init won't work in some cases - path!("/init") + cstr!("/init") .follow_link() .set_secontext(cstr!("u:object_r:init_exec:s0")) .ok(); @@ -89,10 +88,10 @@ impl MagiskInit { } fn handle_sepolicy_impl(&mut self) -> LoggedResult<()> { - path!(SELINUXMOCK).mkdir(0o711)?; + cstr!(SELINUXMOCK).mkdir(0o711)?; let mut rules = String::new(); - let rule_file = path!(concatcp!("/data/", PREINITMIRR, "/sepolicy.rule")); + let rule_file = cstr!(concatcp!("/data/", PREINITMIRR, "/sepolicy.rule")); if rule_file.exists() { debug!("Loading custom sepolicy patch: [{}]", rule_file); rule_file.open(libc::O_RDONLY)?.read_to_string(&mut rules)?; @@ -102,7 +101,7 @@ impl MagiskInit { let strat: SePatchStrategy; - if path!("/system/bin/init").exists() { + if cstr!("/system/bin/init").exists() { strat = SePatchStrategy::LdPreload; } else { let init = MappedFile::open(cstr!("/init"))?; @@ -124,7 +123,7 @@ impl MagiskInit { SePatchStrategy::LdPreload => { info!("SePatchStrategy: LD_PRELOAD"); - path!("init-ld").copy_to(preload_lib())?; + cstr!("init-ld").copy_to(preload_lib())?; unsafe { libc::setenv(raw_cstr!("LD_PRELOAD"), preload_lib().as_ptr(), 1); } @@ -137,7 +136,7 @@ impl MagiskInit { // selinuxfs was not already mounted, mount it ourselves // Remount procfs with proper options - path!("/proc").remount_with_data(cstr!("hidepid=2,gid=3009"))?; + cstr!("/proc").remount_with_data(cstr!("hidepid=2,gid=3009"))?; // Preserve sysfs and procfs self.mount_list.retain(|s| s != "/proc" && s != "/sys"); diff --git a/native/src/init/twostage.rs b/native/src/init/twostage.rs index 44201c4b2..d9f66c1b2 100644 --- a/native/src/init/twostage.rs +++ b/native/src/init/twostage.rs @@ -1,8 +1,7 @@ use crate::ffi::MagiskInit; use base::{ - LoggedResult, MappedFile, MutBytesExt, ResultExt, cstr, debug, error, + FsPath, FsPathMnt, LoggedResult, MappedFile, MutBytesExt, ResultExt, cstr, debug, error, libc::{O_CLOEXEC, O_CREAT, O_RDONLY, O_WRONLY}, - path, }; use std::io::Write; @@ -29,8 +28,8 @@ pub(crate) fn hexpatch_init_for_second_stage(writable: bool) { if !writable { // If we cannot directly modify /init, we need to bind mount a replacement on top of it - let src = path!("/init"); - let dest = path!("/data/init"); + let src = cstr!("/init"); + let dest = cstr!("/data/init"); let _: LoggedResult<()> = try { { let mut fd = dest.create(O_CREAT | O_WRONLY, 0)?; @@ -70,32 +69,32 @@ impl MagiskInit { // /sdcard exists and fallback to using hexpatch. if self.config.force_normal_boot { - path!("/first_stage_ramdisk/storage/self") + cstr!("/first_stage_ramdisk/storage/self") .mkdirs(0o755) .log_ok(); - path!("/first_stage_ramdisk/storage/self/primary") - .create_symlink_to(path!("/system/system/bin/init")) + cstr!("/first_stage_ramdisk/storage/self/primary") + .create_symlink_to(cstr!("/system/system/bin/init")) .log_ok(); debug!("Symlink /first_stage_ramdisk/storage/self/primary -> /system/system/bin/init"); - path!("/first_stage_ramdisk/sdcard") + cstr!("/first_stage_ramdisk/sdcard") .create(O_RDONLY | O_CREAT | O_CLOEXEC, 0) .log_ok(); } else { - path!("/storage/self").mkdirs(0o755).log_ok(); - path!("/storage/self/primary") - .create_symlink_to(path!("/system/system/bin/init")) + cstr!("/storage/self").mkdirs(0o755).log_ok(); + cstr!("/storage/self/primary") + .create_symlink_to(cstr!("/system/system/bin/init")) .log_ok(); debug!("Symlink /storage/self/primary -> /system/system/bin/init"); } - path!("/init").rename_to(path!("/sdcard")).log_ok(); + cstr!("/init").rename_to(cstr!("/sdcard")).log_ok(); // First try to mount magiskinit from rootfs to workaround Samsung RKP - if path!("/sdcard").bind_mount_to(path!("/sdcard")).is_ok() { + if cstr!("/sdcard").bind_mount_to(cstr!("/sdcard")).is_ok() { debug!("Bind mount /sdcard -> /sdcard"); } else { // Binding mounting from rootfs is not supported before Linux 3.12 - path!("/data/magiskinit") - .bind_mount_to(path!("/sdcard")) + cstr!("/data/magiskinit") + .bind_mount_to(cstr!("/sdcard")) .log_ok(); debug!("Bind mount /data/magiskinit -> /sdcard"); } diff --git a/native/src/sepolicy/statement.rs b/native/src/sepolicy/statement.rs index 14020a95b..5a1158346 100644 --- a/native/src/sepolicy/statement.rs +++ b/native/src/sepolicy/statement.rs @@ -279,7 +279,7 @@ impl SePolicy { pub fn load_rule_file(&mut self, filename: &Utf8CStr) { let result: LoggedResult<()> = try { - let file = FsPath::from(filename).open(O_RDONLY | O_CLOEXEC)?; + let file = filename.open(O_RDONLY | O_CLOEXEC)?; let mut reader = BufReader::new(file); self.load_rules_from_reader(&mut reader); };