From 2cb0af1ff39e6fae0673bfa1c4ebf250534aa6f9 Mon Sep 17 00:00:00 2001 From: topjohnwu Date: Sat, 30 Mar 2024 02:51:39 -0700 Subject: [PATCH] Move revert_unmount into Rust --- native/src/Android.mk | 3 +-- native/src/core/deny/revert.cpp | 42 -------------------------------- native/src/core/include/core.hpp | 1 - native/src/core/lib.rs | 3 ++- native/src/core/mount.rs | 38 ++++++++++++++++++++++++++++- 5 files changed, 40 insertions(+), 47 deletions(-) delete mode 100644 native/src/core/deny/revert.cpp diff --git a/native/src/Android.mk b/native/src/Android.mk index 165fc627a..4ab294341 100644 --- a/native/src/Android.mk +++ b/native/src/Android.mk @@ -37,8 +37,7 @@ LOCAL_SRC_FILES := \ core/zygisk/module.cpp \ core/zygisk/hook.cpp \ core/deny/cli.cpp \ - core/deny/utils.cpp \ - core/deny/revert.cpp + core/deny/utils.cpp LOCAL_LDLIBS := -llog LOCAL_LDFLAGS := -Wl,--dynamic-list=src/exported_sym.txt diff --git a/native/src/core/deny/revert.cpp b/native/src/core/deny/revert.cpp deleted file mode 100644 index e6c56ebd2..000000000 --- a/native/src/core/deny/revert.cpp +++ /dev/null @@ -1,42 +0,0 @@ -#include -#include - -#include -#include -#include - -#include "deny.hpp" - -using namespace std; - -static void lazy_unmount(const char* mountpoint) { - if (umount2(mountpoint, MNT_DETACH) != -1) - LOGD("denylist: Unmounted (%s)\n", mountpoint); -} - -void revert_unmount() { - set targets; - - // Unmount dummy skeletons and MAGISKTMP - // since mirror nodes are always mounted under skeleton, we don't have to specifically unmount - for (auto &info: parse_mount_info("self")) { - if (info.source == "magisk" || // magisktmp tmpfs - info.root.starts_with("/adb/modules")) { // bind mount from data partition - targets.insert(info.target); - } - } - - if (targets.empty()) return; - - auto last_target = *targets.cbegin() + '/'; - for (auto iter = next(targets.cbegin()); iter != targets.cend();) { - if (iter->starts_with(last_target)) { - iter = targets.erase(iter); - } else { - last_target = *iter++ + '/'; - } - } - - for (auto &s : targets) - lazy_unmount(s.data()); -} diff --git a/native/src/core/include/core.hpp b/native/src/core/include/core.hpp index c68fd52c1..ee42eb80a 100644 --- a/native/src/core/include/core.hpp +++ b/native/src/core/include/core.hpp @@ -91,4 +91,3 @@ extern std::atomic denylist_enforced; int denylist_cli(int argc, char **argv); void initialize_denylist(); bool is_deny_target(int uid, std::string_view process); -void revert_unmount(); diff --git a/native/src/core/lib.rs b/native/src/core/lib.rs index c6d1232c5..67a69ac7c 100644 --- a/native/src/core/lib.rs +++ b/native/src/core/lib.rs @@ -8,7 +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 mount::{find_preinit_device, revert_unmount, setup_mounts}; use resetprop::{persist_delete_prop, persist_get_prop, persist_get_props, persist_set_prop}; mod cert; @@ -90,6 +90,7 @@ pub mod ffi { fn read_certificate(fd: i32, version: i32) -> Vec; fn setup_mounts(); fn find_preinit_device() -> String; + fn revert_unmount(); 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; diff --git a/native/src/core/mount.rs b/native/src/core/mount.rs index 9d15ac7a6..36ecbb72c 100644 --- a/native/src/core/mount.rs +++ b/native/src/core/mount.rs @@ -1,4 +1,4 @@ -use std::path::Path; +use std::path::{Path, PathBuf}; use std::ptr; use num_traits::AsPrimitive; @@ -274,3 +274,39 @@ pub fn find_preinit_device() -> String { .unwrap() .to_string() } + +pub fn revert_unmount() { + let mut targets = Vec::new(); + + // Unmount Magisk tmpfs and mounts from module files + for info in parse_mount_info("self") { + if info.source == "magisk" || info.root.starts_with("/adb/modules") { + targets.push(info.target); + } + } + + if targets.is_empty() { + return; + } + + let mut prev: Option = None; + targets.sort(); + targets.retain(|target| { + if let Some(prev) = &prev { + if Path::new(target).starts_with(prev) { + return false; + } + } + prev = Some(PathBuf::from(target.clone())); + true + }); + + for mut target in targets { + let target = Utf8CStr::from_string(&mut target); + unsafe { + if libc::umount2(target.as_ptr(), libc::MNT_DETACH) == 0 { + debug!("denylist: Unmounted ({})", target); + } + } + } +}