Fix path tracking in module.rs

This commit is contained in:
topjohnwu
2025-09-12 12:11:39 -07:00
committed by John Wu
parent e2a1774e5b
commit 71213cc6f4

View File

@@ -96,46 +96,101 @@ impl Drop for PathTracker<'_> {
} }
} }
struct FilePaths<'a> { // The comments for this struct assume real = "/system/bin"
struct ModulePaths<'a> {
real: PathTracker<'a>, real: PathTracker<'a>,
worker: PathTracker<'a>, module: PathTracker<'a>,
module_mnt: PathTracker<'a>, module_mnt: PathTracker<'a>,
module_root: PathTracker<'a>,
} }
impl FilePaths<'_> { impl ModulePaths<'_> {
fn append(&mut self, name: &str) -> FilePaths<'_> { fn new<'a>(
FilePaths { real: &'a mut dyn Utf8CStrBuf,
real: self.real.append(name), module: &'a mut dyn Utf8CStrBuf,
worker: self.worker.append(name), module_mnt: &'a mut dyn Utf8CStrBuf,
module_mnt: self.module_mnt.append(name), ) -> ModulePaths<'a> {
module_root: self.module_root.append(name), real.append_path("/");
module.append_path(MODULEROOT);
module_mnt
.append_path(get_magisk_tmp())
.append_path(MODULEMNT);
ModulePaths {
real: PathTracker::from(real),
module: PathTracker::from(module),
module_mnt: PathTracker::from(module_mnt),
} }
} }
fn reborrow(&mut self) -> FilePaths<'_> { fn set_module(&mut self, module: &str) -> ModulePaths<'_> {
FilePaths { ModulePaths {
real: self.real.reborrow(), real: self.real.reborrow(),
worker: self.worker.reborrow(), module: self.module.append(module),
module_mnt: self.module_mnt.reborrow(), module_mnt: self.module_mnt.append(module),
module_root: self.module_root.reborrow(),
} }
} }
fn append(&mut self, name: &str) -> ModulePaths<'_> {
ModulePaths {
real: self.real.append(name),
module: self.module.append(name),
module_mnt: self.module_mnt.append(name),
}
}
// Returns "/system/bin"
fn real(&self) -> &Utf8CStr { fn real(&self) -> &Utf8CStr {
self.real.path self.real.path
} }
fn worker(&self) -> &Utf8CStr { // Returns "$MAGISK_TMP/.magisk/modules/{module}/system/bin"
self.worker.path fn module(&self) -> &Utf8CStr {
self.module.path
} }
// Returns "/data/adb/modules/{module}/system/bin"
fn module_mnt(&self) -> &Utf8CStr { fn module_mnt(&self) -> &Utf8CStr {
self.module_mnt.path self.module_mnt.path
} }
}
fn module(&self) -> &Utf8CStr { // The comments for this struct assume real = "/system/bin"
self.module_root.path struct MountPaths<'a> {
real: PathTracker<'a>,
worker: PathTracker<'a>,
}
impl MountPaths<'_> {
fn new<'a>(real: &'a mut dyn Utf8CStrBuf, worker: &'a mut dyn Utf8CStrBuf) -> MountPaths<'a> {
real.append_path("/");
worker.append_path(get_magisk_tmp()).append_path(WORKERDIR);
MountPaths {
real: PathTracker::from(real),
worker: PathTracker::from(worker),
}
}
fn append(&mut self, name: &str) -> MountPaths<'_> {
MountPaths {
real: self.real.append(name),
worker: self.worker.append(name),
}
}
fn reborrow(&mut self) -> MountPaths<'_> {
MountPaths {
real: self.real.reborrow(),
worker: self.worker.reborrow(),
}
}
// Returns "/system/bin"
fn real(&self) -> &Utf8CStr {
self.real.path
}
// Returns "$MAGISK_TMP/.magisk/worker/system/bin"
fn worker(&self) -> &Utf8CStr {
self.worker.path
} }
} }
@@ -154,7 +209,7 @@ impl FsNode {
} }
} }
fn collect(&mut self, mut paths: FilePaths) -> LoggedResult<()> { fn collect(&mut self, mut paths: ModulePaths) -> LoggedResult<()> {
let FsNode::Directory { children } = self else { let FsNode::Directory { children } = self else {
return Ok(()); return Ok(());
}; };
@@ -169,6 +224,7 @@ impl FsNode {
.or_insert_with(FsNode::new_dir); .or_insert_with(FsNode::new_dir);
node.collect(entry_paths)?; node.collect(entry_paths)?;
} else if entry.is_symlink() { } else if entry.is_symlink() {
// Read the link and store its target
let mut link = cstr::buf::default(); let mut link = cstr::buf::default();
path.read_link(&mut link)?; path.read_link(&mut link)?;
children children
@@ -225,7 +281,7 @@ impl FsNode {
} }
} }
fn commit(&mut self, mut path: FilePaths, is_root_dir: bool) -> LoggedResult<()> { fn commit(&mut self, mut path: MountPaths, is_root_dir: bool) -> LoggedResult<()> {
match self { match self {
FsNode::Directory { children } => { FsNode::Directory { children } => {
let mut is_tmpfs = false; let mut is_tmpfs = false;
@@ -277,7 +333,7 @@ impl FsNode {
Ok(()) Ok(())
} }
fn commit_tmpfs(&mut self, mut path: FilePaths) -> LoggedResult<()> { fn commit_tmpfs(&mut self, mut path: MountPaths) -> LoggedResult<()> {
match self { match self {
FsNode::Directory { children } => { FsNode::Directory { children } => {
path.worker().mkdirs(0o000)?; path.worker().mkdirs(0o000)?;
@@ -779,26 +835,12 @@ impl MagiskD {
fn apply_modules(&self, module_list: &[ModuleInfo]) { fn apply_modules(&self, module_list: &[ModuleInfo]) {
let mut system = FsNode::new_dir(); let mut system = FsNode::new_dir();
// Build all the base "prefix" paths // Create buffers for paths
let mut root = cstr::buf::default().join_path("/"); let mut buf1 = cstr::buf::dynamic(256);
let mut buf2 = cstr::buf::dynamic(256);
let mut buf3 = cstr::buf::dynamic(256);
let mut module_dir = cstr::buf::default().join_path(MODULEROOT); let mut paths = ModulePaths::new(&mut buf1, &mut buf2, &mut buf3);
let mut module_mnt = cstr::buf::default()
.join_path(get_magisk_tmp())
.join_path(MODULEMNT);
let mut worker = cstr::buf::default()
.join_path(get_magisk_tmp())
.join_path(WORKERDIR);
// Create a collection of all relevant paths
let mut root_paths = FilePaths {
real: PathTracker::from(&mut root),
worker: PathTracker::from(&mut worker),
module_mnt: PathTracker::from(&mut module_mnt),
module_root: PathTracker::from(&mut module_dir),
};
// Step 1: Create virtual filesystem tree // Step 1: Create virtual filesystem tree
// //
@@ -806,28 +848,27 @@ impl MagiskD {
// record the union of all module filesystem trees under each of their /system directory. // record the union of all module filesystem trees under each of their /system directory.
for info in module_list { for info in module_list {
let mut module_paths = root_paths.append(&info.name); let mut paths = paths.set_module(&info.name);
{
// Read props // Read props
let prop = module_paths.append("system.prop"); let prop = paths.append("system.prop");
if prop.module().exists() { if prop.module().exists() {
load_prop_file(prop.module()); load_prop_file(prop.module());
}
} }
{ drop(prop);
// Check whether skip mounting
let skip = module_paths.append("skip_mount"); // Check whether skip mounting
if skip.module().exists() { let skip = paths.append("skip_mount");
continue; if skip.module().exists() {
} continue;
} }
{ drop(skip);
// Double check whether the system folder exists
let sys = module_paths.append("system"); // Double check whether the system folder exists
if sys.module().exists() { let sys = paths.append("system");
info!("{}: loading module files", &info.name); if sys.module().exists() {
system.collect(sys).log_ok(); info!("{}: loading module files", &info.name);
} system.collect(sys).log_ok();
} }
} }
@@ -874,6 +915,9 @@ impl MagiskD {
} }
roots.insert("system", system); roots.insert("system", system);
drop(paths);
let mut paths = MountPaths::new(&mut buf1, &mut buf2);
for (dir, mut root) in roots { for (dir, mut root) in roots {
// Step 4: Convert virtual filesystem tree into concrete operations // Step 4: Convert virtual filesystem tree into concrete operations
// //
@@ -882,8 +926,8 @@ impl MagiskD {
// The "core" of the logic is to decide which directories need to be rebuilt in the // The "core" of the logic is to decide which directories need to be rebuilt in the
// tmpfs worker directory, and real sub-nodes need to be mirrored inside it. // tmpfs worker directory, and real sub-nodes need to be mirrored inside it.
let path = root_paths.append(dir); let paths = paths.append(dir);
root.commit(path, true).log_ok(); root.commit(paths, true).log_ok();
} }
} }
} }