mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-12-22 16:07:39 +00:00
Implement preinit related features in Rust
This commit is contained in:
parent
1eddbfd72c
commit
a1b6568226
2
native/src/Cargo.lock
generated
2
native/src/Cargo.lock
generated
@ -72,6 +72,7 @@ dependencies = [
|
||||
"argh",
|
||||
"bytemuck",
|
||||
"cfg-if",
|
||||
"const_format",
|
||||
"cxx",
|
||||
"cxx-gen",
|
||||
"libc",
|
||||
@ -467,7 +468,6 @@ version = "0.0.0"
|
||||
dependencies = [
|
||||
"base",
|
||||
"bytemuck",
|
||||
"const_format",
|
||||
"cxx",
|
||||
"cxx-gen",
|
||||
"num-derive",
|
||||
|
@ -22,3 +22,4 @@ argh = { workspace = true }
|
||||
bytemuck = { workspace = true }
|
||||
num-traits = { workspace = true }
|
||||
num-derive = { workspace = true }
|
||||
const_format = { workspace = true }
|
||||
|
@ -451,6 +451,7 @@ pub struct FsPathBuf<'a>(&'a mut dyn Utf8CStrWrite);
|
||||
|
||||
impl<'a> FsPathBuf<'a> {
|
||||
pub fn new(value: &'a mut dyn Utf8CStrWrite) -> Self {
|
||||
value.clear();
|
||||
FsPathBuf(value)
|
||||
}
|
||||
|
||||
@ -656,7 +657,8 @@ macro_rules! cstr {
|
||||
);
|
||||
#[allow(unused_unsafe)]
|
||||
unsafe {
|
||||
$crate::Utf8CStr::from_bytes_unchecked(concat!($($str)*, "\0").as_bytes())
|
||||
$crate::Utf8CStr::from_bytes_unchecked($crate::const_format::concatcp!($($str)*, "\0")
|
||||
.as_bytes())
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
#![feature(io_error_more)]
|
||||
#![feature(utf8_chunks)]
|
||||
|
||||
pub use const_format;
|
||||
pub use libc;
|
||||
use num_traits::FromPrimitive;
|
||||
|
||||
|
@ -17,5 +17,4 @@ cxx = { workspace = true }
|
||||
num-traits = { workspace = true }
|
||||
num-derive = { workspace = true }
|
||||
quick-protobuf = { workspace = true }
|
||||
const_format = { workspace = true }
|
||||
bytemuck = { workspace = true, features = ["derive"] }
|
||||
|
@ -19,157 +19,6 @@ bool zygisk_enabled = false;
|
||||
/*********
|
||||
* Setup *
|
||||
*********/
|
||||
static void setup_mounts() {
|
||||
LOGI("* Magic mount setup\n");
|
||||
auto self_mount_info = parse_mount_info("self");
|
||||
char path[PATH_MAX];
|
||||
|
||||
// Bind remount module root to clear nosuid
|
||||
ssprintf(path, sizeof(path), "%s/" MODULEMNT, get_magisk_tmp());
|
||||
xmkdir(path, 0755);
|
||||
xmount(MODULEROOT, path, nullptr, MS_BIND, nullptr);
|
||||
xmount(nullptr, path, nullptr, MS_REMOUNT | MS_BIND | MS_RDONLY, nullptr);
|
||||
xmount(nullptr, path, nullptr, MS_PRIVATE, nullptr);
|
||||
|
||||
// Check and mount preinit mirror
|
||||
char dev_path[64];
|
||||
ssprintf(dev_path, sizeof(dev_path), "%s/" PREINITDEV, get_magisk_tmp());
|
||||
if (struct stat st{}; stat(dev_path, &st) == 0 && S_ISBLK(st.st_mode)) {
|
||||
// DO NOT mount the block device directly, as we do not know the flags and configs
|
||||
// to properly mount the partition; mounting block devices directly as rw could cause
|
||||
// crashes if the filesystem driver is crap (e.g. some broken F2FS drivers).
|
||||
// What we do instead is to scan through the current mountinfo and find a pre-existing
|
||||
// mount point mounting our desired partition, and then bind mount the target folder.
|
||||
dev_t preinit_dev = st.st_rdev;
|
||||
bool mounted = false;
|
||||
ssprintf(path, sizeof(path), "%s/" PREINITMIRR, get_magisk_tmp());
|
||||
for (const auto &info: self_mount_info) {
|
||||
if (info.root == "/" && info.device == preinit_dev) {
|
||||
auto flags = split_view(info.fs_option, ",");
|
||||
auto rw = std::any_of(flags.begin(), flags.end(), [](const auto &flag) {
|
||||
return flag == "rw"sv;
|
||||
});
|
||||
if (!rw) continue;
|
||||
string preinit_dir = resolve_preinit_dir(info.target.data());
|
||||
xmkdir(preinit_dir.data(), 0700);
|
||||
xmkdirs(path, 0755);
|
||||
mounted = xmount(preinit_dir.data(), path, nullptr, MS_BIND, nullptr) == 0;
|
||||
if (mounted) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!mounted) {
|
||||
LOGW("preinit mirror not mounted %u:%u\n", major(preinit_dev), minor(preinit_dev));
|
||||
unlink(dev_path);
|
||||
}
|
||||
}
|
||||
|
||||
// Prepare worker
|
||||
ssprintf(path, sizeof(path), "%s/" WORKERDIR, get_magisk_tmp());
|
||||
xmkdir(path, 0);
|
||||
xmount(path, path, nullptr, MS_BIND, nullptr);
|
||||
xmount(nullptr, path, nullptr, MS_PRIVATE, nullptr);
|
||||
}
|
||||
|
||||
string find_preinit_device() {
|
||||
enum part_t {
|
||||
UNKNOWN,
|
||||
PERSIST,
|
||||
METADATA,
|
||||
CACHE,
|
||||
DATA,
|
||||
};
|
||||
|
||||
part_t ext4_type = UNKNOWN;
|
||||
part_t f2fs_type = UNKNOWN;
|
||||
|
||||
bool encrypted = get_prop("ro.crypto.state") == "encrypted";
|
||||
bool mount = getuid() == 0 && getenv("MAGISKTMP");
|
||||
bool make_dev = mount && getenv("MAKEDEV");
|
||||
|
||||
string preinit_source;
|
||||
string preinit_dir;
|
||||
dev_t preinit_dev;
|
||||
|
||||
for (const auto &info: parse_mount_info("self")) {
|
||||
if (info.target.ends_with(PREINITMIRR))
|
||||
return basename(info.source.data());
|
||||
if (info.root != "/" || info.source[0] != '/' || info.source.find("/dm-") != string::npos)
|
||||
continue;
|
||||
// Skip all non ext4 partitions once we found a matching ext4 partition
|
||||
if (ext4_type != UNKNOWN && info.type != "ext4")
|
||||
continue;
|
||||
if (info.type != "ext4" && info.type != "f2fs")
|
||||
continue;
|
||||
auto flags = split_view(info.fs_option, ",");
|
||||
auto rw = std::any_of(flags.begin(), flags.end(), [](const auto &flag) {
|
||||
return flag == "rw"sv;
|
||||
});
|
||||
if (!rw) continue;
|
||||
if (auto base = std::string_view(info.source).substr(0, info.source.find_last_of('/'));
|
||||
!base.ends_with("/by-name") && !base.ends_with("/block")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
part_t &matched = (info.type == "f2fs") ? f2fs_type : ext4_type;
|
||||
switch (matched) {
|
||||
case UNKNOWN:
|
||||
if (info.target == "/persist" || info.target == "/mnt/vendor/persist") {
|
||||
matched = PERSIST;
|
||||
break;
|
||||
}
|
||||
[[fallthrough]];
|
||||
case PERSIST:
|
||||
if (info.target == "/metadata") {
|
||||
matched = METADATA;
|
||||
break;
|
||||
}
|
||||
[[fallthrough]];
|
||||
case METADATA:
|
||||
if (info.target == "/cache") {
|
||||
matched = CACHE;
|
||||
break;
|
||||
}
|
||||
[[fallthrough]];
|
||||
case CACHE:
|
||||
if (info.target == "/data") {
|
||||
if (!encrypted || access("/data/unencrypted", F_OK) == 0) {
|
||||
matched = DATA;
|
||||
break;
|
||||
}
|
||||
}
|
||||
[[fallthrough]];
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
|
||||
if (mount) {
|
||||
preinit_dir = resolve_preinit_dir(info.target.data());
|
||||
preinit_dev = info.device;
|
||||
}
|
||||
preinit_source = info.source;
|
||||
|
||||
// Cannot find any better partition, stop finding
|
||||
if (ext4_type == DATA)
|
||||
break;
|
||||
}
|
||||
|
||||
if (preinit_source.empty())
|
||||
return "";
|
||||
|
||||
if (!preinit_dir.empty()) {
|
||||
auto mirror_dir = string(getenv("MAGISKTMP")) + "/" PREINITMIRR;
|
||||
mkdirs(preinit_dir.data(), 0700);
|
||||
mkdirs(mirror_dir.data(), 0700);
|
||||
xmount(preinit_dir.data(), mirror_dir.data(), nullptr, MS_BIND, nullptr);
|
||||
if (make_dev) {
|
||||
auto dev_path = string(getenv("MAGISKTMP")) + "/" PREINITDEV;
|
||||
xmknod(dev_path.data(), S_IFBLK | 0600, preinit_dev);
|
||||
}
|
||||
}
|
||||
return basename(preinit_source.data());
|
||||
}
|
||||
|
||||
static bool magisk_env() {
|
||||
char buf[4096];
|
||||
|
@ -42,7 +42,6 @@ extern std::string native_bridge;
|
||||
|
||||
void reset_zygisk(bool restore);
|
||||
int connect_daemon(int req, bool create = false);
|
||||
std::string find_preinit_device();
|
||||
void unlock_blocks();
|
||||
|
||||
// Poll control
|
||||
|
@ -26,4 +26,9 @@ private:
|
||||
};
|
||||
|
||||
const char *get_magisk_tmp();
|
||||
|
||||
// Rust bindings
|
||||
static inline rust::Utf8CStr get_magisk_tmp_rs() { return get_magisk_tmp(); }
|
||||
static inline rust::String resolve_preinit_dir_rs(rust::Utf8CStr base_dir) {
|
||||
return resolve_preinit_dir(base_dir.c_str());
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
#![feature(format_args_nl)]
|
||||
#![feature(try_blocks)]
|
||||
#![allow(clippy::missing_safety_doc)]
|
||||
|
||||
use base::Utf8CStr;
|
||||
@ -7,6 +8,7 @@ use daemon::{daemon_entry, find_apk_path, get_magiskd, MagiskD};
|
||||
use logging::{
|
||||
android_logging, magisk_logging, zygisk_close_logd, zygisk_get_logd, zygisk_logging,
|
||||
};
|
||||
use mount::{find_preinit_device, setup_mounts};
|
||||
use resetprop::{persist_delete_prop, persist_get_prop, persist_get_props, persist_set_prop};
|
||||
|
||||
mod cert;
|
||||
@ -14,6 +16,7 @@ mod cert;
|
||||
mod consts;
|
||||
mod daemon;
|
||||
mod logging;
|
||||
mod mount;
|
||||
mod resetprop;
|
||||
|
||||
#[cxx::bridge]
|
||||
@ -66,6 +69,8 @@ pub mod ffi {
|
||||
|
||||
#[cxx_name = "get_magisk_tmp_rs"]
|
||||
fn get_magisk_tmp() -> Utf8CStrRef<'static>;
|
||||
#[cxx_name = "resolve_preinit_dir_rs"]
|
||||
fn resolve_preinit_dir(base_dir: Utf8CStrRef) -> String;
|
||||
|
||||
#[cxx_name = "MagiskD"]
|
||||
type CxxMagiskD;
|
||||
@ -83,6 +88,8 @@ pub mod ffi {
|
||||
fn zygisk_get_logd() -> i32;
|
||||
fn find_apk_path(pkg: Utf8CStrRef, data: &mut [u8]) -> usize;
|
||||
fn read_certificate(fd: i32, version: i32) -> Vec<u8>;
|
||||
fn setup_mounts();
|
||||
fn find_preinit_device() -> String;
|
||||
unsafe fn persist_get_prop(name: Utf8CStrRef, prop_cb: Pin<&mut PropCb>);
|
||||
unsafe fn persist_get_props(prop_cb: Pin<&mut PropCb>);
|
||||
unsafe fn persist_delete_prop(name: Utf8CStrRef) -> bool;
|
||||
|
@ -9,7 +9,6 @@ use std::sync::atomic::{AtomicI32, Ordering};
|
||||
use std::{fs, io};
|
||||
|
||||
use bytemuck::{bytes_of, bytes_of_mut, write_zeroes, Pod, Zeroable};
|
||||
use const_format::concatcp;
|
||||
use num_derive::{FromPrimitive, ToPrimitive};
|
||||
use num_traits::FromPrimitive;
|
||||
|
||||
@ -19,8 +18,8 @@ use base::libc::{
|
||||
SIG_SETMASK,
|
||||
};
|
||||
use base::{
|
||||
exit_on_error, libc, raw_cstr, FsPathBuf, LogLevel, Logger, Utf8CStr, Utf8CStrBuf,
|
||||
Utf8CStrBufArr, Utf8CStrWrite, LOGGER,
|
||||
const_format::concatcp, exit_on_error, libc, raw_cstr, FsPathBuf, LogLevel, Logger, Utf8CStr,
|
||||
Utf8CStrBuf, Utf8CStrBufArr, Utf8CStrWrite, LOGGER,
|
||||
};
|
||||
|
||||
use crate::consts::{LOGFILE, LOG_PIPE};
|
||||
|
@ -137,9 +137,8 @@ int magisk_main(int argc, char *argv[]) {
|
||||
install_module(argv[2]);
|
||||
} else if (argv[1] == "--preinit-device"sv) {
|
||||
auto name = find_preinit_device();
|
||||
LOGD("preinit device: %s\n", name.data());
|
||||
if (!name.empty()) {
|
||||
printf("%s\n", name.data());
|
||||
printf("%s\n", name.c_str());
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
|
276
native/src/core/mount.rs
Normal file
276
native/src/core/mount.rs
Normal file
@ -0,0 +1,276 @@
|
||||
use std::path::Path;
|
||||
use std::ptr;
|
||||
|
||||
use num_traits::AsPrimitive;
|
||||
|
||||
use base::libc::{c_uint, dev_t};
|
||||
use base::{
|
||||
cstr, debug, info, libc, parse_mount_info, raw_cstr, warn, FsPath, FsPathBuf, LibcReturn,
|
||||
LoggedResult, ResultExt, Utf8CStr, Utf8CStrBufArr,
|
||||
};
|
||||
|
||||
use crate::consts::{MODULEMNT, MODULEROOT, PREINITDEV, PREINITMIRR, WORKERDIR};
|
||||
use crate::ffi::{get_magisk_tmp, resolve_preinit_dir};
|
||||
use crate::get_prop;
|
||||
|
||||
pub fn setup_mounts() {
|
||||
info!("* Setup internal mounts");
|
||||
|
||||
let magisk_tmp = get_magisk_tmp();
|
||||
let mut buf = Utf8CStrBufArr::default();
|
||||
|
||||
// Mount preinit directory
|
||||
let mut dev_buf = Utf8CStrBufArr::<64>::new();
|
||||
let dev_path = FsPathBuf::new(&mut dev_buf)
|
||||
.join(magisk_tmp)
|
||||
.join(PREINITDEV);
|
||||
if let Ok(attr) = dev_path.get_attr() {
|
||||
if attr.st.st_mode & libc::S_IFMT as c_uint == libc::S_IFBLK.as_() {
|
||||
// DO NOT mount the block device directly, as we do not know the flags and configs
|
||||
// to properly mount the partition; mounting block devices directly as rw could cause
|
||||
// crashes if the filesystem driver is crap (e.g. some broken F2FS drivers).
|
||||
// What we do instead is to scan through the current mountinfo and find a pre-existing
|
||||
// mount point mounting our desired partition, and then bind mount the target folder.
|
||||
let preinit_dev = attr.st.st_rdev;
|
||||
let mnt_path = FsPathBuf::new(&mut buf).join(magisk_tmp).join(PREINITMIRR);
|
||||
let mut mounted = false;
|
||||
for info in parse_mount_info("self") {
|
||||
if info.root == "/" && info.device == preinit_dev {
|
||||
if !info.fs_option.split(',').any(|s| s == "rw") {
|
||||
// Only care about rw mounts
|
||||
continue;
|
||||
}
|
||||
let mut target = info.target;
|
||||
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 r: LoggedResult<()> = try {
|
||||
FsPath::from(preinit_dir).mkdir(0o700)?;
|
||||
mnt_path.mkdirs(0o755)?;
|
||||
unsafe {
|
||||
libc::mount(
|
||||
preinit_dir.as_ptr(),
|
||||
mnt_path.as_ptr(),
|
||||
ptr::null(),
|
||||
libc::MS_BIND,
|
||||
ptr::null(),
|
||||
)
|
||||
.as_os_err()?
|
||||
}
|
||||
};
|
||||
if r.is_ok() {
|
||||
mounted = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if !mounted {
|
||||
warn!("mount: preinit mirror not mounted");
|
||||
dev_path.remove().ok();
|
||||
} else {
|
||||
debug!("mount: preinit mirror mounted");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Bind remount module root to clear nosuid
|
||||
let module_mnt = FsPathBuf::new(&mut buf).join(magisk_tmp).join(MODULEMNT);
|
||||
let _: LoggedResult<()> = try {
|
||||
module_mnt.mkdir(0o755)?;
|
||||
unsafe {
|
||||
libc::mount(
|
||||
raw_cstr!(MODULEROOT),
|
||||
module_mnt.as_ptr(),
|
||||
ptr::null(),
|
||||
libc::MS_BIND,
|
||||
ptr::null(),
|
||||
)
|
||||
.as_os_err()?;
|
||||
libc::mount(
|
||||
ptr::null(),
|
||||
module_mnt.as_ptr(),
|
||||
ptr::null(),
|
||||
libc::MS_REMOUNT | libc::MS_BIND | libc::MS_RDONLY,
|
||||
ptr::null(),
|
||||
)
|
||||
.as_os_err()?;
|
||||
libc::mount(
|
||||
ptr::null(),
|
||||
module_mnt.as_ptr(),
|
||||
ptr::null(),
|
||||
libc::MS_PRIVATE,
|
||||
ptr::null(),
|
||||
)
|
||||
.as_os_err()?;
|
||||
}
|
||||
};
|
||||
|
||||
// Prepare worker
|
||||
let worker_dir = FsPathBuf::new(&mut buf).join(magisk_tmp).join(WORKERDIR);
|
||||
let _: LoggedResult<()> = try {
|
||||
worker_dir.mkdir(0)?;
|
||||
unsafe {
|
||||
libc::mount(
|
||||
worker_dir.as_ptr(),
|
||||
worker_dir.as_ptr(),
|
||||
ptr::null(),
|
||||
libc::MS_BIND,
|
||||
ptr::null(),
|
||||
)
|
||||
.as_os_err()?;
|
||||
libc::mount(
|
||||
ptr::null(),
|
||||
worker_dir.as_ptr(),
|
||||
ptr::null(),
|
||||
libc::MS_PRIVATE,
|
||||
ptr::null(),
|
||||
)
|
||||
.as_os_err()?;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[derive(Ord, PartialOrd, Eq, PartialEq)]
|
||||
enum PartId {
|
||||
Unknown,
|
||||
Persist,
|
||||
Metadata,
|
||||
Cache,
|
||||
Data,
|
||||
}
|
||||
|
||||
pub fn find_preinit_device() -> String {
|
||||
let encrypted = get_prop(cstr!("ro.crypto.state"), false) == "encrypted";
|
||||
let mount = unsafe { libc::getuid() } == 0 && std::env::var("MAGISKTMP").is_ok();
|
||||
let make_dev = mount && std::env::var_os("MAKEDEV").is_some();
|
||||
|
||||
let mut ext4_type = PartId::Unknown;
|
||||
let mut f2fs_type = PartId::Unknown;
|
||||
|
||||
let mut preinit_source: String = String::new();
|
||||
let mut preinit_dir: String = String::new();
|
||||
let mut preinit_dev: u64 = 0;
|
||||
|
||||
'info_loop: for info in parse_mount_info("self") {
|
||||
if info.target.ends_with(PREINITMIRR) {
|
||||
return Path::new(&info.source)
|
||||
.file_name()
|
||||
.unwrap()
|
||||
.to_str()
|
||||
.unwrap()
|
||||
.to_string();
|
||||
}
|
||||
if info.root != "/" || !info.source.starts_with('/') || info.source.contains("/dm-") {
|
||||
continue;
|
||||
}
|
||||
if ext4_type != PartId::Unknown && info.fs_type != "ext4" {
|
||||
// Skip all non ext4 partitions once we found a matching ext4 partition
|
||||
continue;
|
||||
}
|
||||
if info.fs_type != "ext4" && info.fs_type != "f2fs" {
|
||||
// Only care about ext4 and f2fs filesystems
|
||||
continue;
|
||||
}
|
||||
if !info.fs_option.split(',').any(|s| s == "rw") {
|
||||
// Only care about rw mounts
|
||||
continue;
|
||||
}
|
||||
if let Some(path) = Path::new(&info.source).parent() {
|
||||
if !path.ends_with("by-name") && !path.ends_with("block") {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
let matched_type = if info.fs_type == "f2fs" {
|
||||
&mut f2fs_type
|
||||
} else {
|
||||
&mut ext4_type
|
||||
};
|
||||
|
||||
'block: {
|
||||
if *matched_type <= PartId::Unknown
|
||||
&& (info.target == "/persist" || info.target == "/mnt/vendor/persist")
|
||||
{
|
||||
*matched_type = PartId::Persist;
|
||||
break 'block;
|
||||
}
|
||||
if *matched_type <= PartId::Persist && info.target == "/metadata" {
|
||||
*matched_type = PartId::Metadata;
|
||||
break 'block;
|
||||
}
|
||||
if *matched_type <= PartId::Metadata && info.target == "/cache" {
|
||||
*matched_type = PartId::Cache;
|
||||
break 'block;
|
||||
}
|
||||
if *matched_type <= PartId::Cache
|
||||
&& info.target == "/data"
|
||||
&& (!encrypted || FsPath::from(cstr!("/data/unencrypted")).exists())
|
||||
{
|
||||
*matched_type = PartId::Data;
|
||||
}
|
||||
|
||||
// No matches, continue through the loop
|
||||
continue 'info_loop;
|
||||
}
|
||||
|
||||
if mount {
|
||||
let mut target = info.target;
|
||||
preinit_dir = resolve_preinit_dir(Utf8CStr::from_string(&mut target));
|
||||
preinit_dev = info.device;
|
||||
}
|
||||
preinit_source = info.source;
|
||||
|
||||
// Cannot find any better partition, stop finding
|
||||
if ext4_type == PartId::Data {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if preinit_source.is_empty() {
|
||||
return String::new();
|
||||
}
|
||||
|
||||
if !preinit_dir.is_empty() {
|
||||
if let Ok(tmp) = std::env::var("MAGISKTMP") {
|
||||
let mut buf = Utf8CStrBufArr::default();
|
||||
let mirror_dir = FsPathBuf::new(&mut buf).join(&tmp).join(PREINITMIRR);
|
||||
let preinit_dir = FsPath::from(Utf8CStr::from_string(&mut preinit_dir));
|
||||
let _: LoggedResult<()> = try {
|
||||
preinit_dir.mkdirs(0o700)?;
|
||||
mirror_dir.mkdirs(0o700)?;
|
||||
unsafe {
|
||||
libc::mount(
|
||||
preinit_dir.as_ptr(),
|
||||
mirror_dir.as_ptr(),
|
||||
ptr::null(),
|
||||
libc::MS_BIND,
|
||||
ptr::null(),
|
||||
)
|
||||
.as_os_err()?;
|
||||
}
|
||||
};
|
||||
if make_dev {
|
||||
let dev_path = FsPathBuf::new(&mut buf).join(&tmp).join(PREINITDEV);
|
||||
unsafe {
|
||||
libc::mknod(
|
||||
dev_path.as_ptr(),
|
||||
libc::S_IFBLK | 0o600,
|
||||
preinit_dev as dev_t,
|
||||
)
|
||||
.as_os_err()
|
||||
.log()
|
||||
.ok();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Path::new(&preinit_source)
|
||||
.file_name()
|
||||
.unwrap()
|
||||
.to_str()
|
||||
.unwrap()
|
||||
.to_string()
|
||||
}
|
@ -1,6 +1,17 @@
|
||||
use const_format::concatcp;
|
||||
use base::const_format::concatcp;
|
||||
|
||||
pub const LOGFILE: &str = "/cache/magisk.log";
|
||||
pub const INTLROOT: &str = ".magisk";
|
||||
pub const LOG_PIPE: &str = concatcp!(INTLROOT, "/device/log");
|
||||
pub const MAIN_CONFIG: &str = concatcp!(INTLROOT, "/config");
|
||||
|
||||
// data paths
|
||||
const SECURE_DIR: &str = "/data/adb";
|
||||
pub const MODULEROOT: &str = concatcp!(SECURE_DIR, "modules");
|
||||
|
||||
// tmpfs paths
|
||||
const INTERNAL_DIR: &str = ".magisk";
|
||||
pub const LOG_PIPE: &str = concatcp!(INTERNAL_DIR, "/device/log");
|
||||
pub const MAIN_CONFIG: &str = concatcp!(INTERNAL_DIR, "/config");
|
||||
pub const PREINITMIRR: &str = concatcp!(INTERNAL_DIR, "/preinit");
|
||||
pub const MODULEMNT: &str = concatcp!(INTERNAL_DIR, "/modules");
|
||||
pub const WORKERDIR: &str = concatcp!(INTERNAL_DIR, "/worker");
|
||||
pub const DEVICEDIR: &str = concatcp!(INTERNAL_DIR, "/device");
|
||||
pub const PREINITDEV: &str = concatcp!(DEVICEDIR, "/preinit");
|
||||
|
Loading…
x
Reference in New Issue
Block a user