Merge "Add policies and enforce overlayable to header" into rvc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
2201f8b626
@@ -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: {
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
28
cmds/idmap2/idmap2/CommandUtils.h
Normal file
28
cmds/idmap2/idmap2/CommandUtils.h
Normal 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_
|
||||
@@ -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_
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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};
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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_;
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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_));
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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*/)) {
|
||||
|
||||
@@ -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_
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -28,5 +28,6 @@ java_test_host {
|
||||
":OverlayRemountedTest_Target",
|
||||
":OverlayRemountedTest_TargetUpgrade",
|
||||
":OverlayRemountedTest_Overlay",
|
||||
":OverlayRemountedTest_Overlay_SameCert",
|
||||
],
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
@@ -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",
|
||||
}
|
||||
@@ -17,4 +17,5 @@
|
||||
|
||||
<resources>
|
||||
<bool name="target_overlaid">true</bool>
|
||||
<bool name="signature_policy_overlaid">true</bool>
|
||||
</resources>
|
||||
|
||||
@@ -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",
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
19
core/tests/overlaytests/remount/test-apps/certs/Android.bp
Normal file
19
core/tests/overlaytests/remount/test-apps/certs/Android.bp
Normal 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",
|
||||
}
|
||||
Binary file not shown.
@@ -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-----
|
||||
@@ -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];
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -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});
|
||||
|
||||
Reference in New Issue
Block a user