mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-11-27 20:15:29 +00:00
Simplify get manager app info logic
This commit is contained in:
parent
82f303e1c6
commit
7b25e74418
@ -106,9 +106,10 @@ static bool magisk_env() {
|
|||||||
LOGI("* Initializing Magisk environment\n");
|
LOGI("* Initializing Magisk environment\n");
|
||||||
|
|
||||||
string pkg;
|
string pkg;
|
||||||
check_manager(&pkg);
|
get_manager(&pkg);
|
||||||
|
|
||||||
sprintf(buf, "%s/0/%s/install", APP_DATA_DIR, pkg.data());
|
sprintf(buf, "%s/0/%s/install", APP_DATA_DIR,
|
||||||
|
pkg.empty() ? "xxx" /* Ensure non-exist path */ : pkg.data());
|
||||||
|
|
||||||
// Alternative binaries paths
|
// Alternative binaries paths
|
||||||
const char *alt_bin[] = { "/cache/data_adb/magisk", "/data/magisk", buf };
|
const char *alt_bin[] = { "/cache/data_adb/magisk", "/data/magisk", buf };
|
||||||
@ -354,7 +355,7 @@ void boot_complete(int client) {
|
|||||||
if (access(SECURE_DIR, F_OK) != 0)
|
if (access(SECURE_DIR, F_OK) != 0)
|
||||||
xmkdir(SECURE_DIR, 0700);
|
xmkdir(SECURE_DIR, 0700);
|
||||||
|
|
||||||
if (!check_manager()) {
|
if (!get_manager()) {
|
||||||
if (access(MANAGERAPK, F_OK) == 0) {
|
if (access(MANAGERAPK, F_OK) == 0) {
|
||||||
// Only try to install APK when no manager is installed
|
// Only try to install APK when no manager is installed
|
||||||
// Magisk Manager should be upgraded by itself, not through recovery installs
|
// Magisk Manager should be upgraded by itself, not through recovery installs
|
||||||
|
@ -341,41 +341,39 @@ int get_uid_policy(su_access &su, int uid) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool check_manager(string *pkg) {
|
bool get_manager(int user_id, std::string *pkg, struct stat *st) {
|
||||||
db_strings str;
|
db_strings str;
|
||||||
get_db_strings(str, SU_MANAGER);
|
get_db_strings(str, SU_MANAGER);
|
||||||
bool ret = validate_manager(str[SU_MANAGER], 0, nullptr);
|
|
||||||
if (pkg) {
|
|
||||||
if (ret)
|
|
||||||
pkg->swap(str[SU_MANAGER]);
|
|
||||||
else
|
|
||||||
*pkg = "xxx"; /* Make sure the return pkg can never exist */
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool validate_manager(string &pkg, int userid, struct stat *st) {
|
|
||||||
struct stat tmp_st;
|
|
||||||
if (st == nullptr)
|
|
||||||
st = &tmp_st;
|
|
||||||
|
|
||||||
// Prefer DE storage
|
|
||||||
char app_path[128];
|
char app_path[128];
|
||||||
sprintf(app_path, "%s/%d/%s", APP_DATA_DIR, userid, pkg.data());
|
|
||||||
if (pkg.empty() || stat(app_path, st)) {
|
if (!str[SU_MANAGER].empty()) {
|
||||||
// Check the official package name
|
// App is repackaged
|
||||||
sprintf(app_path, "%s/%d/" JAVA_PACKAGE_NAME, APP_DATA_DIR, userid);
|
sprintf(app_path, "%s/%d/%s", APP_DATA_DIR, user_id, str[SU_MANAGER].data());
|
||||||
if (stat(app_path, st)) {
|
if (stat(app_path, st) == 0) {
|
||||||
LOGE("su: cannot find manager\n");
|
if (pkg)
|
||||||
memset(st, 0, sizeof(*st));
|
pkg->swap(str[SU_MANAGER]);
|
||||||
pkg.clear();
|
return true;
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
// Switch to official package if exists
|
|
||||||
pkg = JAVA_PACKAGE_NAME;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
|
// Check the official package name
|
||||||
|
sprintf(app_path, "%s/%d/" JAVA_PACKAGE_NAME, APP_DATA_DIR, user_id);
|
||||||
|
if (stat(app_path, st) == 0) {
|
||||||
|
if (pkg)
|
||||||
|
*pkg = JAVA_PACKAGE_NAME;
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
LOGE("su: cannot find manager\n");
|
||||||
|
memset(st, 0, sizeof(*st));
|
||||||
|
if (pkg)
|
||||||
|
pkg->clear();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool get_manager(string *pkg) {
|
||||||
|
struct stat st;
|
||||||
|
return get_manager(0, pkg, &st);
|
||||||
}
|
}
|
||||||
|
|
||||||
void exec_sql(int client) {
|
void exec_sql(int client) {
|
||||||
|
@ -126,8 +126,8 @@ using db_row_cb = std::function<bool(db_row&)>;
|
|||||||
int get_db_settings(db_settings &cfg, int key = -1);
|
int get_db_settings(db_settings &cfg, int key = -1);
|
||||||
int get_db_strings(db_strings &str, int key = -1);
|
int get_db_strings(db_strings &str, int key = -1);
|
||||||
int get_uid_policy(su_access &su, int uid);
|
int get_uid_policy(su_access &su, int uid);
|
||||||
bool check_manager(std::string *pkg = nullptr);
|
bool get_manager(int user_id, std::string *pkg, struct stat *st);
|
||||||
bool validate_manager(std::string &pkg, int userid, struct stat *st);
|
bool get_manager(std::string *pkg = nullptr);
|
||||||
void exec_sql(int client);
|
void exec_sql(int client);
|
||||||
char *db_exec(const char *sql);
|
char *db_exec(const char *sql);
|
||||||
char *db_exec(const char *sql, const db_row_cb &fn);
|
char *db_exec(const char *sql, const db_row_cb &fn);
|
||||||
|
@ -106,7 +106,7 @@ static void exec_cmd(const char *action, vector<Extra> &data,
|
|||||||
|
|
||||||
// First try content provider call method
|
// First try content provider call method
|
||||||
if (mode >= CONTENT_PROVIDER) {
|
if (mode >= CONTENT_PROVIDER) {
|
||||||
sprintf(target, "content://%s.provider", info->str[SU_MANAGER].data());
|
sprintf(target, "content://%s.provider", info->mgr_pkg.data());
|
||||||
vector<const char *> args{ CALL_PROVIDER };
|
vector<const char *> args{ CALL_PROVIDER };
|
||||||
for (auto &e : data) {
|
for (auto &e : data) {
|
||||||
e.add_bind(args);
|
e.add_bind(args);
|
||||||
@ -137,7 +137,7 @@ static void exec_cmd(const char *action, vector<Extra> &data,
|
|||||||
|
|
||||||
if (mode >= PKG_ACTIVITY) {
|
if (mode >= PKG_ACTIVITY) {
|
||||||
// Then try start activity without component name
|
// Then try start activity without component name
|
||||||
strcpy(target, info->str[SU_MANAGER].data());
|
strcpy(target, info->mgr_pkg.data());
|
||||||
exec_command_sync(exec);
|
exec_command_sync(exec);
|
||||||
if (check_no_error(exec.fd))
|
if (check_no_error(exec.fd))
|
||||||
return;
|
return;
|
||||||
@ -145,7 +145,7 @@ static void exec_cmd(const char *action, vector<Extra> &data,
|
|||||||
|
|
||||||
// Finally, fallback to start activity with component name
|
// Finally, fallback to start activity with component name
|
||||||
args[4] = "-n";
|
args[4] = "-n";
|
||||||
sprintf(target, "%s/.ui.surequest.SuRequestActivity", info->str[SU_MANAGER].data());
|
sprintf(target, "%s/.ui.surequest.SuRequestActivity", info->mgr_pkg.data());
|
||||||
exec.fd = -2;
|
exec.fd = -2;
|
||||||
exec.fork = fork_dont_care;
|
exec.fork = fork_dont_care;
|
||||||
exec_command(exec);
|
exec_command(exec);
|
||||||
|
@ -20,8 +20,8 @@ public:
|
|||||||
|
|
||||||
/* These should be guarded with internal lock */
|
/* These should be guarded with internal lock */
|
||||||
db_settings cfg;
|
db_settings cfg;
|
||||||
db_strings str;
|
|
||||||
su_access access;
|
su_access access;
|
||||||
|
std::string mgr_pkg;
|
||||||
struct stat mgr_st;
|
struct stat mgr_st;
|
||||||
|
|
||||||
/* This should be guarded with global cache lock */
|
/* This should be guarded with global cache lock */
|
||||||
|
@ -47,18 +47,17 @@ void su_info::refresh() {
|
|||||||
static void database_check(const shared_ptr<su_info> &info) {
|
static void database_check(const shared_ptr<su_info> &info) {
|
||||||
int uid = info->uid;
|
int uid = info->uid;
|
||||||
get_db_settings(info->cfg);
|
get_db_settings(info->cfg);
|
||||||
get_db_strings(info->str);
|
|
||||||
|
|
||||||
// Check multiuser settings
|
// Check multiuser settings
|
||||||
switch (info->cfg[SU_MULTIUSER_MODE]) {
|
switch (info->cfg[SU_MULTIUSER_MODE]) {
|
||||||
case MULTIUSER_MODE_OWNER_ONLY:
|
case MULTIUSER_MODE_OWNER_ONLY:
|
||||||
if (info->uid / 100000) {
|
if (to_user_id(uid) != 0) {
|
||||||
uid = -1;
|
uid = -1;
|
||||||
info->access = NO_SU_ACCESS;
|
info->access = NO_SU_ACCESS;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MULTIUSER_MODE_OWNER_MANAGED:
|
case MULTIUSER_MODE_OWNER_MANAGED:
|
||||||
uid = info->uid % 100000;
|
uid = to_app_id(uid);
|
||||||
break;
|
break;
|
||||||
case MULTIUSER_MODE_USER:
|
case MULTIUSER_MODE_USER:
|
||||||
default:
|
default:
|
||||||
@ -70,7 +69,7 @@ static void database_check(const shared_ptr<su_info> &info) {
|
|||||||
|
|
||||||
// We need to check our manager
|
// We need to check our manager
|
||||||
if (info->access.log || info->access.notify)
|
if (info->access.log || info->access.notify)
|
||||||
validate_manager(info->str[SU_MANAGER], uid / 100000, &info->mgr_st);
|
get_manager(to_user_id(uid), &info->mgr_pkg, &info->mgr_st);
|
||||||
}
|
}
|
||||||
|
|
||||||
static shared_ptr<su_info> get_su_info(unsigned uid) {
|
static shared_ptr<su_info> get_su_info(unsigned uid) {
|
||||||
@ -93,7 +92,7 @@ static shared_ptr<su_info> get_su_info(unsigned uid) {
|
|||||||
database_check(info);
|
database_check(info);
|
||||||
|
|
||||||
// If it's root or the manager, allow it silently
|
// If it's root or the manager, allow it silently
|
||||||
if (info->uid == UID_ROOT || (info->uid % 100000) == (info->mgr_st.st_uid % 100000)) {
|
if (info->uid == UID_ROOT || to_app_id(info->uid) == to_app_id(info->mgr_st.st_uid)) {
|
||||||
info->access = SILENT_SU_ACCESS;
|
info->access = SILENT_SU_ACCESS;
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
@ -125,7 +124,7 @@ static shared_ptr<su_info> get_su_info(unsigned uid) {
|
|||||||
return info;
|
return info;
|
||||||
|
|
||||||
// If still not determined, check if manager exists
|
// If still not determined, check if manager exists
|
||||||
if (info->str[SU_MANAGER].empty()) {
|
if (info->mgr_pkg.empty()) {
|
||||||
info->access = NO_SU_ACCESS;
|
info->access = NO_SU_ACCESS;
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,9 @@
|
|||||||
clazz(const clazz &) = delete; \
|
clazz(const clazz &) = delete; \
|
||||||
clazz(clazz &&) = delete;
|
clazz(clazz &&) = delete;
|
||||||
|
|
||||||
|
#define to_app_id(uid) (uid % 100000)
|
||||||
|
#define to_user_id(uid) (uid / 100000)
|
||||||
|
|
||||||
class mutex_guard {
|
class mutex_guard {
|
||||||
DISALLOW_COPY_AND_MOVE(mutex_guard)
|
DISALLOW_COPY_AND_MOVE(mutex_guard)
|
||||||
public:
|
public:
|
||||||
|
Loading…
Reference in New Issue
Block a user