mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-04-25 21:20:52 +00:00
Move module list into MagiskD
This commit is contained in:
parent
4dcd733ddd
commit
0d8d6290a3
@ -179,7 +179,6 @@ bool MagiskD::post_fs_data() const noexcept {
|
||||
initialize_denylist();
|
||||
setup_mounts();
|
||||
handle_modules();
|
||||
load_modules();
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -189,7 +188,7 @@ void MagiskD::late_start() const noexcept {
|
||||
LOGI("** late_start service mode running\n");
|
||||
|
||||
exec_common_scripts("service");
|
||||
exec_module_scripts("service");
|
||||
exec_module_scripts("service", module_list());
|
||||
}
|
||||
|
||||
void MagiskD::boot_complete() const noexcept {
|
||||
|
@ -378,7 +378,6 @@ static void daemon_entry() {
|
||||
|
||||
default_new(poll_map);
|
||||
default_new(poll_fds);
|
||||
default_new(module_list);
|
||||
|
||||
// Register handler for main socket
|
||||
pollfd main_socket_pfd = { fd, POLLIN, 0 };
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::consts::{MAGISK_FULL_VER, MAIN_CONFIG};
|
||||
use crate::db::Sqlite3;
|
||||
use crate::ffi::{get_magisk_tmp, RequestCode};
|
||||
use crate::ffi::{get_magisk_tmp, ModuleInfo, RequestCode};
|
||||
use crate::get_prop;
|
||||
use crate::logging::{magisk_logging, start_log_daemon};
|
||||
use crate::package::ManagerInfo;
|
||||
@ -59,6 +59,7 @@ pub struct MagiskD {
|
||||
pub sql_connection: Mutex<Option<Sqlite3>>,
|
||||
pub manager_info: Mutex<ManagerInfo>,
|
||||
boot_stage_lock: Mutex<BootStateFlags>,
|
||||
module_list: OnceLock<Vec<ModuleInfo>>,
|
||||
sdk_int: i32,
|
||||
pub is_emulator: bool,
|
||||
is_recovery: bool,
|
||||
@ -73,6 +74,14 @@ impl MagiskD {
|
||||
self.sdk_int
|
||||
}
|
||||
|
||||
pub fn set_module_list(&self, module_list: Vec<ModuleInfo>) {
|
||||
self.module_list.set(module_list).ok();
|
||||
}
|
||||
|
||||
pub fn module_list(&self) -> &Vec<ModuleInfo> {
|
||||
self.module_list.get().unwrap()
|
||||
}
|
||||
|
||||
pub fn app_data_dir(&self) -> &'static Utf8CStr {
|
||||
if self.sdk_int >= 24 {
|
||||
cstr!("/data/user_de")
|
||||
|
@ -26,16 +26,7 @@ enum class RespondCode : int {
|
||||
END
|
||||
};
|
||||
|
||||
struct module_info {
|
||||
std::string name;
|
||||
int z32 = -1;
|
||||
#if defined(__LP64__)
|
||||
int z64 = -1;
|
||||
#endif
|
||||
};
|
||||
|
||||
extern bool zygisk_enabled;
|
||||
extern std::vector<module_info> *module_list;
|
||||
extern std::string native_bridge;
|
||||
|
||||
void reset_zygisk(bool restore);
|
||||
@ -58,16 +49,13 @@ void su_daemon_handler(int client, const sock_cred *cred);
|
||||
void zygisk_handler(int client, const sock_cred *cred);
|
||||
|
||||
// Module stuffs
|
||||
void handle_modules();
|
||||
void load_modules();
|
||||
void disable_modules();
|
||||
void remove_modules();
|
||||
void exec_module_scripts(const char *stage);
|
||||
|
||||
// Scripting
|
||||
void exec_script(const char *script);
|
||||
void exec_common_scripts(const char *stage);
|
||||
void exec_module_scripts(const char *stage, const std::vector<std::string_view> &modules);
|
||||
void exec_module_scripts(const char *stage, const rust::Vec<ModuleInfo> &module_list);
|
||||
void clear_pkg(const char *pkg, int user_id);
|
||||
[[noreturn]] void install_module(const char *file);
|
||||
|
||||
|
@ -135,6 +135,12 @@ pub mod ffi {
|
||||
notify: bool,
|
||||
}
|
||||
|
||||
struct ModuleInfo {
|
||||
name: String,
|
||||
z32: i32,
|
||||
z64: i32,
|
||||
}
|
||||
|
||||
unsafe extern "C++" {
|
||||
include!("include/sqlite.hpp");
|
||||
|
||||
@ -185,6 +191,8 @@ pub mod ffi {
|
||||
fn uid_granted_root(&self, mut uid: i32) -> bool;
|
||||
#[cxx_name = "get_manager"]
|
||||
unsafe fn get_manager_for_cxx(&self, user: i32, ptr: *mut CxxString, install: bool) -> i32;
|
||||
fn set_module_list(&self, module_list: Vec<ModuleInfo>);
|
||||
fn module_list(&self) -> &Vec<ModuleInfo>;
|
||||
|
||||
#[cxx_name = "get_db_settings"]
|
||||
fn get_db_settings_for_cxx(&self, cfg: &mut DbSettings) -> bool;
|
||||
@ -209,6 +217,8 @@ pub mod ffi {
|
||||
fn post_fs_data(self: &MagiskD) -> bool;
|
||||
fn late_start(self: &MagiskD);
|
||||
fn boot_complete(self: &MagiskD);
|
||||
#[allow(dead_code)]
|
||||
fn handle_modules(self: &MagiskD);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -86,7 +86,7 @@ bool dir_node::prepare() {
|
||||
return upgrade_to_tmpfs;
|
||||
}
|
||||
|
||||
void dir_node::collect_module_files(const char *module, int dfd) {
|
||||
void dir_node::collect_module_files(std::string_view module, int dfd) {
|
||||
auto dir = xopen_dir(xopenat(dfd, name().data(), O_RDONLY | O_CLOEXEC));
|
||||
if (!dir)
|
||||
return;
|
||||
@ -149,7 +149,9 @@ void module_node::mount() {
|
||||
VLOGD("delete", "null", node_path().data());
|
||||
return;
|
||||
}
|
||||
std::string path = module + (parent()->root()->prefix + node_path());
|
||||
std::string path{module.begin(), module.end()};
|
||||
path += parent()->root()->prefix;
|
||||
path += node_path();
|
||||
string mnt_src = module_mnt + path;
|
||||
{
|
||||
string src = MODULEROOT "/" + path;
|
||||
@ -267,9 +269,7 @@ static void inject_zygisk_libs(root_node *system) {
|
||||
}
|
||||
}
|
||||
|
||||
vector<module_info> *module_list;
|
||||
|
||||
void load_modules() {
|
||||
static void load_modules(const rust::Vec<ModuleInfo> &module_list) {
|
||||
node_entry::module_mnt = get_magisk_tmp() + "/"s MODULEMNT "/";
|
||||
|
||||
auto root = make_unique<root_node>("");
|
||||
@ -278,14 +278,14 @@ void load_modules() {
|
||||
|
||||
char buf[4096];
|
||||
LOGI("* Loading modules\n");
|
||||
for (const auto &m : *module_list) {
|
||||
const char *module = m.name.data();
|
||||
char *b = buf + ssprintf(buf, sizeof(buf), "%s/" MODULEMNT "/%s/", get_magisk_tmp(), module);
|
||||
for (const auto &m : module_list) {
|
||||
char *b = buf + ssprintf(buf, sizeof(buf), "%s/" MODULEMNT "/%.*s/",
|
||||
get_magisk_tmp(), (int) m.name.size(), m.name.data());
|
||||
|
||||
// Read props
|
||||
strcpy(b, "system.prop");
|
||||
if (access(buf, F_OK) == 0) {
|
||||
LOGI("%s: loading [system.prop]\n", module);
|
||||
LOGI("%.*s: loading [system.prop]\n", (int) m.name.size(), m.name.data());
|
||||
// Do NOT go through property service as it could cause boot lock
|
||||
load_prop_file(buf, true);
|
||||
}
|
||||
@ -300,10 +300,10 @@ void load_modules() {
|
||||
if (access(buf, F_OK) != 0)
|
||||
continue;
|
||||
|
||||
LOGI("%s: loading mount files\n", module);
|
||||
LOGI("%.*s: loading mount files\n", (int) m.name.size(), m.name.data());
|
||||
b[-1] = '\0';
|
||||
int fd = xopen(buf, O_RDONLY | O_CLOEXEC);
|
||||
system->collect_module_files(module, fd);
|
||||
system->collect_module_files({ m.name.begin(), m.name.end() }, fd);
|
||||
close(fd);
|
||||
}
|
||||
if (get_magisk_tmp() != "/sbin"sv || !str_contains(getenv("PATH") ?: "", "/sbin")) {
|
||||
@ -392,8 +392,9 @@ static void foreach_module(Func fn) {
|
||||
}
|
||||
}
|
||||
|
||||
static void collect_modules(bool open_zygisk) {
|
||||
foreach_module([=](int dfd, dirent *entry, int modfd) {
|
||||
static rust::Vec<ModuleInfo> collect_modules(bool open_zygisk) {
|
||||
rust::Vec<ModuleInfo> modules;
|
||||
foreach_module([&](int dfd, dirent *entry, int modfd) {
|
||||
if (faccessat(modfd, "remove", F_OK, 0) == 0) {
|
||||
LOGI("%s: remove\n", entry->d_name);
|
||||
auto uninstaller = MODULEROOT + "/"s + entry->d_name + "/uninstall.sh";
|
||||
@ -407,7 +408,7 @@ static void collect_modules(bool open_zygisk) {
|
||||
if (faccessat(modfd, "disable", F_OK, 0) == 0)
|
||||
return;
|
||||
|
||||
module_info info;
|
||||
ModuleInfo info{};
|
||||
if (zygisk_enabled) {
|
||||
// Riru and its modules are not compatible with zygisk
|
||||
if (entry->d_name == "riru-core"sv || faccessat(modfd, "riru", F_OK, 0) == 0) {
|
||||
@ -417,11 +418,13 @@ static void collect_modules(bool open_zygisk) {
|
||||
if (open_zygisk) {
|
||||
#if defined(__arm__)
|
||||
info.z32 = openat(modfd, "zygisk/armeabi-v7a.so", O_RDONLY | O_CLOEXEC);
|
||||
info.z64 = -1;
|
||||
#elif defined(__aarch64__)
|
||||
info.z32 = openat(modfd, "zygisk/armeabi-v7a.so", O_RDONLY | O_CLOEXEC);
|
||||
info.z64 = openat(modfd, "zygisk/arm64-v8a.so", O_RDONLY | O_CLOEXEC);
|
||||
#elif defined(__i386__)
|
||||
info.z32 = openat(modfd, "zygisk/x86.so", O_RDONLY | O_CLOEXEC);
|
||||
info.z64 = -1;
|
||||
#elif defined(__x86_64__)
|
||||
info.z32 = openat(modfd, "zygisk/x86.so", O_RDONLY | O_CLOEXEC);
|
||||
info.z64 = openat(modfd, "zygisk/x86_64.so", O_RDONLY | O_CLOEXEC);
|
||||
@ -441,7 +444,7 @@ static void collect_modules(bool open_zygisk) {
|
||||
}
|
||||
}
|
||||
info.name = entry->d_name;
|
||||
module_list->push_back(info);
|
||||
modules.push_back(std::move(info));
|
||||
});
|
||||
if (zygisk_enabled) {
|
||||
bool use_memfd = true;
|
||||
@ -461,23 +464,23 @@ static void collect_modules(bool open_zygisk) {
|
||||
}
|
||||
return fd;
|
||||
};
|
||||
std::for_each(module_list->begin(), module_list->end(), [&](module_info &info) {
|
||||
std::for_each(modules.begin(),modules.end(), [&](ModuleInfo &info) {
|
||||
info.z32 = convert_to_memfd(info.z32);
|
||||
#if defined(__LP64__)
|
||||
info.z64 = convert_to_memfd(info.z64);
|
||||
#endif
|
||||
});
|
||||
}
|
||||
return modules;
|
||||
}
|
||||
|
||||
void handle_modules() {
|
||||
void MagiskD::handle_modules() const noexcept {
|
||||
prepare_modules();
|
||||
collect_modules(false);
|
||||
exec_module_scripts("post-fs-data");
|
||||
|
||||
exec_module_scripts("post-fs-data", collect_modules(false));
|
||||
// Recollect modules (module scripts could remove itself)
|
||||
module_list->clear();
|
||||
collect_modules(true);
|
||||
auto list = collect_modules(true);
|
||||
load_modules(list);
|
||||
set_module_list(std::move(list));
|
||||
}
|
||||
|
||||
static int check_rules_dir(char *buf, size_t sz) {
|
||||
@ -517,10 +520,3 @@ void remove_modules() {
|
||||
});
|
||||
rm_rf(MODULEROOT);
|
||||
}
|
||||
|
||||
void exec_module_scripts(const char *stage) {
|
||||
vector<string_view> module_names;
|
||||
std::transform(module_list->begin(), module_list->end(), std::back_inserter(module_names),
|
||||
[](const module_info &info) -> string_view { return info.name; });
|
||||
exec_module_scripts(stage, module_names);
|
||||
}
|
||||
|
@ -105,7 +105,7 @@ public:
|
||||
**************/
|
||||
|
||||
// Traverse through module directories to generate a tree of module files
|
||||
void collect_module_files(const char *module, int dfd);
|
||||
void collect_module_files(std::string_view module, int dfd);
|
||||
|
||||
// Traverse through the real filesystem and prepare the tree for magic mount.
|
||||
// Return true to indicate that this node needs to be upgraded to tmpfs_node.
|
||||
@ -279,16 +279,16 @@ public:
|
||||
|
||||
class module_node : public node_entry {
|
||||
public:
|
||||
module_node(const char *module, dirent *entry)
|
||||
module_node(std::string_view module, dirent *entry)
|
||||
: node_entry(entry->d_name, entry->d_type, this), module(module) {}
|
||||
|
||||
module_node(node_entry *node, const char *module) : node_entry(this), module(module) {
|
||||
module_node(node_entry *node, std::string_view module) : node_entry(this), module(module) {
|
||||
node_entry::consume(node);
|
||||
}
|
||||
|
||||
void mount() override;
|
||||
private:
|
||||
const char *module;
|
||||
std::string_view module;
|
||||
};
|
||||
|
||||
// Don't create tmpfs_node before prepare
|
||||
|
@ -117,9 +117,9 @@ static bool operator>(const timespec &a, const timespec &b) {
|
||||
return a.tv_nsec > b.tv_nsec;
|
||||
}
|
||||
|
||||
void exec_module_scripts(const char *stage, const vector<string_view> &modules) {
|
||||
void exec_module_scripts(const char *stage, const rust::Vec<ModuleInfo> &module_list) {
|
||||
LOGI("* Running module %s scripts\n", stage);
|
||||
if (modules.empty())
|
||||
if (module_list.empty())
|
||||
return;
|
||||
|
||||
bool pfs = stage == "post-fs-data"sv;
|
||||
@ -134,12 +134,11 @@ void exec_module_scripts(const char *stage, const vector<string_view> &modules)
|
||||
PFS_SETUP()
|
||||
|
||||
char path[4096];
|
||||
for (auto &m : modules) {
|
||||
const char *module = m.data();
|
||||
sprintf(path, MODULEROOT "/%s/%s.sh", module, stage);
|
||||
for (auto &m : module_list) {
|
||||
sprintf(path, MODULEROOT "/%.*s/%s.sh", (int) m.name.size(), m.name.data(), stage);
|
||||
if (access(path, F_OK) == -1)
|
||||
continue;
|
||||
LOGI("%s: exec [%s.sh]\n", module, stage);
|
||||
LOGI("%.*s: exec [%s.sh]\n", (int) m.name.size(), m.name.data(), stage);
|
||||
exec_t exec {
|
||||
.pre_exec = set_script_env,
|
||||
.fork = pfs ? xfork : fork_dont_care
|
||||
|
@ -15,6 +15,8 @@ using namespace std;
|
||||
|
||||
string native_bridge = "0";
|
||||
|
||||
using modules_t = const rust::Vec<ModuleInfo>&;
|
||||
|
||||
static bool is_compatible_with(uint32_t) {
|
||||
zygisk_logging();
|
||||
hook_entry();
|
||||
@ -55,20 +57,20 @@ int remote_get_info(int uid, const char *process, uint32_t *flags, vector<int> &
|
||||
|
||||
// The following code runs in magiskd
|
||||
|
||||
static vector<int> get_module_fds(bool is_64_bit) {
|
||||
static vector<int> get_module_fds(bool is_64_bit, modules_t module_list) {
|
||||
vector<int> fds;
|
||||
// All fds passed to send_fds have to be valid file descriptors.
|
||||
// To workaround this issue, send over STDOUT_FILENO as an indicator of an
|
||||
// invalid fd as it will always be /dev/null in magiskd
|
||||
#if defined(__LP64__)
|
||||
if (is_64_bit) {
|
||||
std::transform(module_list->begin(), module_list->end(), std::back_inserter(fds),
|
||||
[](const module_info &info) { return info.z64 < 0 ? STDOUT_FILENO : info.z64; });
|
||||
std::transform(module_list.begin(), module_list.end(), std::back_inserter(fds),
|
||||
[](const ModuleInfo &info) { return info.z64 < 0 ? STDOUT_FILENO : info.z64; });
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
std::transform(module_list->begin(), module_list->end(), std::back_inserter(fds),
|
||||
[](const module_info &info) { return info.z32 < 0 ? STDOUT_FILENO : info.z32; });
|
||||
std::transform(module_list.begin(), module_list.end(), std::back_inserter(fds),
|
||||
[](const ModuleInfo &info) { return info.z32 < 0 ? STDOUT_FILENO : info.z32; });
|
||||
}
|
||||
return fds;
|
||||
}
|
||||
@ -77,9 +79,10 @@ static pthread_mutex_t zygiskd_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
static int zygiskd_sockets[] = { -1, -1 };
|
||||
#define zygiskd_socket zygiskd_sockets[is_64_bit]
|
||||
|
||||
static void connect_companion(int client, bool is_64_bit) {
|
||||
static void connect_companion(int client, modules_t module_list) {
|
||||
mutex_guard g(zygiskd_lock);
|
||||
|
||||
bool is_64_bit = read_int(client);
|
||||
if (zygiskd_socket >= 0) {
|
||||
// Make sure the socket is still valid
|
||||
pollfd pfd = { zygiskd_socket, 0, 0 };
|
||||
@ -109,7 +112,7 @@ static void connect_companion(int client, bool is_64_bit) {
|
||||
exit(-1);
|
||||
}
|
||||
close(fds[1]);
|
||||
vector<int> module_fds = get_module_fds(is_64_bit);
|
||||
vector<int> module_fds = get_module_fds(is_64_bit, module_list);
|
||||
send_fds(zygiskd_socket, module_fds.data(), module_fds.size());
|
||||
// Wait for ack
|
||||
if (read_int(zygiskd_socket) != 0) {
|
||||
@ -120,7 +123,7 @@ static void connect_companion(int client, bool is_64_bit) {
|
||||
send_fd(zygiskd_socket, client);
|
||||
}
|
||||
|
||||
static void get_process_info(int client, const sock_cred *cred) {
|
||||
static void get_process_info(int client, const sock_cred *cred, modules_t module_list) {
|
||||
int uid = read_int(client);
|
||||
string process = read_string(client);
|
||||
int arch = read_int(client);
|
||||
@ -144,7 +147,7 @@ static void get_process_info(int client, const sock_cred *cred) {
|
||||
xwrite(client, &flags, sizeof(flags));
|
||||
|
||||
if (should_load_modules(flags)) {
|
||||
vector<int> fds = get_module_fds(arch);
|
||||
vector<int> fds = get_module_fds(arch, module_list);
|
||||
send_fds(client, fds.data(), fds.size());
|
||||
}
|
||||
|
||||
@ -159,12 +162,12 @@ static void get_process_info(int client, const sock_cred *cred) {
|
||||
xxread(client, &l, sizeof(l));
|
||||
bits.emplace_back(l);
|
||||
}
|
||||
for (int id = 0; id < module_list->size(); ++id) {
|
||||
for (int id = 0; id < module_list.size(); ++id) {
|
||||
if (!as_const(bits)[id]) {
|
||||
// Either not a zygisk module, or incompatible
|
||||
char buf[4096];
|
||||
ssprintf(buf, sizeof(buf), MODULEROOT "/%s/zygisk",
|
||||
module_list->operator[](id).name.data());
|
||||
module_list[id].name.data());
|
||||
if (int dirfd = open(buf, O_RDONLY | O_CLOEXEC); dirfd >= 0) {
|
||||
close(xopenat(dirfd, "unloaded", O_CREAT | O_RDONLY, 0644));
|
||||
close(dirfd);
|
||||
@ -173,28 +176,28 @@ static void get_process_info(int client, const sock_cred *cred) {
|
||||
}
|
||||
}
|
||||
|
||||
static void get_moddir(int client) {
|
||||
static void get_moddir(int client, modules_t module_list) {
|
||||
int id = read_int(client);
|
||||
char buf[4096];
|
||||
ssprintf(buf, sizeof(buf), MODULEROOT "/%s", module_list->operator[](id).name.data());
|
||||
auto &m = module_list[id];
|
||||
ssprintf(buf, sizeof(buf), MODULEROOT "/%.*s", (int) m.name.size(), m.name.data());
|
||||
int dfd = xopen(buf, O_RDONLY | O_CLOEXEC);
|
||||
send_fd(client, dfd);
|
||||
close(dfd);
|
||||
}
|
||||
|
||||
void zygisk_handler(int client, const sock_cred *cred) {
|
||||
auto &module_list = MagiskD().module_list();
|
||||
int code = read_int(client);
|
||||
switch (code) {
|
||||
case ZygiskRequest::GET_INFO:
|
||||
get_process_info(client, cred);
|
||||
get_process_info(client, cred, module_list);
|
||||
break;
|
||||
case ZygiskRequest::CONNECT_COMPANION: {
|
||||
int arch = read_int(client);
|
||||
connect_companion(client, arch);
|
||||
case ZygiskRequest::CONNECT_COMPANION:
|
||||
connect_companion(client, module_list);
|
||||
break;
|
||||
}
|
||||
case ZygiskRequest::GET_MODDIR:
|
||||
get_moddir(client);
|
||||
get_moddir(client, module_list);
|
||||
break;
|
||||
default:
|
||||
// Unknown code
|
||||
|
Loading…
x
Reference in New Issue
Block a user