lazy-update app data path in ConfigManager::IsAppNeedHook()
zygote always starts with `uid == 0` and then fork into a different user. so we delay the evaluation until we get to the point where it's been hooked already. this enabled multi-user support, since we can now find the config files!
This commit is contained in:
parent
efe0869390
commit
db5d51483d
|
|
@ -35,8 +35,7 @@ namespace edxp {
|
||||||
LOGI("using installer %s", kLegacyInstallerPkgName);
|
LOGI("using installer %s", kLegacyInstallerPkgName);
|
||||||
return kLegacyInstallerPkgName;
|
return kLegacyInstallerPkgName;
|
||||||
}
|
}
|
||||||
LOGE("no supported installer app found, using primary as default %s",
|
LOGE("no supported installer app found, using default: %s", kPrimaryInstallerPkgName);
|
||||||
kPrimaryInstallerPkgName);
|
|
||||||
return kPrimaryInstallerPkgName;
|
return kPrimaryInstallerPkgName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -48,7 +47,7 @@ namespace edxp {
|
||||||
while ((dent = readdir(dir)) != nullptr) {
|
while ((dent = readdir(dir)) != nullptr) {
|
||||||
if (dent->d_type == DT_REG) {
|
if (dent->d_type == DT_REG) {
|
||||||
const char *fileName = dent->d_name;
|
const char *fileName = dent->d_name;
|
||||||
LOGI("whitelist: %s", fileName);
|
LOGI(" whitelist: %s", fileName);
|
||||||
white_list_default_.emplace_back(fileName);
|
white_list_default_.emplace_back(fileName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -59,7 +58,7 @@ namespace edxp {
|
||||||
while ((dent = readdir(dir)) != nullptr) {
|
while ((dent = readdir(dir)) != nullptr) {
|
||||||
if (dent->d_type == DT_REG) {
|
if (dent->d_type == DT_REG) {
|
||||||
const char *fileName = dent->d_name;
|
const char *fileName = dent->d_name;
|
||||||
LOGI("blacklist: %s", fileName);
|
LOGI(" blacklist: %s", fileName);
|
||||||
black_list_default_.emplace_back(fileName);
|
black_list_default_.emplace_back(fileName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -67,10 +66,16 @@ namespace edxp {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigManager::InitOnce() {
|
void ConfigManager::UpdateConfigPath(const uid_t user) {
|
||||||
if (!initialized_) {
|
if (last_user_ != user) {
|
||||||
use_prot_storage_ = GetAndroidApiLevel() >= ANDROID_N;
|
LOGI("updating config data paths from %u to %u...", last_user_, user);
|
||||||
data_path_prefix_ = use_prot_storage_ ? "/data/user_de/0/" : "/data/user/0/";
|
last_user_ = user;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *format = use_prot_storage_ ? "/data/user_de/%u/" : "/data/user/%u/";
|
||||||
|
char buff[PATH_MAX];
|
||||||
|
snprintf(buff, sizeof(buff), format, last_user_);
|
||||||
|
data_path_prefix_ = buff;
|
||||||
|
|
||||||
installer_pkg_name_ = RetrieveInstallerPkgName();
|
installer_pkg_name_ = RetrieveInstallerPkgName();
|
||||||
base_config_path_ = GetConfigPath("");
|
base_config_path_ = GetConfigPath("");
|
||||||
|
|
@ -86,20 +91,35 @@ namespace edxp {
|
||||||
|
|
||||||
// use_white_list snapshot
|
// use_white_list snapshot
|
||||||
use_white_list_snapshot_ = access(use_whitelist_path_.c_str(), F_OK) == 0;
|
use_white_list_snapshot_ = access(use_whitelist_path_.c_str(), F_OK) == 0;
|
||||||
LOGI("application list mode: %s, using whitelist: %s",
|
LOGI("data path prefix: %s", data_path_prefix_.c_str());
|
||||||
BoolToString(black_white_list_enabled_), BoolToString(use_white_list_snapshot_));
|
LOGI(" application list mode: %s", BoolToString(black_white_list_enabled_));
|
||||||
LOGI("dynamic modules mode: %s", BoolToString(dynamic_modules_enabled_));
|
LOGI(" using whitelist: %s", BoolToString(use_white_list_snapshot_));
|
||||||
LOGI("resources hook: %s", BoolToString(resources_hook_enabled_));
|
LOGI(" dynamic modules mode: %s", BoolToString(dynamic_modules_enabled_));
|
||||||
LOGI("deopt boot image: %s", BoolToString(deopt_boot_image_enabled_));
|
LOGI(" resources hook: %s", BoolToString(resources_hook_enabled_));
|
||||||
LOGI("no module log: %s", BoolToString(no_module_log_enabled_));
|
LOGI(" deopt boot image: %s", BoolToString(deopt_boot_image_enabled_));
|
||||||
|
LOGI(" no module log: %s", BoolToString(no_module_log_enabled_));
|
||||||
if (black_white_list_enabled_) {
|
if (black_white_list_enabled_) {
|
||||||
SnapshotBlackWhiteList();
|
SnapshotBlackWhiteList();
|
||||||
}
|
}
|
||||||
initialized_ = true;
|
}
|
||||||
|
|
||||||
|
bool ConfigManager::IsAppNeedHook(const std::string &app_data_dir) {
|
||||||
|
// zygote always starts with `uid == 0` and then fork into different user.
|
||||||
|
// so we have to check if we are the correct user or not.
|
||||||
|
uid_t user = 0;
|
||||||
|
char package_name[PATH_MAX];
|
||||||
|
if (sscanf(app_data_dir.c_str(), "/data/%*[^/]/%u/%s", &user, package_name) != 2) {
|
||||||
|
if (sscanf(app_data_dir.c_str(), "/data/%*[^/]/%s", package_name) != 1) {
|
||||||
|
package_name[0] = '\0';
|
||||||
|
LOGE("can't parse %s", app_data_dir.c_str());
|
||||||
|
return false; // default to no hooking for safety
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ConfigManager::IsAppNeedHook(const std::string &app_data_dir) const {
|
if (last_user_ != user) {
|
||||||
|
UpdateConfigPath(user);
|
||||||
|
}
|
||||||
|
|
||||||
if (!black_white_list_enabled_) {
|
if (!black_white_list_enabled_) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -112,15 +132,6 @@ namespace edxp {
|
||||||
app_data_dir.c_str());
|
app_data_dir.c_str());
|
||||||
use_white_list = use_white_list_snapshot_;
|
use_white_list = use_white_list_snapshot_;
|
||||||
}
|
}
|
||||||
int user = 0;
|
|
||||||
char package_name[PATH_MAX];
|
|
||||||
if (sscanf(app_data_dir.c_str(), "/data/%*[^/]/%d/%s", &user, package_name) != 2) {
|
|
||||||
if (sscanf(app_data_dir.c_str(), "/data/%*[^/]/%s", package_name) != 1) {
|
|
||||||
package_name[0] = '\0';
|
|
||||||
LOGE("can't parse %s", app_data_dir.c_str());
|
|
||||||
return !use_white_list;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (strcmp(package_name, kPrimaryInstallerPkgName) == 0
|
if (strcmp(package_name, kPrimaryInstallerPkgName) == 0
|
||||||
|| strcmp(package_name, kLegacyInstallerPkgName) == 0) {
|
|| strcmp(package_name, kLegacyInstallerPkgName) == 0) {
|
||||||
// always hook installer apps
|
// always hook installer apps
|
||||||
|
|
@ -185,11 +196,9 @@ namespace edxp {
|
||||||
};
|
};
|
||||||
|
|
||||||
ConfigManager::ConfigManager() {
|
ConfigManager::ConfigManager() {
|
||||||
InitOnce();
|
use_prot_storage_ = GetAndroidApiLevel() >= ANDROID_N;
|
||||||
}
|
last_user_ = 0;
|
||||||
|
UpdateConfigPath(last_user_);
|
||||||
ConfigManager::~ConfigManager() {
|
|
||||||
initialized_ = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -22,20 +22,26 @@ namespace edxp {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsBlackWhiteListEnabled() const;
|
bool IsBlackWhiteListEnabled() const;
|
||||||
|
|
||||||
bool IsDynamicModulesEnabled() const;
|
bool IsDynamicModulesEnabled() const;
|
||||||
|
|
||||||
bool IsResourcesHookEnabled() const;
|
bool IsResourcesHookEnabled() const;
|
||||||
|
|
||||||
bool IsDeoptBootImageEnabled() const;
|
bool IsDeoptBootImageEnabled() const;
|
||||||
|
|
||||||
bool IsNoModuleLogEnabled() const;
|
bool IsNoModuleLogEnabled() const;
|
||||||
|
|
||||||
std::string GetInstallerPackageName() const;
|
std::string GetInstallerPackageName() const;
|
||||||
|
|
||||||
std::string GetDataPathPrefix() const;
|
std::string GetDataPathPrefix() const;
|
||||||
|
|
||||||
std::string GetConfigPath(const std::string &suffix) const;
|
std::string GetConfigPath(const std::string &suffix) const;
|
||||||
|
|
||||||
bool IsAppNeedHook(const std::string &app_data_dir) const;
|
bool IsAppNeedHook(const std::string &app_data_dir);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
inline static ConfigManager *instance_;
|
inline static ConfigManager *instance_;
|
||||||
bool initialized_ = false;
|
uid_t last_user_ = false;
|
||||||
bool use_prot_storage_ = true;
|
bool use_prot_storage_ = true;
|
||||||
std::string data_path_prefix_;
|
std::string data_path_prefix_;
|
||||||
std::string installer_pkg_name_;
|
std::string installer_pkg_name_;
|
||||||
|
|
@ -55,9 +61,7 @@ namespace edxp {
|
||||||
|
|
||||||
ConfigManager();
|
ConfigManager();
|
||||||
|
|
||||||
~ConfigManager();
|
void UpdateConfigPath(const uid_t user);
|
||||||
|
|
||||||
void InitOnce();
|
|
||||||
|
|
||||||
void SnapshotBlackWhiteList();
|
void SnapshotBlackWhiteList();
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue