Fail on duplicate when activating flattened apexes
Bug: 254172648
Test: ApexTestCases:ApexdMountTest
Change-Id: Ic76d06f8c984fd620a95bddf0cfd14a3d292caa0
diff --git a/apexd/apexd.cpp b/apexd/apexd.cpp
index cd9557e..60fdf83 100644
--- a/apexd/apexd.cpp
+++ b/apexd/apexd.cpp
@@ -3726,6 +3726,7 @@
LOG(INFO) << "ActivateFlattenedApex";
std::vector<com::android::apex::ApexInfo> apex_infos;
+ std::unordered_map<std::string, std::string> apex_names;
for (const std::string& dir : gConfig->apex_built_in_dirs) {
LOG(INFO) << "Scanning " << dir;
@@ -3758,6 +3759,13 @@
continue;
}
+ if (auto it = apex_names.find(manifest->name()); it != apex_names.end()) {
+ LOG(ERROR) << "Failed to activate apex from " << apex_dir
+ << " : duplicate of " << manifest->name() << " found in "
+ << it->second;
+ return 1;
+ }
+
std::string mount_point = std::string(kApexRoot) + "/" + manifest->name();
if (mkdir(mount_point.c_str(), 0755) != 0) {
PLOG(ERROR) << "Failed to mkdir " << mount_point;
@@ -3779,6 +3787,7 @@
/* isFactory= */ true, /* isActive= */ true,
/* lastUpdateMillis= */ 0,
/* provideSharedApexLibs= */ false);
+ apex_names.emplace(manifest->name(), apex_dir);
}
}
diff --git a/apexd/apexd_test.cpp b/apexd/apexd_test.cpp
index 606d1c1..766130d 100644
--- a/apexd/apexd_test.cpp
+++ b/apexd/apexd_test.cpp
@@ -83,6 +83,8 @@
using ::testing::StartsWith;
using ::testing::UnorderedElementsAre;
using ::testing::UnorderedElementsAreArray;
+using ::testing::internal::CaptureStderr;
+using ::testing::internal::GetCapturedStderr;
static std::string GetTestDataDir() { return GetExecutableDirectory(); }
static std::string GetTestFile(const std::string& name) {
@@ -3048,29 +3050,25 @@
ApexInfoXmlEq(apex_info_xml_2)));
}
+void PrepareFlattenedApex(const std::string& apex_dir,
+ const std::string& apex_name, int version) {
+ ASSERT_EQ(mkdir(apex_dir.c_str(), 0755), 0);
+
+ ::apex::proto::ApexManifest manifest;
+ manifest.set_name(apex_name);
+ manifest.set_version(version);
+ manifest.set_versionname(std::to_string(version));
+
+ std::string out;
+ manifest.SerializeToString(&out);
+ ASSERT_TRUE(WriteStringToFile(out, apex_dir + "/apex_manifest.pb"));
+}
+
TEST_F(ApexdMountTest, ActivateFlattenedApex) {
std::string apex_dir_1 = GetBuiltInDir() + "/com.android.apex.test_package";
std::string apex_dir_2 = GetBuiltInDir() + "/com.android.apex.test_package_2";
-
- ASSERT_EQ(mkdir(apex_dir_1.c_str(), 0755), 0);
- ASSERT_EQ(mkdir(apex_dir_2.c_str(), 0755), 0);
-
- auto write_manifest_fn = [&](const std::string& apex_dir,
- const std::string& module_name, int version) {
- using ::apex::proto::ApexManifest;
-
- ApexManifest manifest;
- manifest.set_name(module_name);
- manifest.set_version(version);
- manifest.set_versionname(std::to_string(version));
-
- std::string out;
- manifest.SerializeToString(&out);
- ASSERT_TRUE(WriteStringToFile(out, apex_dir + "/apex_manifest.pb"));
- };
-
- write_manifest_fn(apex_dir_1, "com.android.apex.test_package", 2);
- write_manifest_fn(apex_dir_2, "com.android.apex.test_package_2", 1);
+ PrepareFlattenedApex(apex_dir_1, "com.android.apex.test_package", 2);
+ PrepareFlattenedApex(apex_dir_2, "com.android.apex.test_package_2", 1);
ASSERT_EQ(ActivateFlattenedApex(), 0);
@@ -3108,6 +3106,20 @@
ApexInfoXmlEq(apex_info_xml_2)));
}
+TEST_F(ApexdMountTest, ActivateFlattenedApexShouldFailWithDuplicate) {
+ // Two flattened APEXes with the same name
+ PrepareFlattenedApex(GetBuiltInDir() + "/com.android.apex.test_package",
+ "com.android.apex.test_package", 1);
+ PrepareFlattenedApex(GetBuiltInDir() + "/com.android.apex.test_package_2",
+ "com.android.apex.test_package", 1);
+
+ CaptureStderr();
+ ASSERT_EQ(ActivateFlattenedApex(), 1);
+ std::string error = GetCapturedStderr();
+ ASSERT_THAT(error,
+ HasSubstr("duplicate of com.android.apex.test_package found"));
+}
+
TEST_F(ApexdMountTest, OnStartOnlyPreInstalledApexes) {
MockCheckpointInterface checkpoint_interface;
// Need to call InitializeVold before calling OnStart