You've already forked ReZygisk
mirror of
https://github.com/PerformanC/ReZygisk.git
synced 2025-09-06 06:37:01 +00:00
Implement revert_unmount_magisk
This commit is contained in:
122
loader/src/injector/files.cpp
Normal file
122
loader/src/injector/files.cpp
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
#include <sys/sysmacros.h>
|
||||||
|
|
||||||
|
#include "files.hpp"
|
||||||
|
#include "misc.hpp"
|
||||||
|
|
||||||
|
using namespace std::string_view_literals;
|
||||||
|
|
||||||
|
void file_readline(bool trim, FILE *fp, const std::function<bool(std::string_view)> &fn) {
|
||||||
|
size_t len = 1024;
|
||||||
|
char *buf = (char *) malloc(len);
|
||||||
|
char *start;
|
||||||
|
ssize_t read;
|
||||||
|
while ((read = getline(&buf, &len, fp)) >= 0) {
|
||||||
|
start = buf;
|
||||||
|
if (trim) {
|
||||||
|
while (read && "\n\r "sv.find(buf[read - 1]) != std::string::npos)
|
||||||
|
--read;
|
||||||
|
buf[read] = '\0';
|
||||||
|
while (*start == ' ')
|
||||||
|
++start;
|
||||||
|
}
|
||||||
|
if (!fn(start))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
free(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
void file_readline(bool trim, const char *file, const std::function<bool(std::string_view)> &fn) {
|
||||||
|
if (auto fp = open_file(file, "re"))
|
||||||
|
file_readline(trim, fp.get(), fn);
|
||||||
|
}
|
||||||
|
void file_readline(const char *file, const std::function<bool(std::string_view)> &fn) {
|
||||||
|
file_readline(false, file, fn);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<mount_info> parse_mount_info(const char *pid) {
|
||||||
|
char buf[PATH_MAX] = {};
|
||||||
|
snprintf(buf, sizeof(buf), "/proc/%s/mountinfo", pid);
|
||||||
|
std::vector<mount_info> result;
|
||||||
|
|
||||||
|
file_readline(buf, [&result](std::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) {
|
||||||
|
return sDIR(dp, [](DIR *dp){ return dp ? closedir(dp) : 1; });
|
||||||
|
}
|
||||||
|
|
||||||
|
sFILE make_file(FILE *fp) {
|
||||||
|
return sFILE(fp, [](FILE *fp){ return fp ? fclose(fp) : 1; });
|
||||||
|
}
|
||||||
56
loader/src/injector/files.hpp
Normal file
56
loader/src/injector/files.hpp
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
#include <dirent.h>
|
||||||
|
#include <functional>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
|
void file_readline(bool trim, FILE *fp, const std::function<bool(std::string_view)> &fn);
|
||||||
|
void file_readline(bool trim, const char *file, const std::function<bool(std::string_view)> &fn);
|
||||||
|
void file_readline(const char *file, const std::function<bool(std::string_view)> &fn);
|
||||||
|
|
||||||
|
std::vector<mount_info> parse_mount_info(const char *pid);
|
||||||
|
|
||||||
|
using sFILE = std::unique_ptr<FILE, decltype(&fclose)>;
|
||||||
|
using sDIR = std::unique_ptr<DIR, decltype(&closedir)>;
|
||||||
|
sDIR make_dir(DIR *dp);
|
||||||
|
sFILE make_file(FILE *fp);
|
||||||
|
|
||||||
|
static inline sDIR open_dir(const char *path) {
|
||||||
|
return make_dir(opendir(path));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline sDIR xopen_dir(const char *path) {
|
||||||
|
return make_dir(opendir(path));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline sDIR xopen_dir(int dirfd) {
|
||||||
|
return make_dir(fdopendir(dirfd));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline sFILE open_file(const char *path, const char *mode) {
|
||||||
|
return make_file(fopen(path, mode));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline sFILE xopen_file(const char *path, const char *mode) {
|
||||||
|
return make_file(fopen(path, mode));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline sFILE xopen_file(int fd, const char *mode) {
|
||||||
|
return make_file(fdopen(fd, mode));
|
||||||
|
}
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
#include "zygisk.hpp"
|
#include "zygisk.hpp"
|
||||||
#include "memory.hpp"
|
#include "memory.hpp"
|
||||||
#include "module.hpp"
|
#include "module.hpp"
|
||||||
#include "misc.hpp"
|
#include "files.hpp"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using jni_hook::hash_map;
|
using jni_hook::hash_map;
|
||||||
@@ -219,7 +219,11 @@ DCL_HOOK_FUNC(int, unshare, int flags) {
|
|||||||
// Simply avoid doing any unmounts for SysUI to avoid potential issues.
|
// Simply avoid doing any unmounts for SysUI to avoid potential issues.
|
||||||
(g_ctx->info_flags & PROCESS_IS_SYS_UI) == 0) {
|
(g_ctx->info_flags & PROCESS_IS_SYS_UI) == 0) {
|
||||||
if (g_ctx->flags[DO_REVERT_UNMOUNT]) {
|
if (g_ctx->flags[DO_REVERT_UNMOUNT]) {
|
||||||
revert_unmount();
|
if (g_ctx->info_flags & PROCESS_ROOT_IS_KSU) {
|
||||||
|
revert_unmount_ksu();
|
||||||
|
} else if (g_ctx->info_flags & PROCESS_ROOT_IS_MAGISK) {
|
||||||
|
revert_unmount_magisk();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Zygisksu changed: No umount app_process */
|
/* Zygisksu changed: No umount app_process */
|
||||||
|
|||||||
@@ -23,17 +23,6 @@ int parse_int(std::string_view s) {
|
|||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
void parse_mnt(const char* file, const std::function<void(mntent*)>& fn) {
|
|
||||||
auto fp = sFILE(setmntent(file, "re"), endmntent);
|
|
||||||
if (fp) {
|
|
||||||
mntent mentry{};
|
|
||||||
char buf[PATH_MAX];
|
|
||||||
while (getmntent_r(fp.get(), &mentry, buf, sizeof(buf))) {
|
|
||||||
fn(&mentry);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::list<std::string> split_str(std::string_view s, std::string_view delimiter) {
|
std::list<std::string> split_str(std::string_view s, std::string_view delimiter) {
|
||||||
std::list<std::string> ret;
|
std::list<std::string> ret;
|
||||||
size_t pos = 0;
|
size_t pos = 0;
|
||||||
@@ -58,11 +47,3 @@ std::string join_str(const std::list<std::string>& list, std::string_view delimi
|
|||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
sDIR make_dir(DIR *dp) {
|
|
||||||
return sDIR(dp, [](DIR *dp){ return dp ? closedir(dp) : 1; });
|
|
||||||
}
|
|
||||||
|
|
||||||
sFILE make_file(FILE *fp) {
|
|
||||||
return sFILE(fp, [](FILE *fp){ return fp ? fclose(fp) : 1; });
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,12 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <dirent.h>
|
|
||||||
#include <functional>
|
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <mntent.h>
|
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <stdio.h>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
|
|
||||||
@@ -39,12 +35,6 @@ int new_daemon_thread(thread_entry entry, void *arg);
|
|||||||
static inline bool str_contains(std::string_view s, std::string_view ss) {
|
static inline bool str_contains(std::string_view s, std::string_view ss) {
|
||||||
return s.find(ss) != std::string_view::npos;
|
return s.find(ss) != std::string_view::npos;
|
||||||
}
|
}
|
||||||
static inline bool str_starts(std::string_view s, std::string_view ss) {
|
|
||||||
return s.size() >= ss.size() && s.compare(0, ss.size(), ss) == 0;
|
|
||||||
}
|
|
||||||
static inline bool str_ends(std::string_view s, std::string_view ss) {
|
|
||||||
return s.size() >= ss.size() && s.compare(s.size() - ss.size(), std::string_view::npos, ss) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T, typename Impl>
|
template<typename T, typename Impl>
|
||||||
class stateless_allocator {
|
class stateless_allocator {
|
||||||
@@ -61,35 +51,6 @@ public:
|
|||||||
bool operator!=(const stateless_allocator&) { return false; }
|
bool operator!=(const stateless_allocator&) { return false; }
|
||||||
};
|
};
|
||||||
|
|
||||||
using sFILE = std::unique_ptr<FILE, decltype(&fclose)>;
|
|
||||||
using sDIR = std::unique_ptr<DIR, decltype(&closedir)>;
|
|
||||||
sDIR make_dir(DIR *dp);
|
|
||||||
sFILE make_file(FILE *fp);
|
|
||||||
|
|
||||||
static inline sDIR open_dir(const char *path) {
|
|
||||||
return make_dir(opendir(path));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline sDIR xopen_dir(const char *path) {
|
|
||||||
return make_dir(opendir(path));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline sDIR xopen_dir(int dirfd) {
|
|
||||||
return make_dir(fdopendir(dirfd));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline sFILE open_file(const char *path, const char *mode) {
|
|
||||||
return make_file(fopen(path, mode));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline sFILE xopen_file(const char *path, const char *mode) {
|
|
||||||
return make_file(fopen(path, mode));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline sFILE xopen_file(int fd, const char *mode) {
|
|
||||||
return make_file(fdopen(fd, mode));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class reversed_container {
|
class reversed_container {
|
||||||
public:
|
public:
|
||||||
@@ -126,8 +87,6 @@ struct StringCmp {
|
|||||||
*/
|
*/
|
||||||
int parse_int(std::string_view s);
|
int parse_int(std::string_view s);
|
||||||
|
|
||||||
void parse_mnt(const char* file, const std::function<void(mntent*)>& fn);
|
|
||||||
|
|
||||||
std::list<std::string> split_str(std::string_view s, std::string_view delimiter);
|
std::list<std::string> split_str(std::string_view s, std::string_view delimiter);
|
||||||
|
|
||||||
std::string join_str(const std::list<std::string>& list, std::string_view delimiter);
|
std::string join_str(const std::list<std::string>& list, std::string_view delimiter);
|
||||||
|
|||||||
@@ -111,6 +111,8 @@ namespace {
|
|||||||
PROCESS_GRANTED_ROOT = zygisk::StateFlag::PROCESS_GRANTED_ROOT,
|
PROCESS_GRANTED_ROOT = zygisk::StateFlag::PROCESS_GRANTED_ROOT,
|
||||||
PROCESS_ON_DENYLIST = zygisk::StateFlag::PROCESS_ON_DENYLIST,
|
PROCESS_ON_DENYLIST = zygisk::StateFlag::PROCESS_ON_DENYLIST,
|
||||||
|
|
||||||
|
PROCESS_ROOT_IS_KSU = (1u << 29),
|
||||||
|
PROCESS_ROOT_IS_MAGISK = (1u << 30),
|
||||||
PROCESS_IS_SYS_UI = (1u << 31),
|
PROCESS_IS_SYS_UI = (1u << 31),
|
||||||
|
|
||||||
PRIVATE_MASK = PROCESS_IS_SYS_UI
|
PRIVATE_MASK = PROCESS_IS_SYS_UI
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
|
#include <mntent.h>
|
||||||
#include <sys/mount.h>
|
#include <sys/mount.h>
|
||||||
|
|
||||||
|
#include "files.hpp"
|
||||||
#include "logging.h"
|
#include "logging.h"
|
||||||
#include "misc.hpp"
|
#include "misc.hpp"
|
||||||
#include "zygisk.hpp"
|
#include "zygisk.hpp"
|
||||||
@@ -7,7 +9,13 @@
|
|||||||
using namespace std::string_view_literals;
|
using namespace std::string_view_literals;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
constexpr auto KSU_MODULE_DIR = "/data/adb/ksu/modules"sv;
|
constexpr auto KSU_MODULE_DIR = "/data/adb/ksu/modules";
|
||||||
|
|
||||||
|
struct overlay_backup {
|
||||||
|
std::string target;
|
||||||
|
std::string vfs_option;
|
||||||
|
std::string fs_option;
|
||||||
|
};
|
||||||
|
|
||||||
void lazy_unmount(const char* mountpoint) {
|
void lazy_unmount(const char* mountpoint) {
|
||||||
if (umount2(mountpoint, MNT_DETACH) != -1) {
|
if (umount2(mountpoint, MNT_DETACH) != -1) {
|
||||||
@@ -24,37 +32,44 @@ namespace {
|
|||||||
return true; \
|
return true; \
|
||||||
}
|
}
|
||||||
|
|
||||||
void revert_unmount() {
|
void revert_unmount_ksu() {
|
||||||
std::string ksu_loop;
|
std::string ksu_loop;
|
||||||
std::vector<std::string> targets;
|
std::vector<std::string> targets;
|
||||||
std::list<std::pair<std::string, std::string>> backups;
|
std::list<overlay_backup> backups;
|
||||||
|
|
||||||
// Unmount ksu module dir last
|
// Unmount ksu module dir last
|
||||||
targets.emplace_back(KSU_MODULE_DIR);
|
targets.emplace_back(KSU_MODULE_DIR);
|
||||||
parse_mnt("/proc/self/mounts", [&](mntent* mentry) {
|
|
||||||
if (mentry->mnt_dir == KSU_MODULE_DIR) {
|
for (auto& info: parse_mount_info("self")) {
|
||||||
ksu_loop = mentry->mnt_fsname;
|
if (info.target == KSU_MODULE_DIR) {
|
||||||
return;
|
ksu_loop = info.source;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
// Unmount everything on /data/adb except ksu module dir
|
// Unmount everything on /data/adb except ksu module dir
|
||||||
if (str_starts(mentry->mnt_dir, "/data/adb")) {
|
if (info.target.starts_with("/data/adb")) {
|
||||||
targets.emplace_back(mentry->mnt_dir);
|
targets.emplace_back(info.target);
|
||||||
}
|
}
|
||||||
// Unmount ksu overlays
|
// Unmount ksu overlays
|
||||||
if (mentry->mnt_type == "overlay"sv) {
|
if (info.type == "overlay") {
|
||||||
if (str_contains(mentry->mnt_opts, KSU_MODULE_DIR)) {
|
LOGV("Overlay: %s (%s)", info.target.data(), info.fs_option.data());
|
||||||
targets.emplace_back(mentry->mnt_dir);
|
if (str_contains(info.fs_option, KSU_MODULE_DIR)) {
|
||||||
|
targets.emplace_back(info.target);
|
||||||
} else {
|
} else {
|
||||||
backups.emplace_back(mentry->mnt_dir, mentry->mnt_opts);
|
auto backup = overlay_backup{
|
||||||
|
.target = info.target,
|
||||||
|
.vfs_option = info.vfs_option,
|
||||||
|
.fs_option = info.fs_option,
|
||||||
|
};
|
||||||
|
backups.emplace_back(backup);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
// Unmount everything from ksu loop except ksu module dir
|
for (auto& info: parse_mount_info("self")) {
|
||||||
parse_mnt("/proc/self/mounts", [&](mntent* mentry) {
|
// Unmount everything from ksu loop except ksu module dir
|
||||||
if (mentry->mnt_fsname == ksu_loop && mentry->mnt_dir != KSU_MODULE_DIR) {
|
if (info.source == ksu_loop && info.target != KSU_MODULE_DIR) {
|
||||||
targets.emplace_back(mentry->mnt_dir);
|
targets.emplace_back(info.target);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
// Do unmount
|
// Do unmount
|
||||||
for (auto& s: reversed(targets)) {
|
for (auto& s: reversed(targets)) {
|
||||||
@@ -62,18 +77,18 @@ void revert_unmount() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Affirm unmounted system overlays
|
// Affirm unmounted system overlays
|
||||||
parse_mnt("/proc/self/mounts", [&](mntent* mentry) {
|
for (auto& info: parse_mount_info("self")) {
|
||||||
if (mentry->mnt_type == "overlay"sv) {
|
if (info.type == "overlay") {
|
||||||
backups.remove_if([&](auto& mnt) {
|
backups.remove_if([&](overlay_backup& mnt) {
|
||||||
return mnt.first == mentry->mnt_dir && mnt.second == mentry->mnt_opts;
|
return mnt.target == info.target && mnt.fs_option == info.fs_option;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return true;
|
}
|
||||||
});
|
|
||||||
|
|
||||||
// Restore system overlays
|
// Restore system overlays
|
||||||
for (auto& mnt: backups) {
|
for (auto& mnt: backups) {
|
||||||
auto opts = split_str(mnt.second, ",");
|
auto opts = split_str(mnt.vfs_option, ",");
|
||||||
|
opts.splice(opts.end(), split_str(mnt.fs_option, ","));
|
||||||
unsigned long flags = 0;
|
unsigned long flags = 0;
|
||||||
opts.remove_if([&](auto& opt) {
|
opts.remove_if([&](auto& opt) {
|
||||||
PARSE_OPT(MNTOPT_RO, MS_RDONLY)
|
PARSE_OPT(MNTOPT_RO, MS_RDONLY)
|
||||||
@@ -82,10 +97,27 @@ void revert_unmount() {
|
|||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
auto mnt_data = join_str(opts, ",");
|
auto mnt_data = join_str(opts, ",");
|
||||||
if (mount("overlay", mnt.first.data(), "overlay", flags, mnt_data.data()) != -1) {
|
if (mount("overlay", mnt.target.data(), "overlay", flags, mnt_data.data()) != -1) {
|
||||||
LOGD("Remounted (%s)", mnt.first.data());
|
LOGD("Remounted (%s)", mnt.target.data());
|
||||||
} else {
|
} else {
|
||||||
PLOGE("Remount (%s, %s)", mnt.first.data(), mnt_data.data());
|
PLOGE("Remount (%s, %s)", mnt.target.data(), mnt.fs_option.data());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void revert_unmount_magisk() {
|
||||||
|
std::vector<std::string> 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" || info.source == "worker" || // magisktmp tmpfs
|
||||||
|
info.root.starts_with("/adb/modules")) { // bind mount from data partition
|
||||||
|
targets.push_back(info.target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& s: targets) {
|
||||||
|
lazy_unmount(s.data());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -8,4 +8,7 @@ extern void *self_handle;
|
|||||||
|
|
||||||
void hook_functions();
|
void hook_functions();
|
||||||
|
|
||||||
void revert_unmount();
|
void revert_unmount_ksu();
|
||||||
|
|
||||||
|
void revert_unmount_magisk();
|
||||||
|
|
||||||
|
|||||||
@@ -51,4 +51,6 @@ pub enum DaemonSocketAction {
|
|||||||
// Zygisk process flags
|
// Zygisk process flags
|
||||||
pub const PROCESS_GRANTED_ROOT: u32 = 1 << 0;
|
pub const PROCESS_GRANTED_ROOT: u32 = 1 << 0;
|
||||||
pub const PROCESS_ON_DENYLIST: u32 = 1 << 1;
|
pub const PROCESS_ON_DENYLIST: u32 = 1 << 1;
|
||||||
|
pub const PROCESS_ROOT_IS_KSU: u32 = 1 << 29;
|
||||||
|
pub const PROCESS_ROOT_IS_MAGISK: u32 = 1 << 30;
|
||||||
pub const PROCESS_IS_SYSUI: u32 = 1 << 31;
|
pub const PROCESS_IS_SYSUI: u32 = 1 << 31;
|
||||||
|
|||||||
@@ -201,6 +201,11 @@ fn handle_daemon_action(mut stream: UnixStream, context: &Context) -> Result<()>
|
|||||||
if root_impl::uid_on_denylist(uid) {
|
if root_impl::uid_on_denylist(uid) {
|
||||||
flags |= constants::PROCESS_ON_DENYLIST;
|
flags |= constants::PROCESS_ON_DENYLIST;
|
||||||
}
|
}
|
||||||
|
match root_impl::get_impl() {
|
||||||
|
root_impl::RootImpl::KernelSU => flags |= constants::PROCESS_ROOT_IS_KSU,
|
||||||
|
root_impl::RootImpl::Magisk => flags |= constants::PROCESS_ROOT_IS_MAGISK,
|
||||||
|
_ => ()
|
||||||
|
}
|
||||||
// TODO: PROCESS_IS_SYSUI?
|
// TODO: PROCESS_IS_SYSUI?
|
||||||
stream.write_u32(flags)?;
|
stream.write_u32(flags)?;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user