mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-12-25 07:17:38 +00:00
Close unclosed fds from modules
This commit is contained in:
parent
28b5faab0c
commit
50515d9128
@ -164,7 +164,7 @@ DCL_HOOK_FUNC(int, unshare, int flags) {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
// A place to clean things up before calling into zygote::ForkCommon/SpecializeCommon
|
// A place to clean things up before zygote evaluates fd table
|
||||||
DCL_HOOK_FUNC(void, android_log_close) {
|
DCL_HOOK_FUNC(void, android_log_close) {
|
||||||
HookContext::close_fds();
|
HookContext::close_fds();
|
||||||
if (g_ctx && g_ctx->pid <= 0) {
|
if (g_ctx && g_ctx->pid <= 0) {
|
||||||
@ -282,7 +282,13 @@ void hookJniNativeMethods(JNIEnv *env, const char *clz, JNINativeMethod *methods
|
|||||||
old_jniRegisterNativeMethods(env, clz, hooks.data(), hooks.size());
|
old_jniRegisterNativeMethods(env, clz, hooks.data(), hooks.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ZygiskModule::registerModule(ApiTable *table, long *module) {
|
ZygiskModule::ZygiskModule(int id, void *handle, void *entry)
|
||||||
|
: raw_entry(entry), api(this), id(id), handle(handle) {}
|
||||||
|
|
||||||
|
ApiTable::ApiTable(ZygiskModule *m)
|
||||||
|
: module(m), registerModule(&ZygiskModule::RegisterModule) {}
|
||||||
|
|
||||||
|
bool ZygiskModule::RegisterModule(ApiTable *table, long *module) {
|
||||||
long ver = *module;
|
long ver = *module;
|
||||||
// Unsupported version
|
// Unsupported version
|
||||||
if (ver > ZYGISK_API_VERSION)
|
if (ver > ZYGISK_API_VERSION)
|
||||||
@ -339,36 +345,52 @@ void HookContext::run_modules_pre(const vector<int> &fds) {
|
|||||||
for (int i = 0; i < fds.size(); ++i) {
|
for (int i = 0; i < fds.size(); ++i) {
|
||||||
snprintf(buf, sizeof(buf), "/proc/self/fd/%d", fds[i]);
|
snprintf(buf, sizeof(buf), "/proc/self/fd/%d", fds[i]);
|
||||||
if (void *h = dlopen(buf, RTLD_LAZY)) {
|
if (void *h = dlopen(buf, RTLD_LAZY)) {
|
||||||
void (*module_entry)(void *, void *);
|
if (void *e = dlsym(h, "zygisk_module_entry")) {
|
||||||
*(void **) &module_entry = dlsym(h, "zygisk_module_entry");
|
modules.emplace_back(i, h, e);
|
||||||
if (module_entry) {
|
|
||||||
modules.emplace_back(i, h);
|
|
||||||
auto api = new ApiTable(&modules.back());
|
|
||||||
module_entry(api, env);
|
|
||||||
modules.back().table = api;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
close(fds[i]);
|
close(fds[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Record all open fds
|
||||||
|
bitset<1024> open_fds;
|
||||||
|
auto dir = open_dir("/proc/self/fd");
|
||||||
|
for (dirent *entry; (entry = xreaddir(dir.get()));) {
|
||||||
|
int fd = parse_int(entry->d_name);
|
||||||
|
if (fd < 0 || fd >= 1024) {
|
||||||
|
close(fd);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
open_fds[fd] = true;
|
||||||
|
}
|
||||||
|
|
||||||
for (auto &m : modules) {
|
for (auto &m : modules) {
|
||||||
|
m.entry(&m.api, env);
|
||||||
if (flags[APP_SPECIALIZE]) {
|
if (flags[APP_SPECIALIZE]) {
|
||||||
m.preAppSpecialize(args);
|
m.preAppSpecialize(args);
|
||||||
} else if (flags[SERVER_SPECIALIZE]) {
|
} else if (flags[SERVER_SPECIALIZE]) {
|
||||||
m.preServerSpecialize(server_args);
|
m.preServerSpecialize(server_args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Close all unrecorded fds
|
||||||
|
rewinddir(dir.get());
|
||||||
|
for (dirent *entry; (entry = xreaddir(dir.get()));) {
|
||||||
|
int fd = parse_int(entry->d_name);
|
||||||
|
if (fd < 0 || fd >= 1024 || !open_fds[fd]) {
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HookContext::run_modules_post() {
|
void HookContext::run_modules_post() {
|
||||||
for (auto &m : modules) {
|
for (const auto &m : modules) {
|
||||||
if (flags[APP_SPECIALIZE]) {
|
if (flags[APP_SPECIALIZE]) {
|
||||||
m.postAppSpecialize(args);
|
m.postAppSpecialize(args);
|
||||||
} else if (flags[SERVER_SPECIALIZE]) {
|
} else if (flags[SERVER_SPECIALIZE]) {
|
||||||
m.postServerSpecialize(server_args);
|
m.postServerSpecialize(server_args);
|
||||||
}
|
}
|
||||||
if (m.unload) {
|
m.doUnload();
|
||||||
dlclose(m.handle);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -385,7 +407,7 @@ void HookContext::unload_zygisk() {
|
|||||||
|
|
||||||
// Strip out all API function pointers
|
// Strip out all API function pointers
|
||||||
for (auto &m : modules) {
|
for (auto &m : modules) {
|
||||||
memset(m.table, 0, sizeof(*m.table));
|
memset(&m.api, 0, sizeof(m.api));
|
||||||
}
|
}
|
||||||
|
|
||||||
new_daemon_thread(reinterpret_cast<thread_entry>(&dlclose), self_handle);
|
new_daemon_thread(reinterpret_cast<thread_entry>(&dlclose), self_handle);
|
||||||
|
@ -6,7 +6,7 @@ namespace {
|
|||||||
|
|
||||||
using module_abi_v1 = zygisk::internal::module_abi;
|
using module_abi_v1 = zygisk::internal::module_abi;
|
||||||
struct HookContext;
|
struct HookContext;
|
||||||
struct ApiTable;
|
struct ZygiskModule;
|
||||||
|
|
||||||
struct AppSpecializeArgsImpl {
|
struct AppSpecializeArgsImpl {
|
||||||
jint &uid;
|
jint &uid;
|
||||||
@ -67,55 +67,60 @@ force_cast_wrapper<R> force_cast(R &&x) {
|
|||||||
return force_cast_wrapper<R>(std::forward<R>(x));
|
return force_cast_wrapper<R>(std::forward<R>(x));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct ApiTable {
|
||||||
|
// These first 2 entries are permanent
|
||||||
|
ZygiskModule *module;
|
||||||
|
bool (*registerModule)(ApiTable *, long *);
|
||||||
|
|
||||||
|
struct {
|
||||||
|
void (*hookJniNativeMethods)(JNIEnv *, const char *, JNINativeMethod *, int);
|
||||||
|
void (*pltHookRegister)(const char *, const char *, void *, void **);
|
||||||
|
void (*pltHookExclude)(const char *, const char *);
|
||||||
|
bool (*pltHookCommit)();
|
||||||
|
|
||||||
|
int (*connectCompanion)(ZygiskModule *);
|
||||||
|
void (*setOption)(ZygiskModule *, zygisk::Option);
|
||||||
|
} v1;
|
||||||
|
|
||||||
|
ApiTable(ZygiskModule *m);
|
||||||
|
};
|
||||||
|
|
||||||
struct ZygiskModule {
|
struct ZygiskModule {
|
||||||
void preAppSpecialize(AppSpecializeArgsImpl *args) {
|
void preAppSpecialize(AppSpecializeArgsImpl *args) const {
|
||||||
v1->preAppSpecialize(v1->_this, force_cast(args));
|
v1->preAppSpecialize(v1->_this, force_cast(args));
|
||||||
}
|
}
|
||||||
void postAppSpecialize(const AppSpecializeArgsImpl *args) {
|
void postAppSpecialize(const AppSpecializeArgsImpl *args) const {
|
||||||
v1->postAppSpecialize(v1->_this, force_cast(args));
|
v1->postAppSpecialize(v1->_this, force_cast(args));
|
||||||
}
|
}
|
||||||
void preServerSpecialize(ServerSpecializeArgsImpl *args) {
|
void preServerSpecialize(ServerSpecializeArgsImpl *args) const {
|
||||||
v1->preServerSpecialize(v1->_this, force_cast(args));
|
v1->preServerSpecialize(v1->_this, force_cast(args));
|
||||||
}
|
}
|
||||||
void postServerSpecialize(const ServerSpecializeArgsImpl *args) {
|
void postServerSpecialize(const ServerSpecializeArgsImpl *args) const {
|
||||||
v1->postServerSpecialize(v1->_this, force_cast(args));
|
v1->postServerSpecialize(v1->_this, force_cast(args));
|
||||||
}
|
}
|
||||||
|
|
||||||
int connectCompanion() const;
|
int connectCompanion() const;
|
||||||
void setOption(zygisk::Option opt);
|
void setOption(zygisk::Option opt);
|
||||||
static bool registerModule(ApiTable *table, long *module);
|
void doUnload() const { if (unload) dlclose(handle); }
|
||||||
|
|
||||||
ZygiskModule(int id, void *handle) : handle(handle), id(id) {}
|
ZygiskModule(int id, void *handle, void *entry);
|
||||||
|
|
||||||
void * const handle;
|
static bool RegisterModule(ApiTable *table, long *module);
|
||||||
ApiTable *table = nullptr;
|
|
||||||
bool unload = false;
|
union {
|
||||||
|
void (* const entry)(void *, void *);
|
||||||
|
void * const raw_entry;
|
||||||
|
};
|
||||||
|
ApiTable api;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int id;
|
const int id;
|
||||||
|
bool unload = false;
|
||||||
|
void * const handle;
|
||||||
union {
|
union {
|
||||||
long *ver = nullptr;
|
long *ver = nullptr;
|
||||||
module_abi_v1 *v1;
|
module_abi_v1 *v1;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ApiTable {
|
|
||||||
ZygiskModule *module;
|
|
||||||
bool (*registerModule)(ApiTable *, long *);
|
|
||||||
|
|
||||||
union {
|
|
||||||
void *padding[6] = {};
|
|
||||||
struct {
|
|
||||||
void (*hookJniNativeMethods)(JNIEnv *, const char *, JNINativeMethod *, int);
|
|
||||||
void (*pltHookRegister)(const char *, const char *, void *, void **);
|
|
||||||
void (*pltHookExclude)(const char *, const char *);
|
|
||||||
bool (*pltHookCommit)();
|
|
||||||
|
|
||||||
int (*connectCompanion)(ZygiskModule *);
|
|
||||||
void (*setOption)(ZygiskModule *, zygisk::Option);
|
|
||||||
} v1;
|
|
||||||
};
|
|
||||||
ApiTable(ZygiskModule *m) : module(m), registerModule(&ZygiskModule::registerModule) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
Loading…
x
Reference in New Issue
Block a user