OSDN Git Service

Adjust the validation code for secondary dex paths
authorCalin Juravle <calin@google.com>
Mon, 11 Sep 2017 18:50:36 +0000 (11:50 -0700)
committerCalin Juravle <calin@google.com>
Wed, 13 Sep 2017 15:46:43 +0000 (08:46 -0700)
Do not validate the package path when reconciling secondary dex files. If
the file does not exist we cannot resolve the system sym links (e.g.
/data/user/0 -> /data/data) and the validation will fail leaving oat files
behind.

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: I9734ad18a579d44088180326661d8cf8288e90be

cmds/installd/dexopt.cpp
cmds/installd/utils.cpp
cmds/installd/utils.h

index 3c4a933..f29da17 100644 (file)
@@ -1796,8 +1796,14 @@ bool reconcile_secondary_dex_file(const std::string& dex_path,
     }
 
     const char* volume_uuid_cstr = volume_uuid == nullptr ? nullptr : volume_uuid->c_str();
+
+    // Note that we cannot validate the package path here because the file might not exist
+    // and we cannot call realpath to resolve system symlinks. Since /data/user/0 symlinks to
+    // /data/data/ a lot of validations will fail if we attempt to check the package path.
+    // It is still ok to be more relaxed because any file removal is done after forking and
+    // dropping capabilities.
     if (!validate_secondary_dex_path(pkgname.c_str(), dex_path.c_str(), volume_uuid_cstr,
-            uid, storage_flag)) {
+            uid, storage_flag, /*validate_package_path*/ false)) {
         LOG(ERROR) << "Could not validate secondary dex path " << dex_path;
         return false;
     }
index d277bd3..dd32ac6 100644 (file)
@@ -801,7 +801,7 @@ int validate_system_app_path(const char* path) {
 }
 
 bool validate_secondary_dex_path(const std::string& pkgname, const std::string& dex_path,
-        const char* volume_uuid, int uid, int storage_flag) {
+        const char* volume_uuid, int uid, int storage_flag, bool validate_package_path) {
     CHECK(storage_flag == FLAG_STORAGE_CE || storage_flag == FLAG_STORAGE_DE);
 
     // Empty paths are not allowed.
@@ -815,15 +815,18 @@ bool validate_secondary_dex_path(const std::string& pkgname, const std::string&
     // The path should be at most PKG_PATH_MAX long.
     if (dex_path.size() > PKG_PATH_MAX) { return false; }
 
-    // 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) {
-        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
+            ? 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) {
+            return false;
+        }
     }
 
     // If we got here we have a valid path.
index da3a293..e938042 100644 (file)
@@ -125,7 +125,7 @@ std::string read_path_inode(const std::string& parent, const char* name, const c
 
 int validate_system_app_path(const char* path);
 bool validate_secondary_dex_path(const std::string& pkgname, const std::string& dex_path,
-        const char* volume_uuid, int uid, int storage_flag);
+        const char* volume_uuid, int uid, int storage_flag, bool validate_package_path = true);
 
 int get_path_from_env(dir_rec_t* rec, const char* var);