mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-12-24 20:47:38 +00:00
Proper get_manager implementation
This commit is contained in:
parent
34dded3b25
commit
a29ae15ff7
@ -359,6 +359,14 @@ int get_db_strings(db_strings &str, int key) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void rm_db_strings(int key) {
|
||||||
|
char *err;
|
||||||
|
char query[128];
|
||||||
|
snprintf(query, sizeof(query), "DELETE FROM strings WHERE key == '%s'", DB_STRING_KEYS[key]);
|
||||||
|
err = db_exec(query);
|
||||||
|
db_err_cmd(err, return);
|
||||||
|
}
|
||||||
|
|
||||||
void exec_sql(int client) {
|
void exec_sql(int client) {
|
||||||
run_finally f([=]{ close(client); });
|
run_finally f([=]{ close(client); });
|
||||||
string sql = read_string(client);
|
string sql = read_string(client);
|
||||||
|
@ -62,7 +62,7 @@ vector<bool> get_app_no_list() {
|
|||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
int get_manager(int user_id, std::string *pkg) {
|
int get_manager(int user_id, string *pkg) {
|
||||||
mutex_guard g(pkg_lock);
|
mutex_guard g(pkg_lock);
|
||||||
|
|
||||||
char app_path[128];
|
char app_path[128];
|
||||||
@ -73,42 +73,103 @@ int get_manager(int user_id, std::string *pkg) {
|
|||||||
int app_id = mgr_app_id;
|
int app_id = mgr_app_id;
|
||||||
if (app_id > 0) {
|
if (app_id > 0) {
|
||||||
// Just need to check whether the app is installed in the user
|
// Just need to check whether the app is installed in the user
|
||||||
snprintf(app_path, sizeof(app_path), "%s/%d/%s", APP_DATA_DIR, user_id, 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);
|
||||||
if (access(app_path, F_OK) == 0) {
|
if (access(app_path, F_OK) == 0) {
|
||||||
if (pkg) *pkg = *mgr_pkg;
|
if (pkg) *pkg = name;
|
||||||
return user_id * AID_USER_OFFSET + app_id;
|
return user_id * AID_USER_OFFSET + app_id;
|
||||||
} else {
|
} else {
|
||||||
goto not_found;
|
goto not_found;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// Here, we want to actually find the manager app and cache the results.
|
||||||
|
// This means that we check all users, not just the requested user.
|
||||||
|
// We also do a validation on whether the repackaged APK is still installed.
|
||||||
|
|
||||||
db_strings str;
|
db_strings str;
|
||||||
get_db_strings(str, SU_MANAGER);
|
get_db_strings(str, SU_MANAGER);
|
||||||
|
|
||||||
if (!str[SU_MANAGER].empty()) {
|
vector<int> users;
|
||||||
// App is repackaged
|
bool collected = false;
|
||||||
snprintf(app_path, sizeof(app_path),
|
|
||||||
"%s/%d/%s", APP_DATA_DIR, user_id, str[SU_MANAGER].data());
|
auto collect_users = [&] {
|
||||||
if (stat(app_path, &st) == 0) {
|
if (collected)
|
||||||
mgr_pkg->swap(str[SU_MANAGER]);
|
return;
|
||||||
|
collected = true;
|
||||||
|
auto data_dir = xopen_dir(APP_DATA_DIR);
|
||||||
|
if (!data_dir)
|
||||||
|
return;
|
||||||
|
dirent *entry;
|
||||||
|
while ((entry = xreaddir(data_dir.get()))) {
|
||||||
|
// Only collect users not requested as we've already checked it
|
||||||
|
if (int u = parse_int(entry->d_name); u >= 0 && u != user_id)
|
||||||
|
users.push_back(parse_int(entry->d_name));
|
||||||
}
|
}
|
||||||
} else {
|
};
|
||||||
// Check the original package name
|
|
||||||
snprintf(app_path, sizeof(app_path), "%s/%d/" JAVA_PACKAGE_NAME, APP_DATA_DIR, user_id);
|
if (!str[SU_MANAGER].empty()) {
|
||||||
|
// Check the repackaged package name
|
||||||
|
|
||||||
|
auto check_pkg = [&](int u) -> bool {
|
||||||
|
snprintf(app_path, sizeof(app_path),
|
||||||
|
"%s/%d/%s", APP_DATA_DIR, u, str[SU_MANAGER].data());
|
||||||
|
if (stat(app_path, &st) == 0) {
|
||||||
|
mgr_pkg->swap(str[SU_MANAGER]);
|
||||||
|
mgr_app_id = to_app_id(st.st_uid);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (check_pkg(user_id)) {
|
||||||
|
if (pkg) *pkg = *mgr_pkg;
|
||||||
|
return st.st_uid;
|
||||||
|
}
|
||||||
|
collect_users();
|
||||||
|
for (int u : users) {
|
||||||
|
if (check_pkg(u)) {
|
||||||
|
// Found repackaged app, but not installed in the requested user
|
||||||
|
goto not_found;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Repackaged app not found, remove package from db
|
||||||
|
rm_db_strings(SU_MANAGER);
|
||||||
|
|
||||||
|
// Fallthrough
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check the original package name
|
||||||
|
|
||||||
|
auto check_pkg = [&](int u) -> bool {
|
||||||
|
snprintf(app_path, sizeof(app_path), "%s/%d/" JAVA_PACKAGE_NAME, APP_DATA_DIR, u);
|
||||||
if (stat(app_path, &st) == 0) {
|
if (stat(app_path, &st) == 0) {
|
||||||
*mgr_pkg = JAVA_PACKAGE_NAME;
|
mgr_pkg->clear();
|
||||||
} else {
|
mgr_app_id = to_app_id(st.st_uid);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (check_pkg(user_id)) {
|
||||||
|
if (pkg) *pkg = JAVA_PACKAGE_NAME;
|
||||||
|
return st.st_uid;
|
||||||
|
}
|
||||||
|
collect_users();
|
||||||
|
for (int u : users) {
|
||||||
|
if (check_pkg(u)) {
|
||||||
|
// Found app, but not installed in the requested user
|
||||||
goto not_found;
|
goto not_found;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// No manager app is found, clear all cached value
|
||||||
|
mgr_app_id = -1;
|
||||||
|
mgr_pkg->clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
mgr_app_id = to_app_id(st.st_uid);
|
|
||||||
if (pkg) *pkg = *mgr_pkg;
|
|
||||||
return st.st_uid;
|
|
||||||
|
|
||||||
not_found:
|
not_found:
|
||||||
LOGE("su: cannot find manager\n");
|
LOGE("su: cannot find manager for user=[%d]\n", user_id);
|
||||||
if (pkg)
|
if (pkg) pkg->clear();
|
||||||
pkg->clear();
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -125,6 +125,7 @@ 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);
|
||||||
|
void rm_db_strings(int key);
|
||||||
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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user