mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-11-27 20:15:29 +00:00
Use mountinfo for revert unmount
This commit is contained in:
parent
b249832571
commit
79a85f5937
@ -1,10 +1,12 @@
|
|||||||
#include <sys/sendfile.h>
|
#include <sys/sendfile.h>
|
||||||
|
#include <sys/sysmacros.h>
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <libgen.h>
|
#include <libgen.h>
|
||||||
|
|
||||||
#include <base.hpp>
|
#include <base.hpp>
|
||||||
|
#include <misc.hpp>
|
||||||
#include <selinux.hpp>
|
#include <selinux.hpp>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
@ -382,6 +384,86 @@ void parse_mnt(const char *file, const function<bool(mntent*)> &fn) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<mount_info> parse_mount_info(const char *pid) {
|
||||||
|
char buf[PATH_MAX] = {};
|
||||||
|
ssprintf(buf, sizeof(buf), "/proc/%s/mountinfo", pid);
|
||||||
|
std::vector<mount_info> result;
|
||||||
|
|
||||||
|
file_readline(buf, [&result](string_view line) -> bool {
|
||||||
|
int root_start = 0, root_end = 0;
|
||||||
|
int target_start = 0, target_end = 0;
|
||||||
|
int vfs_option_start = 0, vfs_option_end = 0;
|
||||||
|
int type_start = 0, type_end = 0;
|
||||||
|
int source_start = 0, source_end = 0;
|
||||||
|
int fs_option_start = 0, fs_option_end = 0;
|
||||||
|
int optional_start = 0, optional_end = 0;
|
||||||
|
unsigned int id, parent, maj, min;
|
||||||
|
sscanf(line.data(),
|
||||||
|
"%u " // (1) id
|
||||||
|
"%u " // (2) parent
|
||||||
|
"%u:%u " // (3) maj:min
|
||||||
|
"%n%*s%n " // (4) mountroot
|
||||||
|
"%n%*s%n " // (5) target
|
||||||
|
"%n%*s%n" // (6) vfs options (fs-independent)
|
||||||
|
"%n%*[^-]%n - " // (7) optional fields
|
||||||
|
"%n%*s%n " // (8) FS type
|
||||||
|
"%n%*s%n " // (9) source
|
||||||
|
"%n%*s%n", // (10) fs options (fs specific)
|
||||||
|
&id, &parent, &maj, &min, &root_start, &root_end, &target_start,
|
||||||
|
&target_end, &vfs_option_start, &vfs_option_end,
|
||||||
|
&optional_start, &optional_end, &type_start, &type_end,
|
||||||
|
&source_start, &source_end, &fs_option_start, &fs_option_end);
|
||||||
|
|
||||||
|
auto root = line.substr(root_start, root_end - root_start);
|
||||||
|
auto target = line.substr(target_start, target_end - target_start);
|
||||||
|
auto vfs_option =
|
||||||
|
line.substr(vfs_option_start, vfs_option_end - vfs_option_start);
|
||||||
|
++optional_start;
|
||||||
|
--optional_end;
|
||||||
|
auto optional = line.substr(
|
||||||
|
optional_start,
|
||||||
|
optional_end - optional_start > 0 ? optional_end - optional_start : 0);
|
||||||
|
|
||||||
|
auto type = line.substr(type_start, type_end - type_start);
|
||||||
|
auto source = line.substr(source_start, source_end - source_start);
|
||||||
|
auto fs_option =
|
||||||
|
line.substr(fs_option_start, fs_option_end - fs_option_start);
|
||||||
|
|
||||||
|
unsigned int shared = 0;
|
||||||
|
unsigned int master = 0;
|
||||||
|
unsigned int propagate_from = 0;
|
||||||
|
if (auto pos = optional.find("shared:"); pos != std::string_view::npos) {
|
||||||
|
shared = parse_int(optional.substr(pos + 7));
|
||||||
|
}
|
||||||
|
if (auto pos = optional.find("master:"); pos != std::string_view::npos) {
|
||||||
|
master = parse_int(optional.substr(pos + 7));
|
||||||
|
}
|
||||||
|
if (auto pos = optional.find("propagate_from:");
|
||||||
|
pos != std::string_view::npos) {
|
||||||
|
propagate_from = parse_int(optional.substr(pos + 15));
|
||||||
|
}
|
||||||
|
|
||||||
|
result.emplace_back(mount_info {
|
||||||
|
.id = id,
|
||||||
|
.parent = parent,
|
||||||
|
.device = static_cast<dev_t>(makedev(maj, min)),
|
||||||
|
.root {root},
|
||||||
|
.target {target},
|
||||||
|
.vfs_option {vfs_option},
|
||||||
|
.optional {
|
||||||
|
.shared = shared,
|
||||||
|
.master = master,
|
||||||
|
.propagate_from = propagate_from,
|
||||||
|
},
|
||||||
|
.type {type},
|
||||||
|
.source {source},
|
||||||
|
.fs_option {fs_option},
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
sDIR make_dir(DIR *dp) {
|
sDIR make_dir(DIR *dp) {
|
||||||
return sDIR(dp, [](DIR *dp){ return dp ? closedir(dp) : 1; });
|
return sDIR(dp, [](DIR *dp){ return dp ? closedir(dp) : 1; });
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,23 @@ protected:
|
|||||||
void swap(byte_data &o);
|
void swap(byte_data &o);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct mount_info {
|
||||||
|
unsigned int id;
|
||||||
|
unsigned int parent;
|
||||||
|
dev_t device;
|
||||||
|
std::string root;
|
||||||
|
std::string target;
|
||||||
|
std::string vfs_option;
|
||||||
|
struct {
|
||||||
|
unsigned int shared;
|
||||||
|
unsigned int master;
|
||||||
|
unsigned int propagate_from;
|
||||||
|
} optional;
|
||||||
|
std::string type;
|
||||||
|
std::string source;
|
||||||
|
std::string fs_option;
|
||||||
|
};
|
||||||
|
|
||||||
struct mmap_data : public byte_data {
|
struct mmap_data : public byte_data {
|
||||||
mmap_data() = default;
|
mmap_data() = default;
|
||||||
mmap_data(const mmap_data&) = delete;
|
mmap_data(const mmap_data&) = delete;
|
||||||
@ -88,6 +105,7 @@ void parse_prop_file(const char *file,
|
|||||||
const std::function<bool(std::string_view, std::string_view)> &fn);
|
const std::function<bool(std::string_view, std::string_view)> &fn);
|
||||||
void frm_rf(int dirfd);
|
void frm_rf(int dirfd);
|
||||||
void clone_dir(int src, int dest);
|
void clone_dir(int src, int dest);
|
||||||
|
std::vector<mount_info> parse_mount_info(const char *pid);
|
||||||
void parse_mnt(const char *file, const std::function<bool(mntent*)> &fn);
|
void parse_mnt(const char *file, const std::function<bool(mntent*)> &fn);
|
||||||
std::string find_apk_path(const char *pkg);
|
std::string find_apk_path(const char *pkg);
|
||||||
|
|
||||||
|
@ -12,30 +12,19 @@ static void lazy_unmount(const char* mountpoint) {
|
|||||||
LOGD("denylist: Unmounted (%s)\n", mountpoint);
|
LOGD("denylist: Unmounted (%s)\n", mountpoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define TMPFS_MNT(dir) (mentry->mnt_type == "tmpfs"sv && str_starts(mentry->mnt_dir, "/" #dir))
|
|
||||||
|
|
||||||
void revert_unmount() {
|
void revert_unmount() {
|
||||||
vector<string> targets;
|
vector<string> targets;
|
||||||
|
|
||||||
// Unmount dummy skeletons and MAGISKTMP
|
// Unmount dummy skeletons and MAGISKTMP
|
||||||
targets.push_back(MAGISKTMP);
|
// since mirror nodes are always mounted under skeleton, we don't have to specifically unmount
|
||||||
parse_mnt("/proc/self/mounts", [&](mntent *mentry) {
|
for (auto &info: parse_mount_info("self")) {
|
||||||
if (TMPFS_MNT(system) || TMPFS_MNT(vendor) || TMPFS_MNT(product) || TMPFS_MNT(system_ext))
|
if (info.target.starts_with(MAGISKTMP) || // things in magisktmp
|
||||||
targets.emplace_back(mentry->mnt_dir);
|
info.root.starts_with("/adb/modules") || // module nodes
|
||||||
return true;
|
info.root.starts_with("/" INTLROOT)) { // skeleton
|
||||||
});
|
targets.push_back(info.target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (auto &s : reversed(targets))
|
for (auto &s : targets)
|
||||||
lazy_unmount(s.data());
|
|
||||||
targets.clear();
|
|
||||||
|
|
||||||
// Unmount all Magisk created mounts
|
|
||||||
parse_mnt("/proc/self/mounts", [&](mntent *mentry) {
|
|
||||||
if (str_contains(mentry->mnt_fsname, BLOCKDIR))
|
|
||||||
targets.emplace_back(mentry->mnt_dir);
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
for (auto &s : reversed(targets))
|
|
||||||
lazy_unmount(s.data());
|
lazy_unmount(s.data());
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user