Refine unmount

This commit is contained in:
Nullptr
2023-02-18 19:14:15 +08:00
parent e69aa5c527
commit 57d3d8a0ba
13 changed files with 168 additions and 34 deletions

View File

@@ -58,6 +58,17 @@ namespace zygiskd {
return socket_utils::read_string(fd);
}
uint32_t GetProcessFlags(uid_t uid) {
UniqueFd fd = Connect(1);
if (fd == -1) {
PLOGE("GetProcessFlags");
return 0;
}
socket_utils::write_u8(fd, (uint8_t) SocketAction::GetProcessFlags);
socket_utils::write_u32(fd, uid);
return socket_utils::read_u32(fd);
}
std::vector<Module> ReadModules() {
std::vector<Module> modules;
UniqueFd fd = Connect(1);

View File

@@ -90,6 +90,10 @@ namespace socket_utils {
return read_exact_or<uint8_t>(fd, 0);
}
uint32_t read_u32(int fd) {
return read_exact_or<uint32_t>(fd, 0);
}
size_t read_usize(int fd) {
return read_exact_or<size_t>(fd, 0);
}
@@ -110,6 +114,10 @@ namespace socket_utils {
return write_exact<uint8_t>(fd, val);
}
bool write_u32(int fd, uint32_t val) {
return write_exact<uint32_t>(fd, val);
}
bool write_string(int fd, std::string_view str) {
return write_usize(fd, str.size()) && str.size() == xwrite(fd, str.data(), str.size());
}

View File

@@ -54,6 +54,7 @@ namespace zygiskd {
PingHeartBeat,
RequestLogcatFd,
ReadNativeBridge,
GetProcessFlags,
ReadModules,
RequestCompanionSocket,
GetModuleDir,
@@ -67,6 +68,8 @@ namespace zygiskd {
std::vector<Module> ReadModules();
uint32_t GetProcessFlags(uid_t uid);
int ConnectCompanion(size_t index);
int GetModuleDir(size_t index);

View File

@@ -13,12 +13,16 @@ namespace socket_utils {
uint8_t read_u8(int fd);
uint32_t read_u32(int fd);
size_t read_usize(int fd);
std::string read_string(int fd);
bool write_u8(int fd, uint8_t val);
bool write_u32(int fd, uint32_t val);
int recv_fd(int fd);
bool write_usize(int fd, size_t val);

View File

@@ -1,22 +0,0 @@
#include <sys/mount.h>
#include "logging.h"
#include "misc.hpp"
#include "zygisk.hpp"
using namespace std::string_view_literals;
static void lazy_unmount(const char* mountpoint) {
if (umount2(mountpoint, MNT_DETACH) != -1)
LOGD("Unmounted (%s)", mountpoint);
}
void revert_unmount() {
parse_mnt("/proc/self/mounts", [](mntent* mentry) {
if (mentry->mnt_fsname == "/data/adb/ksu/modules"sv ||
std::string_view(mentry->mnt_opts).find("/data/adb/ksu/modules") != std::string_view::npos) {
lazy_unmount(mentry->mnt_fsname);
}
return true;
});
}

View File

@@ -566,15 +566,13 @@ void HookContext::run_modules_post() {
/* Zygisksu changed: Load module fds */
void HookContext::app_specialize_pre() {
flags[APP_SPECIALIZE] = true;
info_flags = zygiskd::GetProcessFlags(g_ctx->args.app->uid);
run_modules_pre();
}
void HookContext::app_specialize_post() {
run_modules_post();
if (info_flags & PROCESS_IS_MAGISK_APP) {
setenv("ZYGISK_ENABLED", "1", 1);
}
// Cleanups
env->ReleaseStringUTFChars(args.app->nice_name, process);

View File

@@ -35,6 +35,31 @@ void parse_mnt(const char* file, const std::function<bool(mntent*)>& fn) {
}
}
std::list<std::string> split_str(std::string_view s, std::string_view delimiter) {
std::list<std::string> ret;
size_t pos = 0;
while (pos < s.size()) {
auto next = s.find(delimiter, pos);
if (next == std::string_view::npos) {
ret.emplace_back(s.substr(pos));
break;
}
ret.emplace_back(s.substr(pos, next - pos));
pos = next + delimiter.size();
}
return ret;
}
std::string join_str(const std::list<std::string>& list, std::string_view delimiter) {
std::string ret;
for (auto& s : list) {
if (!ret.empty())
ret += delimiter;
ret += s;
}
return ret;
}
sDIR make_dir(DIR *dp) {
return sDIR(dp, [](DIR *dp){ return dp ? closedir(dp) : 1; });
}

View File

@@ -2,10 +2,12 @@
#include <dirent.h>
#include <functional>
#include <list>
#include <memory>
#include <mntent.h>
#include <pthread.h>
#include <stdio.h>
#include <string>
#include <string_view>
#include "logging.h"
@@ -34,6 +36,16 @@ private:
using thread_entry = void *(*)(void *);
int new_daemon_thread(thread_entry entry, void *arg);
static inline bool str_contains(std::string_view s, std::string_view ss) {
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>
class stateless_allocator {
public:
@@ -78,6 +90,25 @@ static inline sFILE xopen_file(int fd, const char *mode) {
return make_file(fdopen(fd, mode));
}
template <typename T>
class reversed_container {
public:
reversed_container(T &base) : base(base) {}
decltype(std::declval<T>().rbegin()) begin() { return base.rbegin(); }
decltype(std::declval<T>().crbegin()) begin() const { return base.crbegin(); }
decltype(std::declval<T>().crbegin()) cbegin() const { return base.crbegin(); }
decltype(std::declval<T>().rend()) end() { return base.rend(); }
decltype(std::declval<T>().crend()) end() const { return base.crend(); }
decltype(std::declval<T>().crend()) cend() const { return base.crend(); }
private:
T &base;
};
template <typename T>
reversed_container<T> reversed(T &base) {
return reversed_container<T>(base);
}
template<class T>
static inline void default_new(T *&p) { p = new T(); }
@@ -97,6 +128,10 @@ int parse_int(std::string_view s);
void parse_mnt(const char* file, const std::function<bool(mntent*)>& fn);
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);
template <typename T>
static inline T align_to(T v, int a) {
static_assert(std::is_integral<T>::value);

View File

@@ -111,12 +111,10 @@ namespace {
PROCESS_GRANTED_ROOT = zygisk::StateFlag::PROCESS_GRANTED_ROOT,
PROCESS_ON_DENYLIST = zygisk::StateFlag::PROCESS_ON_DENYLIST,
PROCESS_IS_SYS_UI = (1u << 29),
DENYLIST_ENFORCING = (1u << 30),
PROCESS_IS_MAGISK_APP = (1u << 31),
PROCESS_IS_SYS_UI = (1u << 30),
PROCESS_IS_KSU_APP = (1u << 31),
UNMOUNT_MASK = (PROCESS_ON_DENYLIST | DENYLIST_ENFORCING),
PRIVATE_MASK = (PROCESS_IS_SYS_UI | DENYLIST_ENFORCING | PROCESS_IS_MAGISK_APP)
PRIVATE_MASK = (PROCESS_IS_SYS_UI | PROCESS_IS_KSU_APP)
};
struct api_abi_base {

View File

@@ -0,0 +1,73 @@
#include <sys/mount.h>
#include "logging.h"
#include "misc.hpp"
#include "zygisk.hpp"
using namespace std::string_view_literals;
static void lazy_unmount(const char* mountpoint) {
if (umount2(mountpoint, MNT_DETACH) != -1) {
LOGD("Unmounted (%s)", mountpoint);
} else {
PLOGE("Failed to unmount: %s (%s)", strerror(errno), mountpoint);
}
}
#define PARSE_OPT(name, flag) \
if (opt == name) { \
flags |= (flag); \
return true; \
}
void revert_unmount() {
std::vector<std::string> targets;
std::list<std::pair<std::string, std::string>> backups;
targets.emplace_back("/data/adb/ksu/modules");
parse_mnt("/proc/self/mounts", [&](mntent* mentry) {
if (str_starts(mentry->mnt_fsname, "/data/adb/")) {
targets.emplace_back(mentry->mnt_dir);
}
if (mentry->mnt_type == "overlay"sv) {
if (str_contains(mentry->mnt_opts, "/data/adb/ksu/modules")) {
targets.emplace_back(mentry->mnt_dir);
} else {
backups.emplace_back(mentry->mnt_dir, mentry->mnt_opts);
}
}
return true;
});
for (auto& s: reversed(targets)) {
lazy_unmount(s.data());
}
parse_mnt("/proc/self/mounts", [&](mntent* mentry) {
if (mentry->mnt_type == "overlay"sv) {
for (auto it = backups.begin(); it != backups.end(); it++) {
backups.remove_if([&](auto& mnt) {
return mnt.first == mentry->mnt_dir && mnt.second == mentry->mnt_opts;
});
}
}
return true;
});
for (auto& mnt: backups) {
auto opts = split_str(mnt.second, ",");
unsigned long flags = 0;
opts.remove_if([&](auto& opt) {
PARSE_OPT(MNTOPT_RO, MS_RDONLY)
PARSE_OPT(MNTOPT_NOSUID, MS_NOSUID)
PARSE_OPT("relatime", MS_RELATIME)
return false;
});
auto mnt_data = join_str(opts, ",");
if (mount("overlay", mnt.first.data(), "overlay", flags, mnt_data.data()) != -1) {
LOGD("Remounted (%s)", mnt.first.data());
} else {
LOGW("Failed to remount: %s (%s, %s)", strerror(errno), mnt.first.data(), mnt_data.data());
}
}
}