Loading cmds/idmap2/libidmap2/Idmap.cpp +18 −3 Original line number Diff line number Diff line Loading @@ -287,11 +287,20 @@ std::unique_ptr<const Idmap> Idmap::FromBinaryStream(std::istream& stream, bool CheckOverlayable(const LoadedPackage& target_package, const utils::OverlayManifestInfo& overlay_info, const PolicyBitmask& fulfilled_policies, const ResourceId& resid) { static constexpr const PolicyBitmask sDefaultPolicies = PolicyFlags::POLICY_SYSTEM_PARTITION | PolicyFlags::POLICY_VENDOR_PARTITION | PolicyFlags::POLICY_PRODUCT_PARTITION | PolicyFlags::POLICY_SIGNATURE; // If the resource does not have an overlayable definition, allow the resource to be overlaid if // the overlay is preinstalled or signed with the same signature as the target. if (!target_package.DefinesOverlayable()) { return (sDefaultPolicies & fulfilled_policies) != 0; } const OverlayableInfo* overlayable_info = target_package.GetOverlayableInfo(resid); if (overlayable_info == nullptr) { // If the resource does not have an overlayable definition, allow the resource to be overlaid. // Once overlayable enforcement is turned on, this check will return false. return !target_package.DefinesOverlayable(); // Do not allow non-overlayable resources to be overlaid. return false; } if (overlay_info.target_name != overlayable_info->name) { Loading Loading @@ -427,6 +436,12 @@ std::unique_ptr<const Idmap> Idmap::FromApkAssets( matching_resources.Add(target_resid, overlay_resid); } if (matching_resources.Map().empty()) { out_error << "overlay \"" << overlay_apk_path << "\" does not successfully overlay any resource" << std::endl; return nullptr; } // encode idmap data std::unique_ptr<IdmapData> data(new IdmapData()); const auto types_end = matching_resources.Map().cend(); Loading cmds/idmap2/tests/IdmapTests.cpp +118 −156 Original line number Diff line number Diff line Loading @@ -173,20 +173,27 @@ TEST(IdmapTests, GracefullyFailToCreateIdmapFromCorruptBinaryStream) { ASSERT_THAT(idmap, IsNull()); } TEST(IdmapTests, CreateIdmapFromApkAssets) { const std::string target_apk_path(GetTestDataPath() + "/target/target.apk"); std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path); void CreateIdmap(const StringPiece& target_apk_path, const StringPiece& overlay_apk_path, const PolicyBitmask& fulfilled_policies, bool enforce_overlayable, std::unique_ptr<const Idmap>* out_idmap) { std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path.to_string()); ASSERT_THAT(target_apk, NotNull()); const std::string overlay_apk_path(GetTestDataPath() + "/overlay/overlay.apk"); std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path); std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path.to_string()); ASSERT_THAT(overlay_apk, NotNull()); std::stringstream error; std::unique_ptr<const Idmap> idmap = Idmap::FromApkAssets(target_apk_path, *target_apk, overlay_apk_path, *overlay_apk, PolicyFlags::POLICY_PUBLIC, /* enforce_overlayable */ true, error); ASSERT_THAT(idmap, NotNull()); *out_idmap = Idmap::FromApkAssets(target_apk_path.to_string(), *target_apk, overlay_apk_path.to_string(), *overlay_apk, fulfilled_policies, enforce_overlayable, error); } TEST(IdmapTests, CreateIdmapFromApkAssets) { std::unique_ptr<const Idmap> idmap; std::string target_apk_path = GetTestDataPath() + "/target/target.apk"; std::string overlay_apk_path = GetTestDataPath() + "/overlay/overlay.apk"; CreateIdmap(target_apk_path, overlay_apk_path, PolicyFlags::POLICY_PUBLIC, /* enforce_overlayable */ true, &idmap); ASSERT_THAT(idmap->GetHeader(), NotNull()); ASSERT_EQ(idmap->GetHeader()->GetMagic(), 0x504d4449U); Loading Loading @@ -226,19 +233,12 @@ TEST(IdmapTests, CreateIdmapFromApkAssets) { // Overlays should abide by all overlayable restrictions if enforcement of overlayable is enabled. TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsPolicySystemPublic) { const std::string target_apk_path(GetTestDataPath() + "/target/target.apk"); std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path); ASSERT_THAT(target_apk, NotNull()); const std::string overlay_apk_path(GetTestDataPath() + "/system-overlay/system-overlay.apk"); std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path); ASSERT_THAT(overlay_apk, NotNull()); std::stringstream error; std::unique_ptr<const Idmap> idmap = Idmap::FromApkAssets(target_apk_path, *target_apk, overlay_apk_path, *overlay_apk, std::unique_ptr<const Idmap> idmap; std::string target_apk_path = GetTestDataPath() + "/target/target.apk"; std::string overlay_apk_path = GetTestDataPath() + "/system-overlay/system-overlay.apk"; CreateIdmap(target_apk_path, overlay_apk_path, PolicyFlags::POLICY_SYSTEM_PARTITION | PolicyFlags::POLICY_PUBLIC, /* enforce_overlayable */ true, error); /* enforce_overlayable */ true, &idmap); ASSERT_THAT(idmap, NotNull()); const std::vector<std::unique_ptr<const IdmapData>>& dataBlocks = idmap->GetData(); Loading @@ -263,21 +263,12 @@ TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsPolicySystemPublic) { } TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsPolicySignature) { const std::string target_apk_path(GetTestDataPath() + "/target/target.apk"); std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path); ASSERT_THAT(target_apk, NotNull()); const std::string overlay_apk_path(GetTestDataPath() + "/signature-overlay/signature-overlay.apk"); std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path); ASSERT_THAT(overlay_apk, NotNull()); uint32_t policy_flags = PolicyFlags::POLICY_PUBLIC | PolicyFlags::POLICY_SIGNATURE; std::stringstream error; std::unique_ptr<const Idmap> idmap = Idmap::FromApkAssets(target_apk_path, *target_apk, overlay_apk_path, *overlay_apk, policy_flags, /* enforce_overlayable */ true, error); std::unique_ptr<const Idmap> idmap; std::string target_apk_path = GetTestDataPath() + "/target/target.apk"; std::string overlay_apk_path = GetTestDataPath() + "/signature-overlay/signature-overlay.apk"; CreateIdmap(target_apk_path, overlay_apk_path, PolicyFlags::POLICY_PUBLIC | PolicyFlags::POLICY_SIGNATURE, /* enforce_overlayable */ true, &idmap); ASSERT_THAT(idmap, NotNull()); const std::vector<std::unique_ptr<const IdmapData>>& dataBlocks = idmap->GetData(); Loading @@ -298,52 +289,15 @@ TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsPolicySignature) { ASSERT_EQ(types[0]->GetEntry(0), 0x0000U); // string/policy_signature } TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsPolicySignatureNotFulfilled) { const std::string target_apk_path(GetTestDataPath() + "/target/target.apk"); std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path); ASSERT_THAT(target_apk, NotNull()); const std::string overlay_apk_path(GetTestDataPath() + "/signature-overlay/signature-overlay.apk"); std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path); ASSERT_THAT(overlay_apk, NotNull()); uint32_t policy_flags = PolicyFlags::POLICY_PUBLIC; std::stringstream error; std::unique_ptr<const Idmap> idmap = Idmap::FromApkAssets(target_apk_path, *target_apk, overlay_apk_path, *overlay_apk, policy_flags, /* enforce_overlayable */ true, error); ASSERT_THAT(idmap, NotNull()); const std::vector<std::unique_ptr<const IdmapData>>& dataBlocks = idmap->GetData(); ASSERT_EQ(dataBlocks.size(), 1U); const std::unique_ptr<const IdmapData>& data = dataBlocks[0]; ASSERT_EQ(data->GetHeader()->GetTargetPackageId(), 0x7fU); ASSERT_EQ(data->GetHeader()->GetTypeCount(), 0U); const std::vector<std::unique_ptr<const IdmapData::TypeEntry>>& types = data->GetTypeEntries(); ASSERT_EQ(types.size(), 0U); // can't overlay, so contains nothing } // Overlays should abide by all overlayable restrictions if enforcement of overlayable is enabled. TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsPolicySystemPublicInvalid) { const std::string target_apk_path(GetTestDataPath() + "/target/target.apk"); std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path); ASSERT_THAT(target_apk, NotNull()); const std::string overlay_apk_path(GetTestDataPath() + "/system-overlay-invalid/system-overlay-invalid.apk"); std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path); ASSERT_THAT(overlay_apk, NotNull()); std::stringstream error; std::unique_ptr<const Idmap> idmap = Idmap::FromApkAssets(target_apk_path, *target_apk, overlay_apk_path, *overlay_apk, std::unique_ptr<const Idmap> idmap; std::string target_apk_path = GetTestDataPath() + "/target/target.apk"; std::string overlay_apk_path = GetTestDataPath() + "/system-overlay-invalid/system-overlay-invalid.apk"; CreateIdmap(target_apk_path, overlay_apk_path, PolicyFlags::POLICY_SYSTEM_PARTITION | PolicyFlags::POLICY_PUBLIC, /* enforce_overlayable */ true, error); /* enforce_overlayable */ true, &idmap); ASSERT_THAT(idmap, NotNull()); const std::vector<std::unique_ptr<const IdmapData>>& dataBlocks = idmap->GetData(); Loading @@ -369,20 +323,13 @@ TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsPolicySystemPublicInvalid) { // Overlays should ignore all overlayable restrictions if enforcement of overlayable is disabled. TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsPolicySystemPublicInvalidIgnoreOverlayable) { const std::string target_apk_path(GetTestDataPath() + "/target/target.apk"); std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path); ASSERT_THAT(target_apk, NotNull()); const std::string overlay_apk_path(GetTestDataPath() + "/system-overlay-invalid/system-overlay-invalid.apk"); std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path); ASSERT_THAT(overlay_apk, NotNull()); std::stringstream error; std::unique_ptr<const Idmap> idmap = Idmap::FromApkAssets(target_apk_path, *target_apk, overlay_apk_path, *overlay_apk, std::unique_ptr<const Idmap> idmap; std::string target_apk_path = GetTestDataPath() + "/target/target.apk"; std::string overlay_apk_path = GetTestDataPath() + "/system-overlay-invalid/system-overlay-invalid.apk"; CreateIdmap(target_apk_path, overlay_apk_path, PolicyFlags::POLICY_SYSTEM_PARTITION | PolicyFlags::POLICY_PUBLIC, /* enforce_overlayable */ false, error); /* enforce_overlayable */ false, &idmap); ASSERT_THAT(idmap, NotNull()); const std::vector<std::unique_ptr<const IdmapData>>& dataBlocks = idmap->GetData(); Loading @@ -409,24 +356,62 @@ TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsPolicySystemPublicInvalidIgn ASSERT_EQ(types[0]->GetEntry(6), 0x0006U); // string/policy_system_vendor } // The resources of APKs that do not include an overlayable declaration should not restrict what // resources can be overlaid. TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsNoDefinedOverlayable) { const std::string target_apk_path(GetTestDataPath() + "/target/target-no-overlayable.apk"); std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path); ASSERT_THAT(target_apk, NotNull()); // Overlays that do not specify a target <overlayable> can overlay resources defined as overlayable. TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsNoDefinedOverlayableAndNoTargetName) { std::unique_ptr<const Idmap> idmap; std::string target_apk_path = GetTestDataPath() + "/target/target-no-overlayable.apk"; std::string overlay_apk_path = GetTestDataPath() + "/overlay/overlay-no-name.apk"; CreateIdmap(target_apk_path, overlay_apk_path, PolicyFlags::POLICY_PUBLIC, /* enforce_overlayable */ false, &idmap); ASSERT_THAT(idmap, NotNull()); const std::string overlay_apk_path(GetTestDataPath() + "/system-overlay-invalid/system-overlay-invalid.apk"); std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path); ASSERT_THAT(overlay_apk, NotNull()); const std::vector<std::unique_ptr<const IdmapData>>& dataBlocks = idmap->GetData(); ASSERT_EQ(dataBlocks.size(), 1U); std::stringstream error; std::unique_ptr<const Idmap> idmap = Idmap::FromApkAssets(target_apk_path, *target_apk, overlay_apk_path, *overlay_apk, PolicyFlags::POLICY_PUBLIC, /* enforce_overlayable */ true, error); ASSERT_THAT(idmap, NotNull()); const std::unique_ptr<const IdmapData>& data = dataBlocks[0]; ASSERT_EQ(data->GetHeader()->GetTargetPackageId(), 0x7fU); ASSERT_EQ(data->GetHeader()->GetTypeCount(), 2U); const std::vector<std::unique_ptr<const IdmapData::TypeEntry>>& types = data->GetTypeEntries(); ASSERT_EQ(types.size(), 2U); ASSERT_EQ(types[0]->GetTargetTypeId(), 0x01U); ASSERT_EQ(types[0]->GetOverlayTypeId(), 0x01U); ASSERT_EQ(types[0]->GetEntryCount(), 1U); ASSERT_EQ(types[0]->GetEntryOffset(), 0U); ASSERT_EQ(types[0]->GetEntry(0), 0x0000U); // string/int1 ASSERT_EQ(types[1]->GetTargetTypeId(), 0x02U); ASSERT_EQ(types[1]->GetOverlayTypeId(), 0x02U); ASSERT_EQ(types[1]->GetEntryCount(), 4U); ASSERT_EQ(types[1]->GetEntryOffset(), 10U); ASSERT_EQ(types[1]->GetEntry(0), 0x0000U); // string/str1 ASSERT_EQ(types[1]->GetEntry(1), kNoEntry); // string/str2 ASSERT_EQ(types[1]->GetEntry(2), 0x0001U); // string/str3 ASSERT_EQ(types[1]->GetEntry(3), 0x0002U); // string/str4 } // Overlays that are not pre-installed and are not signed with the same signature as the target // cannot overlay packages that have not defined overlayable resources. TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsDefaultPoliciesPublicFail) { std::unique_ptr<const Idmap> idmap; std::string target_apk_path = GetTestDataPath() + "/target/target-no-overlayable.apk"; std::string overlay_apk_path = GetTestDataPath() + "/overlay/overlay-no-name.apk"; CreateIdmap(target_apk_path, overlay_apk_path, PolicyFlags::POLICY_PUBLIC, /* enforce_overlayable */ true, &idmap); ASSERT_THAT(idmap, IsNull()); } // Overlays that are pre-installed or are signed with the same signature as the target can overlay // packages that have not defined overlayable resources. TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsDefaultPolicies) { std::unique_ptr<const Idmap> idmap; std::string target_apk_path = GetTestDataPath() + "/target/target-no-overlayable.apk"; std::string overlay_apk_path = GetTestDataPath() + "/system-overlay-invalid/system-overlay-invalid.apk"; auto CheckEntries = [&]() -> void { const std::vector<std::unique_ptr<const IdmapData>>& dataBlocks = idmap->GetData(); ASSERT_EQ(dataBlocks.size(), 1U); Loading @@ -449,50 +434,27 @@ TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsNoDefinedOverlayable) { ASSERT_EQ(types[0]->GetEntry(4), 0x0004U); // string/string/policy_signature ASSERT_EQ(types[0]->GetEntry(5), 0x0005U); // string/policy_system ASSERT_EQ(types[0]->GetEntry(6), 0x0006U); // string/policy_system_vendor } // The resources of APKs that do not include an overlayable declaration should not restrict what // resources can be overlaid. TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsNoDefinedOverlayableAndNoTargetName) { const std::string target_apk_path(GetTestDataPath() + "/target/target-no-overlayable.apk"); std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path); ASSERT_THAT(target_apk, NotNull()); const std::string overlay_apk_path(GetTestDataPath() + "/overlay/overlay-no-name.apk"); std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path); ASSERT_THAT(overlay_apk, NotNull()); }; std::stringstream error; std::unique_ptr<const Idmap> idmap = Idmap::FromApkAssets(target_apk_path, *target_apk, overlay_apk_path, *overlay_apk, PolicyFlags::POLICY_PUBLIC, /* enforce_overlayable */ true, error); CreateIdmap(target_apk_path, overlay_apk_path, PolicyFlags::POLICY_SIGNATURE, /* enforce_overlayable */ true, &idmap); ASSERT_THAT(idmap, NotNull()); CheckEntries(); const std::vector<std::unique_ptr<const IdmapData>>& dataBlocks = idmap->GetData(); ASSERT_EQ(dataBlocks.size(), 1U); const std::unique_ptr<const IdmapData>& data = dataBlocks[0]; ASSERT_EQ(data->GetHeader()->GetTargetPackageId(), 0x7fU); ASSERT_EQ(data->GetHeader()->GetTypeCount(), 2U); const std::vector<std::unique_ptr<const IdmapData::TypeEntry>>& types = data->GetTypeEntries(); ASSERT_EQ(types.size(), 2U); CreateIdmap(target_apk_path, overlay_apk_path, PolicyFlags::POLICY_PRODUCT_PARTITION, /* enforce_overlayable */ true, &idmap); ASSERT_THAT(idmap, NotNull()); CheckEntries(); ASSERT_EQ(types[0]->GetTargetTypeId(), 0x01U); ASSERT_EQ(types[0]->GetOverlayTypeId(), 0x01U); ASSERT_EQ(types[0]->GetEntryCount(), 1U); ASSERT_EQ(types[0]->GetEntryOffset(), 0U); ASSERT_EQ(types[0]->GetEntry(0), 0x0000U); CreateIdmap(target_apk_path, overlay_apk_path, PolicyFlags::POLICY_SYSTEM_PARTITION, /* enforce_overlayable */ true, &idmap); ASSERT_THAT(idmap, NotNull()); CheckEntries(); ASSERT_EQ(types[1]->GetTargetTypeId(), 0x02U); ASSERT_EQ(types[1]->GetOverlayTypeId(), 0x02U); ASSERT_EQ(types[1]->GetEntryCount(), 4U); ASSERT_EQ(types[1]->GetEntryOffset(), 10U); ASSERT_EQ(types[1]->GetEntry(0), 0x0000U); ASSERT_EQ(types[1]->GetEntry(1), kNoEntry); ASSERT_EQ(types[1]->GetEntry(2), 0x0001U); ASSERT_EQ(types[1]->GetEntry(3), 0x0002U); CreateIdmap(target_apk_path, overlay_apk_path, PolicyFlags::POLICY_VENDOR_PARTITION, /* enforce_overlayable */ true, &idmap); ASSERT_THAT(idmap, NotNull()); CheckEntries(); } TEST(IdmapTests, FailToCreateIdmapFromApkAssetsIfPathTooLong) { Loading cmds/idmap2/tests/data/overlay/build +1 −1 Original line number Diff line number Diff line Loading @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. FRAMEWORK_RES_APK="${ANDROID_BUILD_TOP}/out/target/common/obj/APPS/framework-res_intermediates/package-export.apk" FRAMEWORK_RES_APK=${ANDROID_BUILD_TOP}/prebuilts/sdk/current/public/android.jar aapt2 compile --dir res -o compiled.flata Loading cmds/idmap2/tests/data/overlay/overlay-no-name.apk +32 B (1.56 KiB) File changed.No diff preview for this file type. View original file View changed file Loading
cmds/idmap2/libidmap2/Idmap.cpp +18 −3 Original line number Diff line number Diff line Loading @@ -287,11 +287,20 @@ std::unique_ptr<const Idmap> Idmap::FromBinaryStream(std::istream& stream, bool CheckOverlayable(const LoadedPackage& target_package, const utils::OverlayManifestInfo& overlay_info, const PolicyBitmask& fulfilled_policies, const ResourceId& resid) { static constexpr const PolicyBitmask sDefaultPolicies = PolicyFlags::POLICY_SYSTEM_PARTITION | PolicyFlags::POLICY_VENDOR_PARTITION | PolicyFlags::POLICY_PRODUCT_PARTITION | PolicyFlags::POLICY_SIGNATURE; // If the resource does not have an overlayable definition, allow the resource to be overlaid if // the overlay is preinstalled or signed with the same signature as the target. if (!target_package.DefinesOverlayable()) { return (sDefaultPolicies & fulfilled_policies) != 0; } const OverlayableInfo* overlayable_info = target_package.GetOverlayableInfo(resid); if (overlayable_info == nullptr) { // If the resource does not have an overlayable definition, allow the resource to be overlaid. // Once overlayable enforcement is turned on, this check will return false. return !target_package.DefinesOverlayable(); // Do not allow non-overlayable resources to be overlaid. return false; } if (overlay_info.target_name != overlayable_info->name) { Loading Loading @@ -427,6 +436,12 @@ std::unique_ptr<const Idmap> Idmap::FromApkAssets( matching_resources.Add(target_resid, overlay_resid); } if (matching_resources.Map().empty()) { out_error << "overlay \"" << overlay_apk_path << "\" does not successfully overlay any resource" << std::endl; return nullptr; } // encode idmap data std::unique_ptr<IdmapData> data(new IdmapData()); const auto types_end = matching_resources.Map().cend(); Loading
cmds/idmap2/tests/IdmapTests.cpp +118 −156 Original line number Diff line number Diff line Loading @@ -173,20 +173,27 @@ TEST(IdmapTests, GracefullyFailToCreateIdmapFromCorruptBinaryStream) { ASSERT_THAT(idmap, IsNull()); } TEST(IdmapTests, CreateIdmapFromApkAssets) { const std::string target_apk_path(GetTestDataPath() + "/target/target.apk"); std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path); void CreateIdmap(const StringPiece& target_apk_path, const StringPiece& overlay_apk_path, const PolicyBitmask& fulfilled_policies, bool enforce_overlayable, std::unique_ptr<const Idmap>* out_idmap) { std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path.to_string()); ASSERT_THAT(target_apk, NotNull()); const std::string overlay_apk_path(GetTestDataPath() + "/overlay/overlay.apk"); std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path); std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path.to_string()); ASSERT_THAT(overlay_apk, NotNull()); std::stringstream error; std::unique_ptr<const Idmap> idmap = Idmap::FromApkAssets(target_apk_path, *target_apk, overlay_apk_path, *overlay_apk, PolicyFlags::POLICY_PUBLIC, /* enforce_overlayable */ true, error); ASSERT_THAT(idmap, NotNull()); *out_idmap = Idmap::FromApkAssets(target_apk_path.to_string(), *target_apk, overlay_apk_path.to_string(), *overlay_apk, fulfilled_policies, enforce_overlayable, error); } TEST(IdmapTests, CreateIdmapFromApkAssets) { std::unique_ptr<const Idmap> idmap; std::string target_apk_path = GetTestDataPath() + "/target/target.apk"; std::string overlay_apk_path = GetTestDataPath() + "/overlay/overlay.apk"; CreateIdmap(target_apk_path, overlay_apk_path, PolicyFlags::POLICY_PUBLIC, /* enforce_overlayable */ true, &idmap); ASSERT_THAT(idmap->GetHeader(), NotNull()); ASSERT_EQ(idmap->GetHeader()->GetMagic(), 0x504d4449U); Loading Loading @@ -226,19 +233,12 @@ TEST(IdmapTests, CreateIdmapFromApkAssets) { // Overlays should abide by all overlayable restrictions if enforcement of overlayable is enabled. TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsPolicySystemPublic) { const std::string target_apk_path(GetTestDataPath() + "/target/target.apk"); std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path); ASSERT_THAT(target_apk, NotNull()); const std::string overlay_apk_path(GetTestDataPath() + "/system-overlay/system-overlay.apk"); std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path); ASSERT_THAT(overlay_apk, NotNull()); std::stringstream error; std::unique_ptr<const Idmap> idmap = Idmap::FromApkAssets(target_apk_path, *target_apk, overlay_apk_path, *overlay_apk, std::unique_ptr<const Idmap> idmap; std::string target_apk_path = GetTestDataPath() + "/target/target.apk"; std::string overlay_apk_path = GetTestDataPath() + "/system-overlay/system-overlay.apk"; CreateIdmap(target_apk_path, overlay_apk_path, PolicyFlags::POLICY_SYSTEM_PARTITION | PolicyFlags::POLICY_PUBLIC, /* enforce_overlayable */ true, error); /* enforce_overlayable */ true, &idmap); ASSERT_THAT(idmap, NotNull()); const std::vector<std::unique_ptr<const IdmapData>>& dataBlocks = idmap->GetData(); Loading @@ -263,21 +263,12 @@ TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsPolicySystemPublic) { } TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsPolicySignature) { const std::string target_apk_path(GetTestDataPath() + "/target/target.apk"); std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path); ASSERT_THAT(target_apk, NotNull()); const std::string overlay_apk_path(GetTestDataPath() + "/signature-overlay/signature-overlay.apk"); std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path); ASSERT_THAT(overlay_apk, NotNull()); uint32_t policy_flags = PolicyFlags::POLICY_PUBLIC | PolicyFlags::POLICY_SIGNATURE; std::stringstream error; std::unique_ptr<const Idmap> idmap = Idmap::FromApkAssets(target_apk_path, *target_apk, overlay_apk_path, *overlay_apk, policy_flags, /* enforce_overlayable */ true, error); std::unique_ptr<const Idmap> idmap; std::string target_apk_path = GetTestDataPath() + "/target/target.apk"; std::string overlay_apk_path = GetTestDataPath() + "/signature-overlay/signature-overlay.apk"; CreateIdmap(target_apk_path, overlay_apk_path, PolicyFlags::POLICY_PUBLIC | PolicyFlags::POLICY_SIGNATURE, /* enforce_overlayable */ true, &idmap); ASSERT_THAT(idmap, NotNull()); const std::vector<std::unique_ptr<const IdmapData>>& dataBlocks = idmap->GetData(); Loading @@ -298,52 +289,15 @@ TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsPolicySignature) { ASSERT_EQ(types[0]->GetEntry(0), 0x0000U); // string/policy_signature } TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsPolicySignatureNotFulfilled) { const std::string target_apk_path(GetTestDataPath() + "/target/target.apk"); std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path); ASSERT_THAT(target_apk, NotNull()); const std::string overlay_apk_path(GetTestDataPath() + "/signature-overlay/signature-overlay.apk"); std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path); ASSERT_THAT(overlay_apk, NotNull()); uint32_t policy_flags = PolicyFlags::POLICY_PUBLIC; std::stringstream error; std::unique_ptr<const Idmap> idmap = Idmap::FromApkAssets(target_apk_path, *target_apk, overlay_apk_path, *overlay_apk, policy_flags, /* enforce_overlayable */ true, error); ASSERT_THAT(idmap, NotNull()); const std::vector<std::unique_ptr<const IdmapData>>& dataBlocks = idmap->GetData(); ASSERT_EQ(dataBlocks.size(), 1U); const std::unique_ptr<const IdmapData>& data = dataBlocks[0]; ASSERT_EQ(data->GetHeader()->GetTargetPackageId(), 0x7fU); ASSERT_EQ(data->GetHeader()->GetTypeCount(), 0U); const std::vector<std::unique_ptr<const IdmapData::TypeEntry>>& types = data->GetTypeEntries(); ASSERT_EQ(types.size(), 0U); // can't overlay, so contains nothing } // Overlays should abide by all overlayable restrictions if enforcement of overlayable is enabled. TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsPolicySystemPublicInvalid) { const std::string target_apk_path(GetTestDataPath() + "/target/target.apk"); std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path); ASSERT_THAT(target_apk, NotNull()); const std::string overlay_apk_path(GetTestDataPath() + "/system-overlay-invalid/system-overlay-invalid.apk"); std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path); ASSERT_THAT(overlay_apk, NotNull()); std::stringstream error; std::unique_ptr<const Idmap> idmap = Idmap::FromApkAssets(target_apk_path, *target_apk, overlay_apk_path, *overlay_apk, std::unique_ptr<const Idmap> idmap; std::string target_apk_path = GetTestDataPath() + "/target/target.apk"; std::string overlay_apk_path = GetTestDataPath() + "/system-overlay-invalid/system-overlay-invalid.apk"; CreateIdmap(target_apk_path, overlay_apk_path, PolicyFlags::POLICY_SYSTEM_PARTITION | PolicyFlags::POLICY_PUBLIC, /* enforce_overlayable */ true, error); /* enforce_overlayable */ true, &idmap); ASSERT_THAT(idmap, NotNull()); const std::vector<std::unique_ptr<const IdmapData>>& dataBlocks = idmap->GetData(); Loading @@ -369,20 +323,13 @@ TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsPolicySystemPublicInvalid) { // Overlays should ignore all overlayable restrictions if enforcement of overlayable is disabled. TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsPolicySystemPublicInvalidIgnoreOverlayable) { const std::string target_apk_path(GetTestDataPath() + "/target/target.apk"); std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path); ASSERT_THAT(target_apk, NotNull()); const std::string overlay_apk_path(GetTestDataPath() + "/system-overlay-invalid/system-overlay-invalid.apk"); std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path); ASSERT_THAT(overlay_apk, NotNull()); std::stringstream error; std::unique_ptr<const Idmap> idmap = Idmap::FromApkAssets(target_apk_path, *target_apk, overlay_apk_path, *overlay_apk, std::unique_ptr<const Idmap> idmap; std::string target_apk_path = GetTestDataPath() + "/target/target.apk"; std::string overlay_apk_path = GetTestDataPath() + "/system-overlay-invalid/system-overlay-invalid.apk"; CreateIdmap(target_apk_path, overlay_apk_path, PolicyFlags::POLICY_SYSTEM_PARTITION | PolicyFlags::POLICY_PUBLIC, /* enforce_overlayable */ false, error); /* enforce_overlayable */ false, &idmap); ASSERT_THAT(idmap, NotNull()); const std::vector<std::unique_ptr<const IdmapData>>& dataBlocks = idmap->GetData(); Loading @@ -409,24 +356,62 @@ TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsPolicySystemPublicInvalidIgn ASSERT_EQ(types[0]->GetEntry(6), 0x0006U); // string/policy_system_vendor } // The resources of APKs that do not include an overlayable declaration should not restrict what // resources can be overlaid. TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsNoDefinedOverlayable) { const std::string target_apk_path(GetTestDataPath() + "/target/target-no-overlayable.apk"); std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path); ASSERT_THAT(target_apk, NotNull()); // Overlays that do not specify a target <overlayable> can overlay resources defined as overlayable. TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsNoDefinedOverlayableAndNoTargetName) { std::unique_ptr<const Idmap> idmap; std::string target_apk_path = GetTestDataPath() + "/target/target-no-overlayable.apk"; std::string overlay_apk_path = GetTestDataPath() + "/overlay/overlay-no-name.apk"; CreateIdmap(target_apk_path, overlay_apk_path, PolicyFlags::POLICY_PUBLIC, /* enforce_overlayable */ false, &idmap); ASSERT_THAT(idmap, NotNull()); const std::string overlay_apk_path(GetTestDataPath() + "/system-overlay-invalid/system-overlay-invalid.apk"); std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path); ASSERT_THAT(overlay_apk, NotNull()); const std::vector<std::unique_ptr<const IdmapData>>& dataBlocks = idmap->GetData(); ASSERT_EQ(dataBlocks.size(), 1U); std::stringstream error; std::unique_ptr<const Idmap> idmap = Idmap::FromApkAssets(target_apk_path, *target_apk, overlay_apk_path, *overlay_apk, PolicyFlags::POLICY_PUBLIC, /* enforce_overlayable */ true, error); ASSERT_THAT(idmap, NotNull()); const std::unique_ptr<const IdmapData>& data = dataBlocks[0]; ASSERT_EQ(data->GetHeader()->GetTargetPackageId(), 0x7fU); ASSERT_EQ(data->GetHeader()->GetTypeCount(), 2U); const std::vector<std::unique_ptr<const IdmapData::TypeEntry>>& types = data->GetTypeEntries(); ASSERT_EQ(types.size(), 2U); ASSERT_EQ(types[0]->GetTargetTypeId(), 0x01U); ASSERT_EQ(types[0]->GetOverlayTypeId(), 0x01U); ASSERT_EQ(types[0]->GetEntryCount(), 1U); ASSERT_EQ(types[0]->GetEntryOffset(), 0U); ASSERT_EQ(types[0]->GetEntry(0), 0x0000U); // string/int1 ASSERT_EQ(types[1]->GetTargetTypeId(), 0x02U); ASSERT_EQ(types[1]->GetOverlayTypeId(), 0x02U); ASSERT_EQ(types[1]->GetEntryCount(), 4U); ASSERT_EQ(types[1]->GetEntryOffset(), 10U); ASSERT_EQ(types[1]->GetEntry(0), 0x0000U); // string/str1 ASSERT_EQ(types[1]->GetEntry(1), kNoEntry); // string/str2 ASSERT_EQ(types[1]->GetEntry(2), 0x0001U); // string/str3 ASSERT_EQ(types[1]->GetEntry(3), 0x0002U); // string/str4 } // Overlays that are not pre-installed and are not signed with the same signature as the target // cannot overlay packages that have not defined overlayable resources. TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsDefaultPoliciesPublicFail) { std::unique_ptr<const Idmap> idmap; std::string target_apk_path = GetTestDataPath() + "/target/target-no-overlayable.apk"; std::string overlay_apk_path = GetTestDataPath() + "/overlay/overlay-no-name.apk"; CreateIdmap(target_apk_path, overlay_apk_path, PolicyFlags::POLICY_PUBLIC, /* enforce_overlayable */ true, &idmap); ASSERT_THAT(idmap, IsNull()); } // Overlays that are pre-installed or are signed with the same signature as the target can overlay // packages that have not defined overlayable resources. TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsDefaultPolicies) { std::unique_ptr<const Idmap> idmap; std::string target_apk_path = GetTestDataPath() + "/target/target-no-overlayable.apk"; std::string overlay_apk_path = GetTestDataPath() + "/system-overlay-invalid/system-overlay-invalid.apk"; auto CheckEntries = [&]() -> void { const std::vector<std::unique_ptr<const IdmapData>>& dataBlocks = idmap->GetData(); ASSERT_EQ(dataBlocks.size(), 1U); Loading @@ -449,50 +434,27 @@ TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsNoDefinedOverlayable) { ASSERT_EQ(types[0]->GetEntry(4), 0x0004U); // string/string/policy_signature ASSERT_EQ(types[0]->GetEntry(5), 0x0005U); // string/policy_system ASSERT_EQ(types[0]->GetEntry(6), 0x0006U); // string/policy_system_vendor } // The resources of APKs that do not include an overlayable declaration should not restrict what // resources can be overlaid. TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsNoDefinedOverlayableAndNoTargetName) { const std::string target_apk_path(GetTestDataPath() + "/target/target-no-overlayable.apk"); std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path); ASSERT_THAT(target_apk, NotNull()); const std::string overlay_apk_path(GetTestDataPath() + "/overlay/overlay-no-name.apk"); std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path); ASSERT_THAT(overlay_apk, NotNull()); }; std::stringstream error; std::unique_ptr<const Idmap> idmap = Idmap::FromApkAssets(target_apk_path, *target_apk, overlay_apk_path, *overlay_apk, PolicyFlags::POLICY_PUBLIC, /* enforce_overlayable */ true, error); CreateIdmap(target_apk_path, overlay_apk_path, PolicyFlags::POLICY_SIGNATURE, /* enforce_overlayable */ true, &idmap); ASSERT_THAT(idmap, NotNull()); CheckEntries(); const std::vector<std::unique_ptr<const IdmapData>>& dataBlocks = idmap->GetData(); ASSERT_EQ(dataBlocks.size(), 1U); const std::unique_ptr<const IdmapData>& data = dataBlocks[0]; ASSERT_EQ(data->GetHeader()->GetTargetPackageId(), 0x7fU); ASSERT_EQ(data->GetHeader()->GetTypeCount(), 2U); const std::vector<std::unique_ptr<const IdmapData::TypeEntry>>& types = data->GetTypeEntries(); ASSERT_EQ(types.size(), 2U); CreateIdmap(target_apk_path, overlay_apk_path, PolicyFlags::POLICY_PRODUCT_PARTITION, /* enforce_overlayable */ true, &idmap); ASSERT_THAT(idmap, NotNull()); CheckEntries(); ASSERT_EQ(types[0]->GetTargetTypeId(), 0x01U); ASSERT_EQ(types[0]->GetOverlayTypeId(), 0x01U); ASSERT_EQ(types[0]->GetEntryCount(), 1U); ASSERT_EQ(types[0]->GetEntryOffset(), 0U); ASSERT_EQ(types[0]->GetEntry(0), 0x0000U); CreateIdmap(target_apk_path, overlay_apk_path, PolicyFlags::POLICY_SYSTEM_PARTITION, /* enforce_overlayable */ true, &idmap); ASSERT_THAT(idmap, NotNull()); CheckEntries(); ASSERT_EQ(types[1]->GetTargetTypeId(), 0x02U); ASSERT_EQ(types[1]->GetOverlayTypeId(), 0x02U); ASSERT_EQ(types[1]->GetEntryCount(), 4U); ASSERT_EQ(types[1]->GetEntryOffset(), 10U); ASSERT_EQ(types[1]->GetEntry(0), 0x0000U); ASSERT_EQ(types[1]->GetEntry(1), kNoEntry); ASSERT_EQ(types[1]->GetEntry(2), 0x0001U); ASSERT_EQ(types[1]->GetEntry(3), 0x0002U); CreateIdmap(target_apk_path, overlay_apk_path, PolicyFlags::POLICY_VENDOR_PARTITION, /* enforce_overlayable */ true, &idmap); ASSERT_THAT(idmap, NotNull()); CheckEntries(); } TEST(IdmapTests, FailToCreateIdmapFromApkAssetsIfPathTooLong) { Loading
cmds/idmap2/tests/data/overlay/build +1 −1 Original line number Diff line number Diff line Loading @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. FRAMEWORK_RES_APK="${ANDROID_BUILD_TOP}/out/target/common/obj/APPS/framework-res_intermediates/package-export.apk" FRAMEWORK_RES_APK=${ANDROID_BUILD_TOP}/prebuilts/sdk/current/public/android.jar aapt2 compile --dir res -o compiled.flata Loading
cmds/idmap2/tests/data/overlay/overlay-no-name.apk +32 B (1.56 KiB) File changed.No diff preview for this file type. View original file View changed file