Commit 80dd37ee authored by topjohnwu's avatar topjohnwu

Add missing specialize arguments

parent e0b56450
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
#include <jni.h> #include <jni.h>
#define ZYGISK_API_VERSION 2 #define ZYGISK_API_VERSION 3
/* /*
...@@ -98,6 +98,7 @@ struct AppSpecializeArgs { ...@@ -98,6 +98,7 @@ struct AppSpecializeArgs {
jint &gid; jint &gid;
jintArray &gids; jintArray &gids;
jint &runtime_flags; jint &runtime_flags;
jobjectArray &rlimits;
jint &mount_external; jint &mount_external;
jstring &se_info; jstring &se_info;
jstring &nice_name; jstring &nice_name;
...@@ -105,6 +106,7 @@ struct AppSpecializeArgs { ...@@ -105,6 +106,7 @@ struct AppSpecializeArgs {
jstring &app_data_dir; jstring &app_data_dir;
// Optional arguments. Please check whether the pointer is null before de-referencing // Optional arguments. Please check whether the pointer is null before de-referencing
jintArray *const fds_to_ignore;
jboolean *const is_child_zygote; jboolean *const is_child_zygote;
jboolean *const is_top_app; jboolean *const is_top_app;
jobjectArray *const pkg_data_info_list; jobjectArray *const pkg_data_info_list;
......
...@@ -87,7 +87,7 @@ class ForkAndSpec(JNIHook): ...@@ -87,7 +87,7 @@ class ForkAndSpec(JNIHook):
return 'nativeForkAndSpecialize' return 'nativeForkAndSpecialize'
def init_args(self): def init_args(self):
return 'AppSpecializeArgsImpl args(uid, gid, gids, runtime_flags, mount_external, se_info, nice_name, instruction_set, app_data_dir);' return 'AppSpecializeArgs_v3 args(uid, gid, gids, runtime_flags, rlimits, mount_external, se_info, nice_name, instruction_set, app_data_dir);'
def body(self): def body(self):
decl = '' decl = ''
...@@ -118,7 +118,7 @@ class ForkServer(ForkAndSpec): ...@@ -118,7 +118,7 @@ class ForkServer(ForkAndSpec):
return 'nativeForkSystemServer' return 'nativeForkSystemServer'
def init_args(self): def init_args(self):
return 'ServerSpecializeArgsImpl args(uid, gid, gids, runtime_flags, permitted_capabilities, effective_capabilities);' return 'ServerSpecializeArgs_v1 args(uid, gid, gids, runtime_flags, permitted_capabilities, effective_capabilities);'
# Common args # Common args
uid = Argument('uid', jint) uid = Argument('uid', jint)
...@@ -134,7 +134,7 @@ instruction_set = Argument('instruction_set', jstring) ...@@ -134,7 +134,7 @@ instruction_set = Argument('instruction_set', jstring)
app_data_dir = Argument('app_data_dir', jstring) app_data_dir = Argument('app_data_dir', jstring)
# o # o
fds_to_ignore = Argument('fds_to_ignore', jintArray) fds_to_ignore = Argument('fds_to_ignore', jintArray, True)
# p # p
is_child_zygote = Argument('is_child_zygote', jboolean, True) is_child_zygote = Argument('is_child_zygote', jboolean, True)
......
...@@ -43,8 +43,8 @@ void name##_post(); ...@@ -43,8 +43,8 @@ void name##_post();
struct HookContext { struct HookContext {
JNIEnv *env; JNIEnv *env;
union { union {
AppSpecializeArgsImpl *args; AppSpecializeArgs_v3 *args;
ServerSpecializeArgsImpl *server_args; ServerSpecializeArgs_v1 *server_args;
void *raw_args; void *raw_args;
}; };
const char *process; const char *process;
...@@ -292,10 +292,11 @@ bool ZygiskModule::RegisterModule(ApiTable *table, long *module) { ...@@ -292,10 +292,11 @@ bool ZygiskModule::RegisterModule(ApiTable *table, long *module) {
// Fill in API accordingly with module API version // Fill in API accordingly with module API version
switch (ver) { switch (ver) {
case 3:
case 2: case 2:
table->v2.getModuleDir = [](ZygiskModule *m) { return m->getModuleDir(); }; table->v2.getModuleDir = [](ZygiskModule *m) { return m->getModuleDir(); };
table->v2.getFlags = [](auto) { return ZygiskModule::getFlags(); }; table->v2.getFlags = [](auto) { return ZygiskModule::getFlags(); };
[[fallthrough]]; // fallthrough
case 1: case 1:
table->v1.hookJniNativeMethods = &hookJniNativeMethods; table->v1.hookJniNativeMethods = &hookJniNativeMethods;
table->v1.pltHookRegister = [](const char *p, const char *s, void *n, void **o) { table->v1.pltHookRegister = [](const char *p, const char *s, void *n, void **o) {
...@@ -391,6 +392,19 @@ void HookContext::run_modules_pre(const vector<int> &fds) { ...@@ -391,6 +392,19 @@ void HookContext::run_modules_pre(const vector<int> &fds) {
} }
} }
// Add all ignored fd onto whitelist
if (state[APP_SPECIALIZE] && args->fds_to_ignore) {
int len = env->GetArrayLength(*args->fds_to_ignore);
int *arr = env->GetIntArrayElements(*args->fds_to_ignore, nullptr);
for (int i = 0; i < len; ++i) {
int fd = arr[i];
if (fd >= 0 && fd < 1024) {
open_fds[fd] = true;
}
}
env->ReleaseIntArrayElements(*args->fds_to_ignore, arr, 0);
}
// Close all unrecorded fds // Close all unrecorded fds
rewinddir(dir.get()); rewinddir(dir.get());
for (dirent *entry; (entry = xreaddir(dir.get()));) { for (dirent *entry; (entry = xreaddir(dir.get()));) {
......
This diff is collapsed.
...@@ -4,22 +4,22 @@ ...@@ -4,22 +4,22 @@
namespace { namespace {
using module_abi_v1 = zygisk::internal::module_abi;
struct HookContext; struct HookContext;
struct ZygiskModule; struct ZygiskModule;
struct AppSpecializeArgsImpl { struct AppSpecializeArgs_v3 {
jint &uid; jint &uid;
jint &gid; jint &gid;
jintArray &gids; jintArray &gids;
jint &runtime_flags; jint &runtime_flags;
jobjectArray &rlimits;
jint &mount_external; jint &mount_external;
jstring &se_info; jstring &se_info;
jstring &nice_name; jstring &nice_name;
jstring &instruction_set; jstring &instruction_set;
jstring &app_data_dir; jstring &app_data_dir;
/* Optional */ jintArray *fds_to_ignore = nullptr;
jboolean *is_child_zygote = nullptr; jboolean *is_child_zygote = nullptr;
jboolean *is_top_app = nullptr; jboolean *is_top_app = nullptr;
jobjectArray *pkg_data_info_list = nullptr; jobjectArray *pkg_data_info_list = nullptr;
...@@ -27,16 +27,55 @@ struct AppSpecializeArgsImpl { ...@@ -27,16 +27,55 @@ struct AppSpecializeArgsImpl {
jboolean *mount_data_dirs = nullptr; jboolean *mount_data_dirs = nullptr;
jboolean *mount_storage_dirs = nullptr; jboolean *mount_storage_dirs = nullptr;
AppSpecializeArgsImpl( AppSpecializeArgs_v3(
jint &uid, jint &gid, jintArray &gids, jint &runtime_flags, jint &uid, jint &gid, jintArray &gids, jint &runtime_flags,
jint &mount_external, jstring &se_info, jstring &nice_name, jobjectArray &rlimits, jint &mount_external, jstring &se_info, jstring &nice_name,
jstring &instruction_set, jstring &app_data_dir) : jstring &instruction_set, jstring &app_data_dir) :
uid(uid), gid(gid), gids(gids), runtime_flags(runtime_flags), uid(uid), gid(gid), gids(gids), runtime_flags(runtime_flags), rlimits(rlimits),
mount_external(mount_external), se_info(se_info), nice_name(nice_name), mount_external(mount_external), se_info(se_info), nice_name(nice_name),
instruction_set(instruction_set), app_data_dir(app_data_dir) {} instruction_set(instruction_set), app_data_dir(app_data_dir) {}
}; };
struct ServerSpecializeArgsImpl { struct AppSpecializeArgs_v1 {
jint &uid;
jint &gid;
jintArray &gids;
jint &runtime_flags;
jint &mount_external;
jstring &se_info;
jstring &nice_name;
jstring &instruction_set;
jstring &app_data_dir;
jboolean *const is_child_zygote;
jboolean *const is_top_app;
jobjectArray *const pkg_data_info_list;
jobjectArray *const whitelisted_data_info_list;
jboolean *const mount_data_dirs;
jboolean *const mount_storage_dirs;
AppSpecializeArgs_v1(const AppSpecializeArgs_v3 *v3) :
uid(v3->uid), gid(v3->gid), gids(v3->gids), runtime_flags(v3->runtime_flags),
mount_external(v3->mount_external), se_info(v3->se_info), nice_name(v3->nice_name),
instruction_set(v3->instruction_set), app_data_dir(v3->app_data_dir),
is_child_zygote(v3->is_child_zygote), is_top_app(v3->is_top_app),
pkg_data_info_list(v3->pkg_data_info_list),
whitelisted_data_info_list(v3->whitelisted_data_info_list),
mount_data_dirs(v3->mount_data_dirs), mount_storage_dirs(v3->mount_storage_dirs) {}
};
struct module_abi_raw {
long api_version;
void *_this;
void (*preAppSpecialize)(void *, void *);
void (*postAppSpecialize)(void *, const void *);
void (*preServerSpecialize)(void *, void *);
void (*postServerSpecialize)(void *, const void *);
};
using module_abi_v1 = module_abi_raw;
struct ServerSpecializeArgs_v1 {
jint &uid; jint &uid;
jint &gid; jint &gid;
jintArray &gids; jintArray &gids;
...@@ -44,7 +83,7 @@ struct ServerSpecializeArgsImpl { ...@@ -44,7 +83,7 @@ struct ServerSpecializeArgsImpl {
jlong &permitted_capabilities; jlong &permitted_capabilities;
jlong &effective_capabilities; jlong &effective_capabilities;
ServerSpecializeArgsImpl( ServerSpecializeArgs_v1(
jint &uid, jint &gid, jintArray &gids, jint &runtime_flags, jint &uid, jint &gid, jintArray &gids, jint &runtime_flags,
jlong &permitted_capabilities, jlong &effective_capabilities) : jlong &permitted_capabilities, jlong &effective_capabilities) :
uid(uid), gid(gid), gids(gids), runtime_flags(runtime_flags), uid(uid), gid(gid), gids(gids), runtime_flags(runtime_flags),
...@@ -63,21 +102,6 @@ enum : uint32_t { ...@@ -63,21 +102,6 @@ enum : uint32_t {
PRIVATE_MASK = (0x3u << 30) PRIVATE_MASK = (0x3u << 30)
}; };
template<typename T>
struct force_cast_wrapper {
template<typename U>
operator U() const { return reinterpret_cast<U>(mX); }
force_cast_wrapper(T &&x) : mX(std::forward<T>(x)) {}
force_cast_wrapper &operator=(const force_cast_wrapper &) = delete;
private:
T &&mX;
};
template<typename R>
force_cast_wrapper<R> force_cast(R &&x) {
return force_cast_wrapper<R>(std::forward<R>(x));
}
struct ApiTable { struct ApiTable {
// These first 2 entries are permanent // These first 2 entries are permanent
ZygiskModule *module; ZygiskModule *module;
...@@ -100,18 +124,32 @@ struct ApiTable { ...@@ -100,18 +124,32 @@ struct ApiTable {
ApiTable(ZygiskModule *m); ApiTable(ZygiskModule *m);
}; };
#define call_app(method) \
switch (*ver) { \
case 1: \
case 2: { \
AppSpecializeArgs_v1 a(args); \
v1->method(v1->_this, &a); \
break; \
} \
case 3: \
v1->method(v1->_this, args); \
break; \
}
struct ZygiskModule { struct ZygiskModule {
void preAppSpecialize(AppSpecializeArgsImpl *args) const {
v1->preAppSpecialize(v1->_this, force_cast(args)); void preAppSpecialize(AppSpecializeArgs_v3 *args) const {
call_app(preAppSpecialize)
} }
void postAppSpecialize(const AppSpecializeArgsImpl *args) const { void postAppSpecialize(const AppSpecializeArgs_v3 *args) const {
v1->postAppSpecialize(v1->_this, force_cast(args)); call_app(postAppSpecialize)
} }
void preServerSpecialize(ServerSpecializeArgsImpl *args) const { void preServerSpecialize(ServerSpecializeArgs_v1 *args) const {
v1->preServerSpecialize(v1->_this, force_cast(args)); v1->preServerSpecialize(v1->_this, args);
} }
void postServerSpecialize(const ServerSpecializeArgsImpl *args) const { void postServerSpecialize(const ServerSpecializeArgs_v1 *args) const {
v1->postServerSpecialize(v1->_this, force_cast(args)); v1->postServerSpecialize(v1->_this, args);
} }
int connectCompanion() const; int connectCompanion() const;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment