Add policies and enforce overlayable to header

If the fulfilled policies change without the contents of the target
and overlay APKs changing, the idmap for the overlay should be
regenerated. This change adds fulfilled policies and enforce
overlayable to the idmap header so that idmap2d can determine if the
polices or enforce overlayable changed from what was used to generate
the idmap.

Bug: 119328308
Test: idmap2_tests
Test: atest RegenerateIdmapTest

Change-Id: I96f970e82b5243be01b205ac2cb6ab249c6100bc
This commit is contained in:
Ryan Mitchell
2020-05-13 14:17:52 -07:00
parent 57e977a585
commit a707013b78
32 changed files with 406 additions and 172 deletions

View File

@@ -168,13 +168,13 @@ cc_binary {
],
host_supported: true,
srcs: [
"idmap2/CommandUtils.cpp",
"idmap2/Create.cpp",
"idmap2/CreateMultiple.cpp",
"idmap2/Dump.cpp",
"idmap2/Lookup.cpp",
"idmap2/Main.cpp",
"idmap2/Scan.cpp",
"idmap2/Verify.cpp",
],
target: {
android: {

View File

@@ -19,30 +19,19 @@
#include <string>
#include <vector>
#include "idmap2/CommandLineOptions.h"
#include "idmap2/Idmap.h"
#include "idmap2/Result.h"
#include "idmap2/SysTrace.h"
using android::idmap2::CommandLineOptions;
using android::idmap2::Error;
using android::idmap2::IdmapHeader;
using android::idmap2::Result;
using android::idmap2::Unit;
Result<Unit> Verify(const std::vector<std::string>& args) {
SYSTRACE << "Verify " << args;
std::string idmap_path;
const CommandLineOptions opts =
CommandLineOptions("idmap2 verify")
.MandatoryOption("--idmap-path", "input: path to idmap file to verify", &idmap_path);
const auto opts_ok = opts.Parse(args);
if (!opts_ok) {
return opts_ok.GetError();
}
Result<Unit> Verify(const std::string& idmap_path, const std::string& target_path,
const std::string& overlay_path, uint32_t fulfilled_policies,
bool enforce_overlayable) {
SYSTRACE << "Verify " << idmap_path;
std::ifstream fin(idmap_path);
const std::unique_ptr<const IdmapHeader> header = IdmapHeader::FromBinaryStream(fin);
fin.close();
@@ -50,7 +39,8 @@ Result<Unit> Verify(const std::vector<std::string>& args) {
return Error("failed to parse idmap header");
}
const auto header_ok = header->IsUpToDate();
const auto header_ok = header->IsUpToDate(target_path.c_str(), overlay_path.c_str(),
fulfilled_policies, enforce_overlayable);
if (!header_ok) {
return Error(header_ok.GetError(), "idmap not up to date");
}

View File

@@ -0,0 +1,28 @@
/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef IDMAP2_IDMAP2_COMMAND_UTILS_H_
#define IDMAP2_IDMAP2_COMMAND_UTILS_H_
#include "idmap2/Result.h"
android::idmap2::Result<android::idmap2::Unit> Verify(const std::string& idmap_path,
const std::string& target_path,
const std::string& overlay_path,
uint32_t fulfilled_policies,
bool enforce_overlayable);
#endif // IDMAP2_IDMAP2_COMMAND_UTILS_H_

View File

@@ -27,6 +27,5 @@ android::idmap2::Result<android::idmap2::Unit> CreateMultiple(const std::vector<
android::idmap2::Result<android::idmap2::Unit> Dump(const std::vector<std::string>& args);
android::idmap2::Result<android::idmap2::Unit> Lookup(const std::vector<std::string>& args);
android::idmap2::Result<android::idmap2::Unit> Scan(const std::vector<std::string>& args);
android::idmap2::Result<android::idmap2::Unit> Verify(const std::vector<std::string>& args);
#endif // IDMAP2_IDMAP2_COMMANDS_H_

View File

@@ -26,6 +26,7 @@
#include "android-base/stringprintf.h"
#include "idmap2/BinaryStreamVisitor.h"
#include "idmap2/CommandLineOptions.h"
#include "idmap2/CommandUtils.h"
#include "idmap2/FileUtils.h"
#include "idmap2/Idmap.h"
#include "idmap2/Policies.h"
@@ -103,7 +104,8 @@ Result<Unit> CreateMultiple(const std::vector<std::string>& args) {
continue;
}
if (!Verify(std::vector<std::string>({"--idmap-path", idmap_path}))) {
if (!Verify(idmap_path, target_apk_path, overlay_apk_path, fulfilled_policies,
!ignore_overlayable)) {
const std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path);
if (!overlay_apk) {
LOG(WARNING) << "failed to load apk " << overlay_apk_path.c_str();

View File

@@ -53,9 +53,8 @@ void PrintUsage(const NameToFunctionMap& commands, std::ostream& out) {
int main(int argc, char** argv) {
SYSTRACE << "main";
const NameToFunctionMap commands = {
{"create", Create}, {"create-multiple", CreateMultiple},
{"dump", Dump}, {"lookup", Lookup},
{"scan", Scan}, {"verify", Verify},
{"create", Create}, {"create-multiple", CreateMultiple}, {"dump", Dump}, {"lookup", Lookup},
{"scan", Scan},
};
if (argc <= 1) {
PrintUsage(commands, std::cerr);

View File

@@ -27,8 +27,11 @@
#include "Commands.h"
#include "android-base/properties.h"
#include "idmap2/CommandLineOptions.h"
#include "idmap2/CommandUtils.h"
#include "idmap2/FileUtils.h"
#include "idmap2/Idmap.h"
#include "idmap2/Policies.h"
#include "idmap2/PolicyUtils.h"
#include "idmap2/ResourceUtils.h"
#include "idmap2/Result.h"
#include "idmap2/SysTrace.h"
@@ -48,6 +51,7 @@ using android::idmap2::policy::kPolicyVendor;
using android::idmap2::utils::ExtractOverlayManifestInfo;
using android::idmap2::utils::FindFiles;
using android::idmap2::utils::OverlayManifestInfo;
using android::idmap2::utils::PoliciesToBitmaskResult;
using PolicyBitmask = android::ResTable_overlayable_policy_header::PolicyBitmask;
@@ -215,7 +219,15 @@ Result<Unit> Scan(const std::vector<std::string>& args) {
std::stringstream stream;
for (const auto& overlay : interesting_apks) {
if (!Verify(std::vector<std::string>({"--idmap-path", overlay.idmap_path}))) {
const auto policy_bitmask = PoliciesToBitmaskResult(overlay.policies);
if (!policy_bitmask) {
LOG(WARNING) << "failed to create idmap for overlay apk path \"" << overlay.apk_path
<< "\": " << policy_bitmask.GetErrorMessage();
continue;
}
if (!Verify(overlay.idmap_path, target_apk_path, overlay.apk_path, *policy_bitmask,
!overlay.ignore_overlayable)) {
std::vector<std::string> create_args = {"--target-apk-path", target_apk_path,
"--overlay-apk-path", overlay.apk_path,
"--idmap-path", overlay.idmap_path};

View File

@@ -33,16 +33,19 @@
#include "idmap2/BinaryStreamVisitor.h"
#include "idmap2/FileUtils.h"
#include "idmap2/Idmap.h"
#include "idmap2/Result.h"
#include "idmap2/SysTrace.h"
#include "idmap2/ZipFile.h"
#include "utils/String8.h"
using android::IPCThreadState;
using android::base::StringPrintf;
using android::binder::Status;
using android::idmap2::BinaryStreamVisitor;
using android::idmap2::GetPackageCrc;
using android::idmap2::Idmap;
using android::idmap2::IdmapHeader;
using android::idmap2::ZipFile;
using android::idmap2::utils::kIdmapCacheDir;
using android::idmap2::utils::kIdmapFilePermissionMask;
using android::idmap2::utils::UidHasWriteAccessToPath;
@@ -66,6 +69,21 @@ PolicyBitmask ConvertAidlArgToPolicyBitmask(int32_t arg) {
return static_cast<PolicyBitmask>(arg);
}
Status GetCrc(const std::string& apk_path, uint32_t* out_crc) {
const auto overlay_zip = ZipFile::Open(apk_path);
if (!overlay_zip) {
return error(StringPrintf("failed to open apk %s", apk_path.c_str()));
}
const auto crc = GetPackageCrc(*overlay_zip);
if (!crc) {
return error(crc.GetErrorMessage());
}
*out_crc = *crc;
return ok();
}
} // namespace
namespace android::os {
@@ -98,10 +116,9 @@ Status Idmap2Service::removeIdmap(const std::string& overlay_apk_path,
}
Status Idmap2Service::verifyIdmap(const std::string& target_apk_path,
const std::string& overlay_apk_path,
int32_t fulfilled_policies ATTRIBUTE_UNUSED,
bool enforce_overlayable ATTRIBUTE_UNUSED,
int32_t user_id ATTRIBUTE_UNUSED, bool* _aidl_return) {
const std::string& overlay_apk_path, int32_t fulfilled_policies,
bool enforce_overlayable, int32_t user_id ATTRIBUTE_UNUSED,
bool* _aidl_return) {
SYSTRACE << "Idmap2Service::verifyIdmap " << overlay_apk_path;
assert(_aidl_return);
const std::string idmap_path = Idmap::CanonicalIdmapPathFor(kIdmapCacheDir, overlay_apk_path);
@@ -113,34 +130,38 @@ Status Idmap2Service::verifyIdmap(const std::string& target_apk_path,
return error("failed to parse idmap header");
}
if (strcmp(header->GetTargetPath().data(), target_apk_path.data()) != 0) {
*_aidl_return = false;
return ok();
}
if (target_apk_path != kFrameworkPath) {
*_aidl_return = (bool) header->IsUpToDate();
uint32_t target_crc;
if (target_apk_path == kFrameworkPath && android_crc_) {
target_crc = *android_crc_;
} else {
if (!android_crc_) {
// Loading the framework zip can take several milliseconds. Cache the crc of the framework
// resource APK to reduce repeated work during boot.
const auto target_zip = idmap2::ZipFile::Open(target_apk_path);
if (!target_zip) {
return error(base::StringPrintf("failed to open target %s", target_apk_path.c_str()));
}
const auto target_crc = GetPackageCrc(*target_zip);
if (!target_crc) {
return error(target_crc.GetErrorMessage());
}
android_crc_ = *target_crc;
auto target_crc_status = GetCrc(target_apk_path, &target_crc);
if (!target_crc_status.isOk()) {
*_aidl_return = false;
return target_crc_status;
}
*_aidl_return = (bool) header->IsUpToDate(android_crc_.value());
// Loading the framework zip can take several milliseconds. Cache the crc of the framework
// resource APK to reduce repeated work during boot.
if (target_apk_path == kFrameworkPath) {
android_crc_ = target_crc;
}
}
uint32_t overlay_crc;
auto overlay_crc_status = GetCrc(overlay_apk_path, &overlay_crc);
if (!overlay_crc_status.isOk()) {
*_aidl_return = false;
return overlay_crc_status;
}
auto up_to_date =
header->IsUpToDate(target_apk_path.c_str(), overlay_apk_path.c_str(), target_crc, overlay_crc,
fulfilled_policies, enforce_overlayable);
if (!up_to_date) {
*_aidl_return = false;
return error(up_to_date.GetErrorMessage());
}
// TODO(b/119328308): Check that the set of fulfilled policies of the overlay has not changed
return ok();
}

View File

@@ -117,6 +117,14 @@ class IdmapHeader {
return overlay_crc_;
}
inline uint32_t GetFulfilledPolicies() const {
return fulfilled_policies_;
}
bool GetEnforceOverlayable() const {
return enforce_overlayable_;
}
inline StringPiece GetTargetPath() const {
return StringPiece(target_path_);
}
@@ -132,8 +140,11 @@ class IdmapHeader {
// Invariant: anytime the idmap data encoding is changed, the idmap version
// field *must* be incremented. Because of this, we know that if the idmap
// header is up-to-date the entire file is up-to-date.
Result<Unit> IsUpToDate() const;
Result<Unit> IsUpToDate(uint32_t target_crc_) const;
Result<Unit> IsUpToDate(const char* target_path, const char* overlay_path,
uint32_t fulfilled_policies, bool enforce_overlayable) const;
Result<Unit> IsUpToDate(const char* target_path, const char* overlay_path, uint32_t target_crc,
uint32_t overlay_crc, uint32_t fulfilled_policies,
bool enforce_overlayable) const;
void accept(Visitor* v) const;
@@ -145,6 +156,8 @@ class IdmapHeader {
uint32_t version_;
uint32_t target_crc_;
uint32_t overlay_crc_;
uint32_t fulfilled_policies_;
bool enforce_overlayable_;
char target_path_[kIdmapStringLength];
char overlay_path_[kIdmapStringLength];
std::string debug_info_;

View File

@@ -66,6 +66,8 @@ void BinaryStreamVisitor::visit(const IdmapHeader& header) {
Write32(header.GetVersion());
Write32(header.GetTargetCrc());
Write32(header.GetOverlayCrc());
Write32(header.GetFulfilledPolicies());
Write8(static_cast<uint8_t>(header.GetEnforceOverlayable()));
WriteString256(header.GetTargetPath());
WriteString256(header.GetOverlayPath());
WriteString(header.GetDebugInfo());

View File

@@ -112,14 +112,18 @@ Result<uint32_t> GetPackageCrc(const ZipFile& zip) {
std::unique_ptr<const IdmapHeader> IdmapHeader::FromBinaryStream(std::istream& stream) {
std::unique_ptr<IdmapHeader> idmap_header(new IdmapHeader());
uint8_t enforce_overlayable;
if (!Read32(stream, &idmap_header->magic_) || !Read32(stream, &idmap_header->version_) ||
!Read32(stream, &idmap_header->target_crc_) || !Read32(stream, &idmap_header->overlay_crc_) ||
!Read32(stream, &idmap_header->fulfilled_policies_) ||
!Read8(stream, &enforce_overlayable) ||
!ReadString256(stream, idmap_header->target_path_) ||
!ReadString256(stream, idmap_header->overlay_path_)) {
return nullptr;
}
idmap_header->enforce_overlayable_ = static_cast<bool>(enforce_overlayable);
auto debug_str = ReadString(stream);
if (!debug_str) {
return nullptr;
@@ -129,21 +133,35 @@ std::unique_ptr<const IdmapHeader> IdmapHeader::FromBinaryStream(std::istream& s
return std::move(idmap_header);
}
Result<Unit> IdmapHeader::IsUpToDate() const {
const std::unique_ptr<const ZipFile> target_zip = ZipFile::Open(target_path_);
Result<Unit> IdmapHeader::IsUpToDate(const char* target_path, const char* overlay_path,
uint32_t fulfilled_policies, bool enforce_overlayable) const {
const std::unique_ptr<const ZipFile> target_zip = ZipFile::Open(target_path);
if (!target_zip) {
return Error("failed to open target %s", GetTargetPath().to_string().c_str());
return Error("failed to open target %s", target_path);
}
Result<uint32_t> target_crc = GetPackageCrc(*target_zip);
const Result<uint32_t> target_crc = GetPackageCrc(*target_zip);
if (!target_crc) {
return Error("failed to get target crc");
}
return IsUpToDate(*target_crc);
const std::unique_ptr<const ZipFile> overlay_zip = ZipFile::Open(overlay_path);
if (!overlay_zip) {
return Error("failed to overlay target %s", overlay_path);
}
const Result<uint32_t> overlay_crc = GetPackageCrc(*overlay_zip);
if (!overlay_crc) {
return Error("failed to get overlay crc");
}
return IsUpToDate(target_path, overlay_path, *target_crc, *overlay_crc, fulfilled_policies,
enforce_overlayable);
}
Result<Unit> IdmapHeader::IsUpToDate(uint32_t target_crc) const {
Result<Unit> IdmapHeader::IsUpToDate(const char* target_path, const char* overlay_path,
uint32_t target_crc, uint32_t overlay_crc,
uint32_t fulfilled_policies, bool enforce_overlayable) const {
if (magic_ != kIdmapMagic) {
return Error("bad magic: actual 0x%08x, expected 0x%08x", magic_, kIdmapMagic);
}
@@ -157,19 +175,30 @@ Result<Unit> IdmapHeader::IsUpToDate(uint32_t target_crc) const {
target_crc);
}
const std::unique_ptr<const ZipFile> overlay_zip = ZipFile::Open(overlay_path_);
if (!overlay_zip) {
return Error("failed to open overlay %s", GetOverlayPath().to_string().c_str());
}
Result<uint32_t> overlay_crc = GetPackageCrc(*overlay_zip);
if (!overlay_crc) {
return Error("failed to get overlay crc");
}
if (overlay_crc_ != *overlay_crc) {
if (overlay_crc_ != overlay_crc) {
return Error("bad overlay crc: idmap version 0x%08x, file system version 0x%08x", overlay_crc_,
*overlay_crc);
overlay_crc);
}
if (fulfilled_policies_ != fulfilled_policies) {
return Error("bad fulfilled policies: idmap version 0x%08x, file system version 0x%08x",
fulfilled_policies, fulfilled_policies_);
}
if (enforce_overlayable != enforce_overlayable_) {
return Error("bad enforce overlayable: idmap version %s, file system version %s",
enforce_overlayable ? "true" : "false",
enforce_overlayable_ ? "true" : "false");
}
if (strcmp(target_path, target_path_) != 0) {
return Error("bad target path: idmap version %s, file system version %s", target_path,
target_path_);
}
if (strcmp(overlay_path, overlay_path_) != 0) {
return Error("bad overlay path: idmap version %s, file system version %s", overlay_path,
overlay_path_);
}
return Unit{};
@@ -320,6 +349,9 @@ Result<std::unique_ptr<const Idmap>> Idmap::FromApkAssets(const ApkAssets& targe
}
header->overlay_crc_ = *crc;
header->fulfilled_policies_ = fulfilled_policies;
header->enforce_overlayable_ = enforce_overlayable;
if (target_apk_path.size() > sizeof(header->target_path_)) {
return Error("target apk path \"%s\" longer than maximum size %zu", target_apk_path.c_str(),
sizeof(header->target_path_));

View File

@@ -23,10 +23,12 @@
#include "android-base/macros.h"
#include "android-base/stringprintf.h"
#include "androidfw/ApkAssets.h"
#include "idmap2/PolicyUtils.h"
#include "idmap2/ResourceUtils.h"
#include "idmap2/Result.h"
using android::ApkAssets;
using android::idmap2::policy::PoliciesToDebugString;
namespace {
@@ -39,9 +41,6 @@ size_t StringSizeWhenEncoded(const std::string& s) {
namespace android::idmap2 {
// verbatim copy fomr PrettyPrintVisitor.cpp, move to common utils
#define RESID(pkg, type, entry) (((pkg) << 24) | ((type) << 16) | (entry))
void RawPrintVisitor::visit(const Idmap& idmap ATTRIBUTE_UNUSED) {
}
@@ -50,6 +49,9 @@ void RawPrintVisitor::visit(const IdmapHeader& header) {
print(header.GetVersion(), "version");
print(header.GetTargetCrc(), "target crc");
print(header.GetOverlayCrc(), "overlay crc");
print(header.GetFulfilledPolicies(), "fulfilled policies: %s",
PoliciesToDebugString(header.GetFulfilledPolicies()).c_str());
print(static_cast<uint8_t>(header.GetEnforceOverlayable()), "enforce overlayable");
print(header.GetTargetPath().to_string(), kIdmapStringLength, "target path");
print(header.GetOverlayPath().to_string(), kIdmapStringLength, "overlay path");
print("...", StringSizeWhenEncoded(header.GetDebugInfo()), "debug info");

View File

@@ -291,13 +291,6 @@ Result<ResourceMapping> ResourceMapping::FromApkAssets(const ApkAssets& target_a
const PolicyBitmask& fulfilled_policies,
bool enforce_overlayable,
LogInfo& log_info) {
if (enforce_overlayable) {
log_info.Info(LogMessage() << "fulfilled_policies="
<< ConcatPolicies(BitmaskToPolicies(fulfilled_policies))
<< " enforce_overlayable="
<< (enforce_overlayable ? "true" : "false"));
}
AssetManager2 target_asset_manager;
if (!target_asset_manager.SetApkAssets({&target_apk_assets}, true /* invalidate_caches */,
false /* filter_incompatible_configs*/)) {

View File

@@ -21,9 +21,12 @@
#include <string>
#include <vector>
#include "android-base/stringprintf.h"
#include "androidfw/ResourceTypes.h"
#include "androidfw/StringPiece.h"
using android::base::StringPrintf;
using PolicyBitmask = android::ResTable_overlayable_policy_header::PolicyBitmask;
using PolicyFlags = android::ResTable_overlayable_policy_header::PolicyFlags;
@@ -48,6 +51,29 @@ inline static const std::array<std::pair<StringPiece, PolicyFlags>, 8> kPolicySt
{kPolicySystem, PolicyFlags::SYSTEM_PARTITION},
{kPolicyVendor, PolicyFlags::VENDOR_PARTITION},
};
inline static std::string PoliciesToDebugString(PolicyBitmask policies) {
std::string str;
uint32_t remaining = policies;
for (auto const& policy : kPolicyStringToFlag) {
if ((policies & policy.second) != policy.second) {
continue;
}
if (!str.empty()) {
str.append("|");
}
str.append(policy.first.data());
remaining &= ~policy.second;
}
if (remaining != 0) {
if (!str.empty()) {
str.append("|");
}
str.append(StringPrintf("0x%08x", remaining));
}
return !str.empty() ? str : "none";
}
} // namespace android::idmap2::policy
#endif // IDMAP2_INCLUDE_IDMAP2_POLICIES_H_

View File

@@ -48,6 +48,11 @@ TEST(BinaryStreamVisitorTests, CreateBinaryStreamViaBinaryStreamVisitor) {
ASSERT_TRUE(result2);
const auto idmap2 = std::move(*result2);
ASSERT_EQ(idmap1->GetHeader()->GetFulfilledPolicies(),
idmap2->GetHeader()->GetFulfilledPolicies());
ASSERT_EQ(idmap1->GetHeader()->GetEnforceOverlayable(),
idmap2->GetHeader()->GetEnforceOverlayable());
ASSERT_EQ(idmap1->GetHeader()->GetTargetPath(), idmap2->GetHeader()->GetTargetPath());
ASSERT_EQ(idmap1->GetHeader()->GetTargetCrc(), idmap2->GetHeader()->GetTargetCrc());
ASSERT_EQ(idmap1->GetHeader()->GetTargetPath(), idmap2->GetHeader()->GetTargetPath());
ASSERT_EQ(idmap1->GetData().size(), 1U);

View File

@@ -62,9 +62,11 @@ TEST(IdmapTests, CreateIdmapHeaderFromBinaryStream) {
std::unique_ptr<const IdmapHeader> header = IdmapHeader::FromBinaryStream(stream);
ASSERT_THAT(header, NotNull());
ASSERT_EQ(header->GetMagic(), 0x504d4449U);
ASSERT_EQ(header->GetVersion(), 0x03U);
ASSERT_EQ(header->GetVersion(), 0x04U);
ASSERT_EQ(header->GetTargetCrc(), 0x1234U);
ASSERT_EQ(header->GetOverlayCrc(), 0x5678U);
ASSERT_EQ(header->GetFulfilledPolicies(), 0x11);
ASSERT_EQ(header->GetEnforceOverlayable(), true);
ASSERT_EQ(header->GetTargetPath().to_string(), "targetX.apk");
ASSERT_EQ(header->GetOverlayPath().to_string(), "overlayX.apk");
ASSERT_EQ(header->GetDebugInfo(), "debug");
@@ -73,7 +75,7 @@ TEST(IdmapTests, CreateIdmapHeaderFromBinaryStream) {
TEST(IdmapTests, FailToCreateIdmapHeaderFromBinaryStreamIfPathTooLong) {
std::string raw(reinterpret_cast<const char*>(idmap_raw_data), idmap_raw_data_len);
// overwrite the target path string, including the terminating null, with '.'
for (size_t i = 0x10; i < 0x110; i++) {
for (size_t i = 0x15; i < 0x115; i++) {
raw[i] = '.';
}
std::istringstream stream(raw);
@@ -82,7 +84,7 @@ TEST(IdmapTests, FailToCreateIdmapHeaderFromBinaryStreamIfPathTooLong) {
}
TEST(IdmapTests, CreateIdmapDataHeaderFromBinaryStream) {
const size_t offset = 0x21c;
const size_t offset = 0x221;
std::string raw(reinterpret_cast<const char*>(idmap_raw_data + offset),
idmap_raw_data_len - offset);
std::istringstream stream(raw);
@@ -94,7 +96,7 @@ TEST(IdmapTests, CreateIdmapDataHeaderFromBinaryStream) {
}
TEST(IdmapTests, CreateIdmapDataFromBinaryStream) {
const size_t offset = 0x21c;
const size_t offset = 0x221;
std::string raw(reinterpret_cast<const char*>(idmap_raw_data + offset),
idmap_raw_data_len - offset);
std::istringstream stream(raw);
@@ -128,9 +130,11 @@ TEST(IdmapTests, CreateIdmapFromBinaryStream) {
ASSERT_THAT(idmap->GetHeader(), NotNull());
ASSERT_EQ(idmap->GetHeader()->GetMagic(), 0x504d4449U);
ASSERT_EQ(idmap->GetHeader()->GetVersion(), 0x03U);
ASSERT_EQ(idmap->GetHeader()->GetVersion(), 0x04U);
ASSERT_EQ(idmap->GetHeader()->GetTargetCrc(), 0x1234U);
ASSERT_EQ(idmap->GetHeader()->GetOverlayCrc(), 0x5678U);
ASSERT_EQ(idmap->GetHeader()->GetFulfilledPolicies(), 0x11);
ASSERT_EQ(idmap->GetHeader()->GetEnforceOverlayable(), true);
ASSERT_EQ(idmap->GetHeader()->GetTargetPath().to_string(), "targetX.apk");
ASSERT_EQ(idmap->GetHeader()->GetOverlayPath().to_string(), "overlayX.apk");
@@ -180,9 +184,11 @@ TEST(IdmapTests, CreateIdmapHeaderFromApkAssets) {
ASSERT_THAT(idmap->GetHeader(), NotNull());
ASSERT_EQ(idmap->GetHeader()->GetMagic(), 0x504d4449U);
ASSERT_EQ(idmap->GetHeader()->GetVersion(), 0x03U);
ASSERT_EQ(idmap->GetHeader()->GetVersion(), 0x04U);
ASSERT_EQ(idmap->GetHeader()->GetTargetCrc(), android::idmap2::TestConstants::TARGET_CRC);
ASSERT_EQ(idmap->GetHeader()->GetOverlayCrc(), android::idmap2::TestConstants::OVERLAY_CRC);
ASSERT_EQ(idmap->GetHeader()->GetFulfilledPolicies(), PolicyFlags::PUBLIC);
ASSERT_EQ(idmap->GetHeader()->GetEnforceOverlayable(), true);
ASSERT_EQ(idmap->GetHeader()->GetTargetPath().to_string(), target_apk_path);
ASSERT_EQ(idmap->GetHeader()->GetOverlayPath(), overlay_apk_path);
}
@@ -389,7 +395,8 @@ TEST(IdmapTests, IdmapHeaderIsUpToDate) {
std::unique_ptr<const IdmapHeader> header = IdmapHeader::FromBinaryStream(stream);
ASSERT_THAT(header, NotNull());
ASSERT_TRUE(header->IsUpToDate());
ASSERT_TRUE(header->IsUpToDate(target_apk_path.c_str(), overlay_apk_path.c_str(),
PolicyFlags::PUBLIC, /* enforce_overlayable */ true));
// magic: bytes (0x0, 0x03)
std::string bad_magic_string(stream.str());
@@ -402,7 +409,8 @@ TEST(IdmapTests, IdmapHeaderIsUpToDate) {
IdmapHeader::FromBinaryStream(bad_magic_stream);
ASSERT_THAT(bad_magic_header, NotNull());
ASSERT_NE(header->GetMagic(), bad_magic_header->GetMagic());
ASSERT_FALSE(bad_magic_header->IsUpToDate());
ASSERT_FALSE(bad_magic_header->IsUpToDate(target_apk_path.c_str(), overlay_apk_path.c_str(),
PolicyFlags::PUBLIC, /* enforce_overlayable */ true));
// version: bytes (0x4, 0x07)
std::string bad_version_string(stream.str());
@@ -415,7 +423,8 @@ TEST(IdmapTests, IdmapHeaderIsUpToDate) {
IdmapHeader::FromBinaryStream(bad_version_stream);
ASSERT_THAT(bad_version_header, NotNull());
ASSERT_NE(header->GetVersion(), bad_version_header->GetVersion());
ASSERT_FALSE(bad_version_header->IsUpToDate());
ASSERT_FALSE(bad_magic_header->IsUpToDate(target_apk_path.c_str(), overlay_apk_path.c_str(),
PolicyFlags::PUBLIC, /* enforce_overlayable */ true));
// target crc: bytes (0x8, 0xb)
std::string bad_target_crc_string(stream.str());
@@ -428,7 +437,8 @@ TEST(IdmapTests, IdmapHeaderIsUpToDate) {
IdmapHeader::FromBinaryStream(bad_target_crc_stream);
ASSERT_THAT(bad_target_crc_header, NotNull());
ASSERT_NE(header->GetTargetCrc(), bad_target_crc_header->GetTargetCrc());
ASSERT_FALSE(bad_target_crc_header->IsUpToDate());
ASSERT_FALSE(bad_magic_header->IsUpToDate(target_apk_path.c_str(), overlay_apk_path.c_str(),
PolicyFlags::PUBLIC, /* enforce_overlayable */ true));
// overlay crc: bytes (0xc, 0xf)
std::string bad_overlay_crc_string(stream.str());
@@ -441,27 +451,55 @@ TEST(IdmapTests, IdmapHeaderIsUpToDate) {
IdmapHeader::FromBinaryStream(bad_overlay_crc_stream);
ASSERT_THAT(bad_overlay_crc_header, NotNull());
ASSERT_NE(header->GetOverlayCrc(), bad_overlay_crc_header->GetOverlayCrc());
ASSERT_FALSE(bad_overlay_crc_header->IsUpToDate());
ASSERT_FALSE(bad_magic_header->IsUpToDate(target_apk_path.c_str(), overlay_apk_path.c_str(),
PolicyFlags::PUBLIC, /* enforce_overlayable */ true));
// target path: bytes (0x10, 0x10f)
// fulfilled policy: bytes (0x10, 0x13)
std::string bad_policy_string(stream.str());
bad_policy_string[0x10] = '.';
bad_policy_string[0x11] = '.';
bad_policy_string[0x12] = '.';
bad_policy_string[0x13] = '.';
std::stringstream bad_policy_stream(bad_policy_string);
std::unique_ptr<const IdmapHeader> bad_policy_header =
IdmapHeader::FromBinaryStream(bad_policy_stream);
ASSERT_THAT(bad_policy_header, NotNull());
ASSERT_NE(header->GetFulfilledPolicies(), bad_policy_header->GetFulfilledPolicies());
ASSERT_FALSE(bad_policy_header->IsUpToDate(target_apk_path.c_str(), overlay_apk_path.c_str(),
PolicyFlags::PUBLIC, /* enforce_overlayable */ true));
// enforce overlayable: bytes (0x14)
std::string bad_enforce_string(stream.str());
bad_enforce_string[0x14] = '\0';
std::stringstream bad_enforce_stream(bad_enforce_string);
std::unique_ptr<const IdmapHeader> bad_enforce_header =
IdmapHeader::FromBinaryStream(bad_enforce_stream);
ASSERT_THAT(bad_enforce_header, NotNull());
ASSERT_NE(header->GetEnforceOverlayable(), bad_enforce_header->GetEnforceOverlayable());
ASSERT_FALSE(bad_enforce_header->IsUpToDate(target_apk_path.c_str(), overlay_apk_path.c_str(),
PolicyFlags::PUBLIC, /* enforce_overlayable */ true));
// target path: bytes (0x15, 0x114)
std::string bad_target_path_string(stream.str());
bad_target_path_string[0x10] = '\0';
bad_target_path_string[0x15] = '\0';
std::stringstream bad_target_path_stream(bad_target_path_string);
std::unique_ptr<const IdmapHeader> bad_target_path_header =
IdmapHeader::FromBinaryStream(bad_target_path_stream);
ASSERT_THAT(bad_target_path_header, NotNull());
ASSERT_NE(header->GetTargetPath(), bad_target_path_header->GetTargetPath());
ASSERT_FALSE(bad_target_path_header->IsUpToDate());
ASSERT_FALSE(bad_magic_header->IsUpToDate(target_apk_path.c_str(), overlay_apk_path.c_str(),
PolicyFlags::PUBLIC, /* enforce_overlayable */ true));
// overlay path: bytes (0x110, 0x20f)
// overlay path: bytes (0x115, 0x214)
std::string bad_overlay_path_string(stream.str());
bad_overlay_path_string[0x110] = '\0';
bad_overlay_path_string[0x115] = '\0';
std::stringstream bad_overlay_path_stream(bad_overlay_path_string);
std::unique_ptr<const IdmapHeader> bad_overlay_path_header =
IdmapHeader::FromBinaryStream(bad_overlay_path_stream);
ASSERT_THAT(bad_overlay_path_header, NotNull());
ASSERT_NE(header->GetOverlayPath(), bad_overlay_path_header->GetOverlayPath());
ASSERT_FALSE(bad_overlay_path_header->IsUpToDate());
ASSERT_FALSE(bad_magic_header->IsUpToDate(target_apk_path.c_str(), overlay_apk_path.c_str(),
PolicyFlags::PUBLIC, /* enforce_overlayable */ true));
}
class TestVisitor : public Visitor {

View File

@@ -43,6 +43,8 @@ namespace android::idmap2 {
<< str << "--------"; \
} while (0)
#define ADDRESS "[0-9a-f]{8}: "
TEST(RawPrintVisitorTests, CreateRawPrintVisitor) {
fclose(stderr); // silence expected warnings
@@ -62,15 +64,16 @@ TEST(RawPrintVisitorTests, CreateRawPrintVisitor) {
RawPrintVisitor visitor(stream);
(*idmap)->accept(&visitor);
#define ADDRESS "[0-9a-f]{8}: "
ASSERT_CONTAINS_REGEX(ADDRESS "504d4449 magic\n", stream.str());
ASSERT_CONTAINS_REGEX(ADDRESS "00000003 version\n", stream.str());
ASSERT_CONTAINS_REGEX(ADDRESS "00000004 version\n", stream.str());
ASSERT_CONTAINS_REGEX(
StringPrintf(ADDRESS "%s target crc\n", android::idmap2::TestConstants::TARGET_CRC_STRING),
stream.str());
ASSERT_CONTAINS_REGEX(
StringPrintf(ADDRESS "%s overlay crc\n", android::idmap2::TestConstants::OVERLAY_CRC_STRING),
stream.str());
ASSERT_CONTAINS_REGEX(ADDRESS "00000001 fulfilled policies: public\n", stream.str());
ASSERT_CONTAINS_REGEX(ADDRESS " 01 enforce overlayable\n", stream.str());
ASSERT_CONTAINS_REGEX(ADDRESS " 7f target package id\n", stream.str());
ASSERT_CONTAINS_REGEX(ADDRESS " 7f overlay package id\n", stream.str());
ASSERT_CONTAINS_REGEX(ADDRESS "00000004 target entry count\n", stream.str());
@@ -83,7 +86,6 @@ TEST(RawPrintVisitorTests, CreateRawPrintVisitor) {
ASSERT_CONTAINS_REGEX(ADDRESS "7f010000 value: integer/int1\n", stream.str());
ASSERT_CONTAINS_REGEX(ADDRESS "7f010000 overlay id: integer/int1\n", stream.str());
ASSERT_CONTAINS_REGEX(ADDRESS "7f010000 target id: integer/int1\n", stream.str());
#undef ADDRESS
}
TEST(RawPrintVisitorTests, CreateRawPrintVisitorWithoutAccessToApks) {
@@ -99,22 +101,23 @@ TEST(RawPrintVisitorTests, CreateRawPrintVisitorWithoutAccessToApks) {
RawPrintVisitor visitor(stream);
(*idmap)->accept(&visitor);
ASSERT_NE(stream.str().find("00000000: 504d4449 magic\n"), std::string::npos);
ASSERT_NE(stream.str().find("00000004: 00000003 version\n"), std::string::npos);
ASSERT_NE(stream.str().find("00000008: 00001234 target crc\n"), std::string::npos);
ASSERT_NE(stream.str().find("0000000c: 00005678 overlay crc\n"), std::string::npos);
ASSERT_NE(stream.str().find("0000021c: 7f target package id\n"), std::string::npos);
ASSERT_NE(stream.str().find("0000021d: 7f overlay package id\n"), std::string::npos);
ASSERT_NE(stream.str().find("0000021e: 00000003 target entry count\n"), std::string::npos);
ASSERT_NE(stream.str().find("00000222: 00000003 overlay entry count\n"), std::string::npos);
ASSERT_NE(stream.str().find("00000226: 00000000 string pool index offset\n"), std::string::npos);
ASSERT_NE(stream.str().find("0000022a: 00000000 string pool byte length\n"), std::string::npos);
ASSERT_NE(stream.str().find("0000022e: 7f020000 target id\n"), std::string::npos);
ASSERT_NE(stream.str().find("00000232: 01 type: reference\n"), std::string::npos);
ASSERT_NE(stream.str().find("00000233: 7f020000 value\n"), std::string::npos);
ASSERT_NE(stream.str().find("00000249: 7f020000 overlay id\n"), std::string::npos);
ASSERT_NE(stream.str().find("0000024d: 7f020000 target id\n"), std::string::npos);
ASSERT_CONTAINS_REGEX(ADDRESS "504d4449 magic\n", stream.str());
ASSERT_CONTAINS_REGEX(ADDRESS "00000004 version\n", stream.str());
ASSERT_CONTAINS_REGEX(ADDRESS "00001234 target crc\n", stream.str());
ASSERT_CONTAINS_REGEX(ADDRESS "00005678 overlay crc\n", stream.str());
ASSERT_CONTAINS_REGEX(ADDRESS "00000011 fulfilled policies: public|signature\n", stream.str());
ASSERT_CONTAINS_REGEX(ADDRESS " 01 enforce overlayable\n", stream.str());
ASSERT_CONTAINS_REGEX(ADDRESS " 7f target package id\n", stream.str());
ASSERT_CONTAINS_REGEX(ADDRESS " 7f overlay package id\n", stream.str());
ASSERT_CONTAINS_REGEX(ADDRESS "00000003 target entry count\n", stream.str());
ASSERT_CONTAINS_REGEX(ADDRESS "00000003 overlay entry count\n", stream.str());
ASSERT_CONTAINS_REGEX(ADDRESS "00000000 string pool index offset\n", stream.str());
ASSERT_CONTAINS_REGEX(ADDRESS "00000000 string pool byte length\n", stream.str());
ASSERT_CONTAINS_REGEX(ADDRESS "7f020000 target id\n", stream.str());
ASSERT_CONTAINS_REGEX(ADDRESS " 01 type: reference\n", stream.str());
ASSERT_CONTAINS_REGEX(ADDRESS "7f020000 value\n", stream.str());
ASSERT_CONTAINS_REGEX(ADDRESS "7f020000 overlay id\n", stream.str());
ASSERT_CONTAINS_REGEX(ADDRESS "7f020000 target id\n", stream.str());
}
} // namespace android::idmap2

View File

@@ -30,7 +30,7 @@ const unsigned char idmap_raw_data[] = {
0x49, 0x44, 0x4d, 0x50,
// 0x4: version
0x03, 0x00, 0x00, 0x00,
0x04, 0x00, 0x00, 0x00,
// 0x8: target crc
0x34, 0x12, 0x00, 0x00,
@@ -38,7 +38,13 @@ const unsigned char idmap_raw_data[] = {
// 0xc: overlay crc
0x78, 0x56, 0x00, 0x00,
// 0x10: target path "targetX.apk"
// 0x10: fulfilled policies
0x11, 0x00, 0x00, 0x00,
// 0x14: enforce overlayable
0x01,
// 0x15: target path "targetX.apk"
0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x58, 0x2e, 0x61, 0x70, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -56,7 +62,7 @@ const unsigned char idmap_raw_data[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// 0x110: overlay path "overlayX.apk"
// 0x115: overlay path "overlayX.apk"
0x6f, 0x76, 0x65, 0x72, 0x6c, 0x61, 0x79, 0x58, 0x2e, 0x61, 0x70, 0x6b, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -74,7 +80,7 @@ const unsigned char idmap_raw_data[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// 0x210: debug string
// 0x215: debug string
// string length, including terminating null
0x08, 0x00, 0x00, 0x00,
@@ -82,63 +88,63 @@ const unsigned char idmap_raw_data[] = {
0x64, 0x65, 0x62, 0x75, 0x67, 0x00, 0x00, 0x00,
// DATA HEADER
// 0x21c: target_package_id
// 0x221: target_package_id
0x7f,
// 0x21d: overlay_package_id
// 0x222: overlay_package_id
0x7f,
// 0x21e: target_entry_count
// 0x223: target_entry_count
0x03, 0x00, 0x00, 0x00,
// 0x222: overlay_entry_count
// 0x227: overlay_entry_count
0x03, 0x00, 0x00, 0x00,
// 0x226: string_pool_offset
// 0x22b: string_pool_offset
0x00, 0x00, 0x00, 0x00,
// 0x22a: string_pool_byte_length
// 0x22f: string_pool_byte_length
0x00, 0x00, 0x00, 0x00,
// TARGET ENTRIES
// 0x22e: 0x7f020000
0x00, 0x00, 0x02, 0x7f,
// 0x232: TYPE_REFERENCE
0x01,
// 0x233: 0x7f020000
0x00, 0x00, 0x02, 0x7f,
// 0x237: 0x7f030000
0x00, 0x00, 0x03, 0x7f,
// 0x23b: TYPE_REFERENCE
// 0x237: TYPE_REFERENCE
0x01,
// 0x238: 0x7f020000
0x00, 0x00, 0x02, 0x7f,
// 0x23c: 0x7f030000
0x00, 0x00, 0x03, 0x7f,
// 0x240: 0x7f030002
0x02, 0x00, 0x03, 0x7f,
// 0x244: TYPE_REFERENCE
// 0x240: TYPE_REFERENCE
0x01,
// 0x245: 0x7f030001
// 0x241: 0x7f030000
0x00, 0x00, 0x03, 0x7f,
// 0x245: 0x7f030002
0x02, 0x00, 0x03, 0x7f,
// 0x249: TYPE_REFERENCE
0x01,
// 0x24a: 0x7f030001
0x01, 0x00, 0x03, 0x7f,
// OVERLAY ENTRIES
// 0x249: 0x7f020000 -> 0x7f020000
// 0x24e: 0x7f020000 -> 0x7f020000
0x00, 0x00, 0x02, 0x7f, 0x00, 0x00, 0x02, 0x7f,
// 0x251: 0x7f030000 -> 0x7f030000
// 0x256: 0x7f030000 -> 0x7f030000
0x00, 0x00, 0x03, 0x7f, 0x00, 0x00, 0x03, 0x7f,
// 0x259: 0x7f030001 -> 0x7f030002
// 0x25e: 0x7f030001 -> 0x7f030002
0x01, 0x00, 0x03, 0x7f, 0x02, 0x00, 0x03, 0x7f};
const unsigned int idmap_raw_data_len = 0x261;
const unsigned int idmap_raw_data_len = 0x266;
std::string GetTestDataPath();

View File

@@ -28,5 +28,6 @@ java_test_host {
":OverlayRemountedTest_Target",
":OverlayRemountedTest_TargetUpgrade",
":OverlayRemountedTest_Overlay",
":OverlayRemountedTest_Overlay_SameCert",
],
}

View File

@@ -22,7 +22,9 @@ import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
public class PackagedUpgradedTest extends OverlayRemountedTestBase {
public class RegenerateIdmapTest extends OverlayRemountedTestBase {
private static final String OVERLAY_SIGNATURE_APK =
"OverlayRemountedTest_Overlay_SameCert.apk";
private static final String TARGET_UPGRADE_APK = "OverlayRemountedTest_TargetUpgrade.apk";
@Test
@@ -66,4 +68,32 @@ public class PackagedUpgradedTest extends OverlayRemountedTestBase {
assertResource(targetReference, "@" + 0x7f0100ff + " -> true");
assertResource(targetOverlaid, "true");
}
@Test
public void testIdmapPoliciesChanged() throws Exception {
final String targetResource = resourceName(TARGET_PACKAGE, "bool",
"signature_policy_overlaid");
mPreparer.pushResourceFile(TARGET_APK, "/product/app/OverlayTarget.apk")
.pushResourceFile(OVERLAY_APK, "/product/overlay/TestOverlay.apk")
.reboot()
.setOverlayEnabled(OVERLAY_PACKAGE, false);
assertResource(targetResource, "false");
// The overlay is not signed with the same signature as the target.
mPreparer.setOverlayEnabled(OVERLAY_PACKAGE, true);
assertResource(targetResource, "false");
// Replace the overlay with a version of the overlay that is signed with the same signature
// as the target.
mPreparer.pushResourceFile(OVERLAY_SIGNATURE_APK, "/product/overlay/TestOverlay.apk")
.reboot();
// The idmap should have been recreated with the signature policy fulfilled.
assertResource(targetResource, "true");
mPreparer.setOverlayEnabled(OVERLAY_PACKAGE, false);
assertResource(targetResource, "false");
}
}

View File

@@ -19,3 +19,9 @@ android_test_helper_app {
"com.android.overlaytest.overlay",
],
}
android_test_helper_app {
name: "OverlayRemountedTest_Overlay_SameCert",
certificate: ":rro-remounted-test-a",
sdk_version: "current",
}

View File

@@ -17,4 +17,5 @@
<resources>
<bool name="target_overlaid">true</bool>
<bool name="signature_policy_overlaid">true</bool>
</resources>

View File

@@ -15,6 +15,7 @@
android_test_helper_app {
name: "OverlayRemountedTest_Target",
sdk_version: "test_current",
certificate: ":rro-remounted-test-a",
apex_available: [
"com.android.overlaytest.overlaid",
],
@@ -23,6 +24,7 @@ android_test_helper_app {
android_test_helper_app {
name: "OverlayRemountedTest_TargetUpgrade",
certificate: ":rro-remounted-test-a",
resource_dirs: ["res_upgrade"],
sdk_version: "test_current",
}

View File

@@ -20,5 +20,8 @@
<policy type="public">
<item type="bool" name="target_overlaid" />
</policy>
<policy type="signature">
<item type="bool" name="signature_policy_overlaid" />
</policy>
</overlayable>
</resources>

View File

@@ -23,4 +23,6 @@
<bool name="target_overlaid">false</bool>
<public type="bool" name="target_overlaid" id="0x7f010000" />
<bool name="target_reference">@bool/target_overlaid</bool>
<bool name="signature_policy_overlaid">false</bool>
</resources>

View File

@@ -0,0 +1,19 @@
// Copyright (C) 2020 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// development/tools/make_key rro-remounted-test-a '/CN=rro_test_a'
android_app_certificate {
name: "rro-remounted-test-a",
certificate: "rro-remounted-test-a",
}

View File

@@ -0,0 +1,19 @@
-----BEGIN CERTIFICATE-----
MIIDCzCCAfOgAwIBAgIUfphI+C6W6V6RomsP7+CW5dO5cGcwDQYJKoZIhvcNAQEL
BQAwFTETMBEGA1UEAwwKcnJvX3Rlc3RfYTAeFw0yMDA1MTQxNjM4MDBaFw00NzA5
MzAxNjM4MDBaMBUxEzARBgNVBAMMCnJyb190ZXN0X2EwggEiMA0GCSqGSIb3DQEB
AQUAA4IBDwAwggEKAoIBAQCvXM8tcqQFwH7iQG6+8mAx2ADhwbtq+8Rcmiz7wviW
Yf/eFDRuvZ/ma6lxeVJ7mcbF7A5rinEKdgN5hlW2UlbTmuX5YOiXnX3Y2J5t+8Pi
aq787IvWxkawwkj0Oy1Hk01Z4w3HTYntYqi36bq4QyNpwh515VqgvEyCHT7IPtQi
XjfwcTW0thUlSDyDkgxq9NxNEJgaHHOamKkeMCO8CkBWkhlcPXvjcM8DPFmyzDI9
Czv8IYFZQbcG/N2GPH9hSteMnuC+zyoMio0V/VRctQGlAA8ATsheBkng0zcNRu9Z
GIavk5AaClmBFTeQx01j3HFSO8UDdDJ5Hk8uDTqecPLpAgMBAAGjUzBRMB0GA1Ud
DgQWBBSPbIdzSkPbzltj3qIS13LNDiyIiDAfBgNVHSMEGDAWgBSPbIdzSkPbzltj
3qIS13LNDiyIiDAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCH
QvvMGyMvVJaWMEJwVdUnszdXiAlUtDd/2HpdGOxW6xVVAvveP8hJ71gWFQ7Qs3Mr
3jxclbC37qVAPiQb8kkD8qUgoQYMC43asif6Jn65OU1QkDRF3bFHP+rZVSPEwtvl
YMbOzHPOLr7HESwlM7TB6EoZ4oOso++jTYI/OSif1MOKOMbOt4X/DE/PXf81ayFs
uRjpocBqnLwOourABMcaKbA92jB0LRTtgv5ngOJ3+5P1cTiHktFbnqVWa8/A3uSA
dNR5dpOUjH+nCHTwPl64b7R70PgDxnoqMs0xI7VtJovXor64OZy9P8WTdurz5V/z
k2IVSi032bf0aTxamvqV
-----END CERTIFICATE-----

View File

@@ -41,7 +41,7 @@
namespace android {
constexpr const static uint32_t kIdmapMagic = 0x504D4449u;
constexpr const static uint32_t kIdmapCurrentVersion = 0x00000003u;
constexpr const static uint32_t kIdmapCurrentVersion = 0x00000004u;
/**
* In C++11, char16_t is defined as *at least* 16 bits. We do a lot of
@@ -1746,6 +1746,9 @@ struct Idmap_header {
uint32_t target_crc32;
uint32_t overlay_crc32;
uint32_t fulfilled_policies;
uint8_t enforce_overlayable;
uint8_t target_path[256];
uint8_t overlay_path[256];

View File

@@ -252,29 +252,6 @@ class ValueBodyPrinter : public ConstValueVisitor {
Printer* printer_;
};
std::string OverlayablePoliciesToString(PolicyFlags policies) {
std::string str;
uint32_t remaining = policies;
for (auto const& policy : kPolicyStringToFlag) {
if ((policies & policy.second) != policy.second) {
continue;
}
if (!str.empty()) {
str.append("|");
}
str.append(policy.first.data());
remaining &= ~policy.second;
}
if (remaining != 0) {
if (!str.empty()) {
str.append("|");
}
str.append(StringPrintf("0x%08x", remaining));
}
return !str.empty() ? str : "none";
}
} // namespace
void Debug::PrintTable(const ResourceTable& table, const DebugPrintTableOptions& options,
@@ -575,7 +552,7 @@ void Debug::DumpOverlayable(const ResourceTable& table, text::Printer* printer)
overlayable_item.overlayable->name.c_str(),
overlayable_item.overlayable->actor.c_str());
const auto policy_subsection = StringPrintf(R"(policies="%s")",
OverlayablePoliciesToString(overlayable_item.policies).c_str());
android::idmap2::policy::PoliciesToDebugString(overlayable_item.policies).c_str());
const auto value =
StringPrintf("%s/%s", to_string(type->type).data(), entry->name.c_str());
items.push_back(DumpOverlayableEntry{overlayable_section, policy_subsection, value});