Move secondary dex files processing in the app process
Run the validation and processing of secondary dex files with the app
process capabilities. This drops the need to validate/use real paths since
all file tests and accesses is done now with lower privileges.
The oat files and profiles are now created relative to the given path
instead of using realpath. This allows us to always know where the
compiler artifacts are even if the original dex file was deleted. It
enables a straightforward clean up during reconciliation.
The validation will accept /data/user/0 as a valid secondary dex path
since for user 0 this is the location that will be used most of the times.
This CL also adds a test framework for dexopt related functionality.
The current tests only cover the secondary dex files with more to come.
Bug: 64460009
Test: adb shell cmd package reconcile-secondary-dex-files
com.google.android.googlequicksearchbox (after removing some files)
adb shell cmd package compile -m speed --secondary-dex
com.google.android.googlequicksearchbox
adb shell /data/nativetest64/installd_utils_test/installd_utils_test
Change-Id: I0d49cd7f3c089bc5156178680bb29b75ab82092c
diff --git a/cmds/installd/utils.cpp b/cmds/installd/utils.cpp
index ca0a82e..7dca7c6 100644
--- a/cmds/installd/utils.cpp
+++ b/cmds/installd/utils.cpp
@@ -87,6 +87,20 @@
create_data_user_ce_path(volume_uuid, user).c_str(), package_name);
}
+/**
+ * Create the path name where package data should be stored for the given
+ * volume UUID, package name, and user ID. An empty UUID is assumed to be
+ * internal storage.
+ * Compared to create_data_user_ce_package_path this method always return the
+ * ".../user/..." directory.
+ */
+std::string create_data_user_ce_package_path_as_user_link(
+ const char* volume_uuid, userid_t userid, const char* package_name) {
+ check_package_name(package_name);
+ std::string data(create_data_path(volume_uuid));
+ return StringPrintf("%s/user/%u/%s", data.c_str(), userid, package_name);
+}
+
std::string create_data_user_ce_package_path(const char* volume_uuid, userid_t user,
const char* package_name, ino_t ce_data_inode) {
// For testing purposes, rely on the inode when defined; this could be
@@ -786,7 +800,7 @@
}
bool validate_secondary_dex_path(const std::string& pkgname, const std::string& dex_path,
- const char* volume_uuid, int uid, int storage_flag, bool validate_package_path) {
+ const char* volume_uuid, int uid, int storage_flag) {
CHECK(storage_flag == FLAG_STORAGE_CE || storage_flag == FLAG_STORAGE_DE);
// Empty paths are not allowed.
@@ -800,16 +814,20 @@
// The path should be at most PKG_PATH_MAX long.
if (dex_path.size() > PKG_PATH_MAX) { return false; }
- if (validate_package_path) {
- // If we are asked to validate the package path check that
- // the dex_path is under the app data directory.
- std::string app_private_dir = storage_flag == FLAG_STORAGE_CE
+ // The dex_path should be under the app data directory.
+ std::string app_private_dir = storage_flag == FLAG_STORAGE_CE
? create_data_user_ce_package_path(
volume_uuid, multiuser_get_user_id(uid), pkgname.c_str())
: create_data_user_de_package_path(
volume_uuid, multiuser_get_user_id(uid), pkgname.c_str());
- if (strncmp(dex_path.c_str(), app_private_dir.c_str(), app_private_dir.size()) != 0) {
+ if (strncmp(dex_path.c_str(), app_private_dir.c_str(), app_private_dir.size()) != 0) {
+ // The check above might fail if the dex file is accessed via the /data/user/0 symlink.
+ // If that's the case, attempt to validate against the user data link.
+ std::string app_private_dir_symlink = create_data_user_ce_package_path_as_user_link(
+ volume_uuid, multiuser_get_user_id(uid), pkgname.c_str());
+ if (strncmp(dex_path.c_str(), app_private_dir_symlink.c_str(),
+ app_private_dir_symlink.size()) != 0) {
return false;
}
}