Install stub if necessary

This commit is contained in:
topjohnwu 2022-05-19 22:54:49 -07:00
parent a29ae15ff7
commit 351f0269ae
6 changed files with 46 additions and 32 deletions

View File

@ -445,8 +445,8 @@ def setup_ndk(args):
def setup_avd(args):
if not args.skip:
build_binary(args)
build_app(args)
args.release = False
build_all(args)
header('* Setting up emulator')
@ -463,8 +463,8 @@ def setup_avd(args):
def patch_avd_ramdisk(args):
if not args.skip:
build_binary(args)
build_app(args)
args.release = False
build_all(args)
header('* Patching emulator ramdisk.img')

View File

@ -18,7 +18,6 @@
using namespace std;
static bool safe_mode = false;
static int stub_fd = -1;
bool zygisk_enabled = false;
/*********
@ -123,10 +122,7 @@ static bool magisk_env() {
LOGI("* Initializing Magisk environment\n");
string stub_path = MAGISKTMP + "/stub.apk";
stub_fd = xopen(stub_path.data(), O_RDONLY | O_CLOEXEC);
unlink(stub_path.data());
preserve_stub_apk();
string pkg;
get_manager(0, &pkg);
@ -375,18 +371,6 @@ void boot_complete(int client) {
if (access(SECURE_DIR, F_OK) != 0)
xmkdir(SECURE_DIR, 0700);
if (stub_fd > 0) {
if (get_manager() < 0) {
// Install stub
struct stat st{};
fstat(stub_fd, &st);
char apk[] = "/data/stub.apk";
int dfd = xopen(apk, O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, 0600);
xsendfile(dfd, stub_fd, nullptr, st.st_size);
close(dfd);
install_apk(apk);
}
close(stub_fd);
stub_fd = -1;
}
// Ensure manager exists
get_manager(0, nullptr, true);
}

View File

@ -3,6 +3,8 @@
#include <daemon.hpp>
#include <db.hpp>
#include "core.hpp"
using namespace std;
// These functions will be called on every single zygote process specialization and su request,
@ -10,11 +12,13 @@ using namespace std;
// or simply skipped unless necessary.
static atomic<ino_t> pkg_xml_ino = 0;
static atomic_flag skip_check;
// pkg_lock protects mgr_app_id and mgr_pkg
static pthread_mutex_t pkg_lock = PTHREAD_MUTEX_INITIALIZER;
// pkg_lock protects all following variables
static int mgr_app_id = -1;
static string *mgr_pkg;
static int stub_apk_fd = -1;
bool need_pkg_refresh() {
struct stat st{};
@ -24,8 +28,7 @@ bool need_pkg_refresh() {
// Packages have not changed
return false;
} else {
mutex_guard g(pkg_lock);
mgr_app_id = -1;
skip_check.clear();
return true;
}
}
@ -62,7 +65,27 @@ vector<bool> get_app_no_list() {
return list;
}
int get_manager(int user_id, string *pkg) {
void preserve_stub_apk() {
mutex_guard g(pkg_lock);
string stub_path = MAGISKTMP + "/stub.apk";
stub_apk_fd = xopen(stub_path.data(), O_RDONLY | O_CLOEXEC);
unlink(stub_path.data());
}
static void install_stub() {
if (stub_apk_fd < 0)
return;
struct stat st{};
fstat(stub_apk_fd, &st);
char apk[] = "/data/stub.apk";
int dfd = xopen(apk, O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, 0600);
xsendfile(dfd, stub_apk_fd, nullptr, st.st_size);
lseek(stub_apk_fd, 0, SEEK_SET);
close(dfd);
install_apk(apk);
}
int get_manager(int user_id, string *pkg, bool install) {
mutex_guard g(pkg_lock);
char app_path[128];
@ -70,14 +93,16 @@ int get_manager(int user_id, string *pkg) {
if (mgr_pkg == nullptr)
default_new(mgr_pkg);
int app_id = mgr_app_id;
if (app_id > 0) {
if (skip_check.test_and_set()) {
if (mgr_app_id < 0) {
goto not_found;
}
// Just need to check whether the app is installed in the user
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);
if (access(app_path, F_OK) == 0) {
if (pkg) *pkg = name;
return user_id * AID_USER_OFFSET + app_id;
return user_id * AID_USER_OFFSET + mgr_app_id;
} else {
goto not_found;
}
@ -166,6 +191,8 @@ int get_manager(int user_id, string *pkg) {
// No manager app is found, clear all cached value
mgr_app_id = -1;
mgr_pkg->clear();
if (install)
install_stub();
}
not_found:

View File

@ -86,9 +86,10 @@ void su_daemon_handler(int client, const sock_cred *cred);
void zygisk_handler(int client, const sock_cred *cred);
// Package
void preserve_stub_apk();
bool need_pkg_refresh();
std::vector<bool> get_app_no_list();
int get_manager(int user_id = 0, std::string *pkg = nullptr);
int get_manager(int user_id = 0, std::string *pkg = nullptr, bool install = false);
// Denylist
void initialize_denylist();

View File

@ -82,7 +82,7 @@ void su_info::check_db() {
// We need to check our manager
if (access.log || access.notify)
mgr_uid = get_manager(to_user_id(eval_uid), &mgr_pkg);
mgr_uid = get_manager(to_user_id(eval_uid), &mgr_pkg, true);
}
bool uid_granted_root(int uid) {

View File

@ -139,6 +139,8 @@ ln -s ./magisk $MAGISKTMP/resetprop
ln -s ./magisk $MAGISKTMP/magiskhide
ln -s ./magiskpolicy $MAGISKTMP/supolicy
./magiskinit -x manager $MAGISKTMP/stub.apk
mkdir -p $MAGISKTMP/.magisk/mirror
mkdir $MAGISKTMP/.magisk/block
touch $MAGISKTMP/.magisk/config