mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-01-12 14:23:37 +00:00
Enforce dyn APK signature in stub app
This commit is contained in:
parent
afa364cfc3
commit
2a252d13b8
@ -35,4 +35,5 @@ 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 std::vector<std::string_view> &modules);
|
||||||
void install_apk(const char *apk);
|
void install_apk(const char *apk);
|
||||||
void uninstall_pkg(const char *pkg);
|
void uninstall_pkg(const char *pkg);
|
||||||
|
void clear_pkg(const char *pkg, int user_id);
|
||||||
[[noreturn]] void install_module(const char *file);
|
[[noreturn]] void install_module(const char *file);
|
||||||
|
@ -8,6 +8,8 @@
|
|||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
#define ENFORCE_SIGNATURE (!MAGISK_DEBUG)
|
||||||
|
|
||||||
// These functions will be called on every single zygote process specialization and su request,
|
// These functions will be called on every single zygote process specialization and su request,
|
||||||
// so performance is absolutely critical. Most operations should either have its result cached
|
// so performance is absolutely critical. Most operations should either have its result cached
|
||||||
// or simply skipped unless necessary.
|
// or simply skipped unless necessary.
|
||||||
@ -100,6 +102,24 @@ int get_manager(int user_id, string *pkg, bool install) {
|
|||||||
if (mgr_cert == nullptr)
|
if (mgr_cert == nullptr)
|
||||||
default_new(mgr_cert);
|
default_new(mgr_cert);
|
||||||
|
|
||||||
|
auto check_dyn = [&](int u) -> bool {
|
||||||
|
snprintf(app_path, sizeof(app_path),
|
||||||
|
"%s/%d/%s/dyn/current.apk", APP_DATA_DIR, u, mgr_pkg->data());
|
||||||
|
int dyn = open(app_path, O_RDONLY | O_CLOEXEC);
|
||||||
|
if (dyn < 0)
|
||||||
|
return false;
|
||||||
|
bool mismatch = default_cert && read_certificate(dyn) != *default_cert;
|
||||||
|
close(dyn);
|
||||||
|
if (mismatch) {
|
||||||
|
LOGE("pkg: dyn APK signature mismatch: %s\n", app_path);
|
||||||
|
#if ENFORCE_SIGNATURE
|
||||||
|
clear_pkg(mgr_pkg->data(), u);
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
if (skip_check.test_and_set()) {
|
if (skip_check.test_and_set()) {
|
||||||
if (mgr_app_id < 0) {
|
if (mgr_app_id < 0) {
|
||||||
goto not_found;
|
goto not_found;
|
||||||
@ -108,6 +128,9 @@ int get_manager(int user_id, string *pkg, bool install) {
|
|||||||
const char *name = mgr_pkg->empty() ? JAVA_PACKAGE_NAME : mgr_pkg->data();
|
const char *name = mgr_pkg->empty() ? JAVA_PACKAGE_NAME : mgr_pkg->data();
|
||||||
snprintf(app_path, sizeof(app_path), "%s/%d/%s", APP_DATA_DIR, user_id, name);
|
snprintf(app_path, sizeof(app_path), "%s/%d/%s", APP_DATA_DIR, user_id, name);
|
||||||
if (access(app_path, F_OK) == 0) {
|
if (access(app_path, F_OK) == 0) {
|
||||||
|
// Always check dyn signature for repackaged app
|
||||||
|
if (!mgr_pkg->empty() && !check_dyn(user_id))
|
||||||
|
goto not_found;
|
||||||
if (pkg) *pkg = name;
|
if (pkg) *pkg = name;
|
||||||
return user_id * AID_USER_OFFSET + mgr_app_id;
|
return user_id * AID_USER_OFFSET + mgr_app_id;
|
||||||
} else {
|
} else {
|
||||||
@ -161,6 +184,7 @@ int get_manager(int user_id, string *pkg, bool install) {
|
|||||||
LOGE("pkg: repackaged APK signature invalid: %s\n", apk.data());
|
LOGE("pkg: repackaged APK signature invalid: %s\n", apk.data());
|
||||||
uninstall_pkg(mgr_pkg->data());
|
uninstall_pkg(mgr_pkg->data());
|
||||||
invalid = true;
|
invalid = true;
|
||||||
|
install = true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -174,6 +198,8 @@ int get_manager(int user_id, string *pkg, bool install) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (check_pkg(user_id)) {
|
if (check_pkg(user_id)) {
|
||||||
|
if (!check_dyn(user_id))
|
||||||
|
goto not_found;
|
||||||
if (pkg) *pkg = *mgr_pkg;
|
if (pkg) *pkg = *mgr_pkg;
|
||||||
return st.st_uid;
|
return st.st_uid;
|
||||||
}
|
}
|
||||||
@ -209,7 +235,7 @@ int get_manager(int user_id, string *pkg, bool install) {
|
|||||||
if (default_cert && cert != *default_cert) {
|
if (default_cert && cert != *default_cert) {
|
||||||
// Found APK with invalid signature, force replace with stub
|
// Found APK with invalid signature, force replace with stub
|
||||||
LOGE("pkg: APK signature mismatch: %s\n", apk.data());
|
LOGE("pkg: APK signature mismatch: %s\n", apk.data());
|
||||||
#if !MAGISK_DEBUG
|
#if ENFORCE_SIGNATURE
|
||||||
uninstall_pkg(JAVA_PACKAGE_NAME);
|
uninstall_pkg(JAVA_PACKAGE_NAME);
|
||||||
invalid = true;
|
invalid = true;
|
||||||
install = true;
|
install = true;
|
||||||
|
@ -152,8 +152,8 @@ void exec_module_scripts(const char *stage, const vector<string_view> &modules)
|
|||||||
|
|
||||||
constexpr char install_script[] = R"EOF(
|
constexpr char install_script[] = R"EOF(
|
||||||
APK=%s
|
APK=%s
|
||||||
log -t Magisk "apk_install: $APK"
|
log -t Magisk "pm_install: $APK"
|
||||||
log -t Magisk "apk_install: $(pm install -r $APK 2>&1)"
|
log -t Magisk "pm_install: $(pm install -r $APK 2>&1)"
|
||||||
rm -f $APK
|
rm -f $APK
|
||||||
)EOF";
|
)EOF";
|
||||||
|
|
||||||
@ -169,8 +169,8 @@ void install_apk(const char *apk) {
|
|||||||
|
|
||||||
constexpr char uninstall_script[] = R"EOF(
|
constexpr char uninstall_script[] = R"EOF(
|
||||||
PKG=%s
|
PKG=%s
|
||||||
log -t Magisk "apk_uninstall: $PKG"
|
log -t Magisk "pm_uninstall: $PKG"
|
||||||
log -t Magisk "apk_uninstall: $(pm uninstall $PKG 2>&1)"
|
log -t Magisk "pm_uninstall: $(pm uninstall $PKG 2>&1)"
|
||||||
)EOF";
|
)EOF";
|
||||||
|
|
||||||
void uninstall_pkg(const char *pkg) {
|
void uninstall_pkg(const char *pkg) {
|
||||||
@ -182,6 +182,22 @@ void uninstall_pkg(const char *pkg) {
|
|||||||
exec_command_sync(exec, "/system/bin/sh", "-c", cmds);
|
exec_command_sync(exec, "/system/bin/sh", "-c", cmds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constexpr char clear_script[] = R"EOF(
|
||||||
|
PKG=%s
|
||||||
|
USER=%d
|
||||||
|
log -t Magisk "pm_clear: $PKG (user=$USER)"
|
||||||
|
log -t Magisk "pm_clear: $(pm clear --user $USER $PKG 2>&1)"
|
||||||
|
)EOF";
|
||||||
|
|
||||||
|
void clear_pkg(const char *pkg, int user_id) {
|
||||||
|
exec_t exec {
|
||||||
|
.fork = fork_no_orphan
|
||||||
|
};
|
||||||
|
char cmds[sizeof(clear_script) + 288];
|
||||||
|
snprintf(cmds, sizeof(cmds), clear_script, pkg, user_id);
|
||||||
|
exec_command_sync(exec, "/system/bin/sh", "-c", cmds);
|
||||||
|
}
|
||||||
|
|
||||||
[[noreturn]] __printflike(2, 3)
|
[[noreturn]] __printflike(2, 3)
|
||||||
static void abort(FILE *fp, const char *fmt, ...) {
|
static void abort(FILE *fp, const char *fmt, ...) {
|
||||||
va_list valist;
|
va_list valist;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user