OMS: Add config_signature policy handling am: 0f942f99ca
Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1453997 Change-Id: I779b6c73a37b0ccd42afa1b899a2b6e4a3c17f92
This commit is contained in:
@@ -29,4 +29,5 @@ interface OverlayablePolicy {
|
|||||||
const int ODM_PARTITION = 0x00000020;
|
const int ODM_PARTITION = 0x00000020;
|
||||||
const int OEM_PARTITION = 0x00000040;
|
const int OEM_PARTITION = 0x00000040;
|
||||||
const int ACTOR_SIGNATURE = 0x00000080;
|
const int ACTOR_SIGNATURE = 0x00000080;
|
||||||
|
const int CONFIG_SIGNATURE = 0x0000100;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,10 +61,13 @@ Result<Unit> CheckOverlayable(const LoadedPackage& target_package,
|
|||||||
const ResourceId& target_resource) {
|
const ResourceId& target_resource) {
|
||||||
static constexpr const PolicyBitmask sDefaultPolicies =
|
static constexpr const PolicyBitmask sDefaultPolicies =
|
||||||
PolicyFlags::ODM_PARTITION | PolicyFlags::OEM_PARTITION | PolicyFlags::SYSTEM_PARTITION |
|
PolicyFlags::ODM_PARTITION | PolicyFlags::OEM_PARTITION | PolicyFlags::SYSTEM_PARTITION |
|
||||||
PolicyFlags::VENDOR_PARTITION | PolicyFlags::PRODUCT_PARTITION | PolicyFlags::SIGNATURE;
|
PolicyFlags::VENDOR_PARTITION | PolicyFlags::PRODUCT_PARTITION | PolicyFlags::SIGNATURE |
|
||||||
|
PolicyFlags::CONFIG_SIGNATURE;
|
||||||
|
|
||||||
// If the resource does not have an overlayable definition, allow the resource to be overlaid if
|
// If the resource does not have an overlayable definition, allow the resource to be overlaid if
|
||||||
// the overlay is preinstalled or signed with the same signature as the target.
|
// the overlay is preinstalled, signed with the same signature as the target or signed with the
|
||||||
|
// same signature as reference package defined in SystemConfig under 'overlay-config-signature'
|
||||||
|
// tag.
|
||||||
if (!target_package.DefinesOverlayable()) {
|
if (!target_package.DefinesOverlayable()) {
|
||||||
return (sDefaultPolicies & fulfilled_policies) != 0
|
return (sDefaultPolicies & fulfilled_policies) != 0
|
||||||
? Result<Unit>({})
|
? Result<Unit>({})
|
||||||
|
|||||||
@@ -37,16 +37,18 @@ constexpr const char* kPolicyOdm = "odm";
|
|||||||
constexpr const char* kPolicyOem = "oem";
|
constexpr const char* kPolicyOem = "oem";
|
||||||
constexpr const char* kPolicyProduct = "product";
|
constexpr const char* kPolicyProduct = "product";
|
||||||
constexpr const char* kPolicyPublic = "public";
|
constexpr const char* kPolicyPublic = "public";
|
||||||
|
constexpr const char* kPolicyConfigSignature = "config_signature";
|
||||||
constexpr const char* kPolicySignature = "signature";
|
constexpr const char* kPolicySignature = "signature";
|
||||||
constexpr const char* kPolicySystem = "system";
|
constexpr const char* kPolicySystem = "system";
|
||||||
constexpr const char* kPolicyVendor = "vendor";
|
constexpr const char* kPolicyVendor = "vendor";
|
||||||
|
|
||||||
inline static const std::array<std::pair<StringPiece, PolicyFlags>, 8> kPolicyStringToFlag = {
|
inline static const std::array<std::pair<StringPiece, PolicyFlags>, 9> kPolicyStringToFlag = {
|
||||||
std::pair{kPolicyActor, PolicyFlags::ACTOR_SIGNATURE},
|
std::pair{kPolicyActor, PolicyFlags::ACTOR_SIGNATURE},
|
||||||
{kPolicyOdm, PolicyFlags::ODM_PARTITION},
|
{kPolicyOdm, PolicyFlags::ODM_PARTITION},
|
||||||
{kPolicyOem, PolicyFlags::OEM_PARTITION},
|
{kPolicyOem, PolicyFlags::OEM_PARTITION},
|
||||||
{kPolicyProduct, PolicyFlags::PRODUCT_PARTITION},
|
{kPolicyProduct, PolicyFlags::PRODUCT_PARTITION},
|
||||||
{kPolicyPublic, PolicyFlags::PUBLIC},
|
{kPolicyPublic, PolicyFlags::PUBLIC},
|
||||||
|
{kPolicyConfigSignature, PolicyFlags::CONFIG_SIGNATURE},
|
||||||
{kPolicySignature, PolicyFlags::SIGNATURE},
|
{kPolicySignature, PolicyFlags::SIGNATURE},
|
||||||
{kPolicySystem, PolicyFlags::SYSTEM_PARTITION},
|
{kPolicySystem, PolicyFlags::SYSTEM_PARTITION},
|
||||||
{kPolicyVendor, PolicyFlags::VENDOR_PARTITION},
|
{kPolicyVendor, PolicyFlags::VENDOR_PARTITION},
|
||||||
|
|||||||
@@ -41,16 +41,17 @@ namespace R::target {
|
|||||||
constexpr ResourceId not_overlayable = 0x7f020003;
|
constexpr ResourceId not_overlayable = 0x7f020003;
|
||||||
constexpr ResourceId other = 0x7f020004;
|
constexpr ResourceId other = 0x7f020004;
|
||||||
constexpr ResourceId policy_actor = 0x7f020005;
|
constexpr ResourceId policy_actor = 0x7f020005;
|
||||||
constexpr ResourceId policy_odm = 0x7f020006;
|
constexpr ResourceId policy_config_signature = 0x7f020006;
|
||||||
constexpr ResourceId policy_oem = 0x7f020007;
|
constexpr ResourceId policy_odm = 0x7f020007;
|
||||||
constexpr ResourceId policy_product = 0x7f020008;
|
constexpr ResourceId policy_oem = 0x7f020008;
|
||||||
constexpr ResourceId policy_public = 0x7f020009;
|
constexpr ResourceId policy_product = 0x7f020009;
|
||||||
constexpr ResourceId policy_signature = 0x7f02000a;
|
constexpr ResourceId policy_public = 0x7f02000a;
|
||||||
constexpr ResourceId policy_system = 0x7f02000b;
|
constexpr ResourceId policy_signature = 0x7f02000b;
|
||||||
constexpr ResourceId policy_system_vendor = 0x7f02000c;
|
constexpr ResourceId policy_system = 0x7f02000c;
|
||||||
constexpr ResourceId str1 = 0x7f02000d;
|
constexpr ResourceId policy_system_vendor = 0x7f02000d;
|
||||||
constexpr ResourceId str3 = 0x7f02000f;
|
constexpr ResourceId str1 = 0x7f02000e;
|
||||||
constexpr ResourceId str4 = 0x7f020010;
|
constexpr ResourceId str3 = 0x7f020010;
|
||||||
|
constexpr ResourceId str4 = 0x7f020011;
|
||||||
|
|
||||||
namespace literal {
|
namespace literal {
|
||||||
inline const std::string str1 = hexify(R::target::string::str1);
|
inline const std::string str1 = hexify(R::target::string::str1);
|
||||||
@@ -92,14 +93,15 @@ namespace R::system_overlay_invalid::string {
|
|||||||
constexpr ResourceId not_overlayable = 0x7f010000;
|
constexpr ResourceId not_overlayable = 0x7f010000;
|
||||||
constexpr ResourceId other = 0x7f010001;
|
constexpr ResourceId other = 0x7f010001;
|
||||||
constexpr ResourceId policy_actor = 0x7f010002;
|
constexpr ResourceId policy_actor = 0x7f010002;
|
||||||
constexpr ResourceId policy_odm = 0x7f010003;
|
constexpr ResourceId policy_config_signature = 0x7f010003;
|
||||||
constexpr ResourceId policy_oem = 0x7f010004;
|
constexpr ResourceId policy_odm = 0x7f010004;
|
||||||
constexpr ResourceId policy_product = 0x7f010005;
|
constexpr ResourceId policy_oem = 0x7f010005;
|
||||||
constexpr ResourceId policy_public = 0x7f010006;
|
constexpr ResourceId policy_product = 0x7f010006;
|
||||||
constexpr ResourceId policy_signature = 0x7f010007;
|
constexpr ResourceId policy_public = 0x7f010007;
|
||||||
constexpr ResourceId policy_system = 0x7f010008;
|
constexpr ResourceId policy_signature = 0x7f010008;
|
||||||
constexpr ResourceId policy_system_vendor = 0x7f010009;
|
constexpr ResourceId policy_system = 0x7f010009;
|
||||||
};
|
constexpr ResourceId policy_system_vendor = 0x7f01000a;
|
||||||
|
}
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
} // namespace android::idmap2
|
} // namespace android::idmap2
|
||||||
|
|||||||
@@ -237,7 +237,7 @@ TEST(ResourceMappingTests, ResourcesFromApkAssetsPolicySystemPublicInvalidIgnore
|
|||||||
|
|
||||||
ASSERT_TRUE(resources) << resources.GetErrorMessage();
|
ASSERT_TRUE(resources) << resources.GetErrorMessage();
|
||||||
auto& res = *resources;
|
auto& res = *resources;
|
||||||
ASSERT_EQ(res.GetTargetToOverlayMap().size(), 10U);
|
ASSERT_EQ(res.GetTargetToOverlayMap().size(), 11U);
|
||||||
ASSERT_RESULT(MappingExists(res, R::target::string::not_overlayable, Res_value::TYPE_REFERENCE,
|
ASSERT_RESULT(MappingExists(res, R::target::string::not_overlayable, Res_value::TYPE_REFERENCE,
|
||||||
R::system_overlay_invalid::string::not_overlayable,
|
R::system_overlay_invalid::string::not_overlayable,
|
||||||
false /* rewrite */));
|
false /* rewrite */));
|
||||||
@@ -256,6 +256,10 @@ TEST(ResourceMappingTests, ResourcesFromApkAssetsPolicySystemPublicInvalidIgnore
|
|||||||
ASSERT_RESULT(MappingExists(res, R::target::string::policy_public, Res_value::TYPE_REFERENCE,
|
ASSERT_RESULT(MappingExists(res, R::target::string::policy_public, Res_value::TYPE_REFERENCE,
|
||||||
R::system_overlay_invalid::string::policy_public,
|
R::system_overlay_invalid::string::policy_public,
|
||||||
false /* rewrite */));
|
false /* rewrite */));
|
||||||
|
ASSERT_RESULT(MappingExists(res, R::target::string::policy_config_signature,
|
||||||
|
Res_value::TYPE_REFERENCE,
|
||||||
|
R::system_overlay_invalid::string::policy_config_signature,
|
||||||
|
false /* rewrite */));
|
||||||
ASSERT_RESULT(MappingExists(res, R::target::string::policy_signature, Res_value::TYPE_REFERENCE,
|
ASSERT_RESULT(MappingExists(res, R::target::string::policy_signature, Res_value::TYPE_REFERENCE,
|
||||||
R::system_overlay_invalid::string::policy_signature,
|
R::system_overlay_invalid::string::policy_signature,
|
||||||
false /* rewrite */));
|
false /* rewrite */));
|
||||||
@@ -298,8 +302,9 @@ TEST(ResourceMappingTests, ResourcesFromApkAssetsDefaultPoliciesPublicFail) {
|
|||||||
ASSERT_EQ(resources->GetTargetToOverlayMap().size(), 0U);
|
ASSERT_EQ(resources->GetTargetToOverlayMap().size(), 0U);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Overlays that are pre-installed or are signed with the same signature as the target can overlay
|
// Overlays that are pre-installed or are signed with the same signature as the target or are signed
|
||||||
// packages that have not defined overlayable resources.
|
// with the same signature as the reference package can overlay packages that have not defined
|
||||||
|
// overlayable resources.
|
||||||
TEST(ResourceMappingTests, ResourcesFromApkAssetsDefaultPolicies) {
|
TEST(ResourceMappingTests, ResourcesFromApkAssetsDefaultPolicies) {
|
||||||
auto CheckEntries = [&](const PolicyBitmask& fulfilled_policies) -> void {
|
auto CheckEntries = [&](const PolicyBitmask& fulfilled_policies) -> void {
|
||||||
auto resources = TestGetResourceMapping("/target/target-no-overlayable.apk",
|
auto resources = TestGetResourceMapping("/target/target-no-overlayable.apk",
|
||||||
@@ -309,7 +314,7 @@ TEST(ResourceMappingTests, ResourcesFromApkAssetsDefaultPolicies) {
|
|||||||
|
|
||||||
ASSERT_TRUE(resources) << resources.GetErrorMessage();
|
ASSERT_TRUE(resources) << resources.GetErrorMessage();
|
||||||
auto& res = *resources;
|
auto& res = *resources;
|
||||||
ASSERT_EQ(resources->GetTargetToOverlayMap().size(), 10U);
|
ASSERT_EQ(resources->GetTargetToOverlayMap().size(), 11U);
|
||||||
ASSERT_RESULT(MappingExists(res, R::target::string::not_overlayable, Res_value::TYPE_REFERENCE,
|
ASSERT_RESULT(MappingExists(res, R::target::string::not_overlayable, Res_value::TYPE_REFERENCE,
|
||||||
R::system_overlay_invalid::string::not_overlayable,
|
R::system_overlay_invalid::string::not_overlayable,
|
||||||
false /* rewrite */));
|
false /* rewrite */));
|
||||||
@@ -330,6 +335,10 @@ TEST(ResourceMappingTests, ResourcesFromApkAssetsDefaultPolicies) {
|
|||||||
ASSERT_RESULT(MappingExists(res, R::target::string::policy_public, Res_value::TYPE_REFERENCE,
|
ASSERT_RESULT(MappingExists(res, R::target::string::policy_public, Res_value::TYPE_REFERENCE,
|
||||||
R::system_overlay_invalid::string::policy_public,
|
R::system_overlay_invalid::string::policy_public,
|
||||||
false /* rewrite */));
|
false /* rewrite */));
|
||||||
|
ASSERT_RESULT(MappingExists(res, R::target::string::policy_config_signature,
|
||||||
|
Res_value::TYPE_REFERENCE,
|
||||||
|
R::system_overlay_invalid::string::policy_config_signature,
|
||||||
|
false /* rewrite */));
|
||||||
ASSERT_RESULT(MappingExists(res, R::target::string::policy_signature, Res_value::TYPE_REFERENCE,
|
ASSERT_RESULT(MappingExists(res, R::target::string::policy_signature, Res_value::TYPE_REFERENCE,
|
||||||
R::system_overlay_invalid::string::policy_signature,
|
R::system_overlay_invalid::string::policy_signature,
|
||||||
false /* rewrite */));
|
false /* rewrite */));
|
||||||
@@ -342,6 +351,7 @@ TEST(ResourceMappingTests, ResourcesFromApkAssetsDefaultPolicies) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
CheckEntries(PolicyFlags::SIGNATURE);
|
CheckEntries(PolicyFlags::SIGNATURE);
|
||||||
|
CheckEntries(PolicyFlags::CONFIG_SIGNATURE);
|
||||||
CheckEntries(PolicyFlags::PRODUCT_PARTITION);
|
CheckEntries(PolicyFlags::PRODUCT_PARTITION);
|
||||||
CheckEntries(PolicyFlags::SYSTEM_PARTITION);
|
CheckEntries(PolicyFlags::SYSTEM_PARTITION);
|
||||||
CheckEntries(PolicyFlags::VENDOR_PARTITION);
|
CheckEntries(PolicyFlags::VENDOR_PARTITION);
|
||||||
|
|||||||
@@ -19,11 +19,11 @@
|
|||||||
|
|
||||||
namespace android::idmap2::TestConstants {
|
namespace android::idmap2::TestConstants {
|
||||||
|
|
||||||
constexpr const auto TARGET_CRC = 0x41c60c8c;
|
constexpr const auto TARGET_CRC = 0x7c2d4719;
|
||||||
constexpr const auto TARGET_CRC_STRING = "41c60c8c";
|
constexpr const auto TARGET_CRC_STRING = "7c2d4719";
|
||||||
|
|
||||||
constexpr const auto OVERLAY_CRC = 0xc054fb26;
|
constexpr const auto OVERLAY_CRC = 0x5afff726;
|
||||||
constexpr const auto OVERLAY_CRC_STRING = "c054fb26";
|
constexpr const auto OVERLAY_CRC_STRING = "5afff726";
|
||||||
|
|
||||||
} // namespace android::idmap2::TestConstants
|
} // namespace android::idmap2::TestConstants
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -26,6 +26,7 @@
|
|||||||
<string name="policy_odm">policy_odm</string>
|
<string name="policy_odm">policy_odm</string>
|
||||||
<string name="policy_oem">policy_oem</string>
|
<string name="policy_oem">policy_oem</string>
|
||||||
<string name="policy_actor">policy_actor</string>
|
<string name="policy_actor">policy_actor</string>
|
||||||
|
<string name="policy_config_signature">policy_config_signature</string>
|
||||||
|
|
||||||
<!-- Requests to overlay a resource that is not declared as overlayable. -->
|
<!-- Requests to overlay a resource that is not declared as overlayable. -->
|
||||||
<string name="not_overlayable">not_overlayable</string>
|
<string name="not_overlayable">not_overlayable</string>
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@@ -45,6 +45,10 @@
|
|||||||
<item type="string" name="policy_actor" />
|
<item type="string" name="policy_actor" />
|
||||||
</policy>
|
</policy>
|
||||||
|
|
||||||
|
<policy type="config_signature">
|
||||||
|
<item type="string" name="policy_config_signature"/>
|
||||||
|
</policy>
|
||||||
|
|
||||||
<!-- Resources publicly overlayable -->
|
<!-- Resources publicly overlayable -->
|
||||||
<policy type="public">
|
<policy type="public">
|
||||||
<item type="string" name="policy_public" />
|
<item type="string" name="policy_public" />
|
||||||
|
|||||||
@@ -37,6 +37,7 @@
|
|||||||
<string name="policy_system">policy_system</string>
|
<string name="policy_system">policy_system</string>
|
||||||
<string name="policy_system_vendor">policy_system_vendor</string>
|
<string name="policy_system_vendor">policy_system_vendor</string>
|
||||||
<string name="policy_actor">policy_actor</string>
|
<string name="policy_actor">policy_actor</string>
|
||||||
|
<string name="policy_config_signature">policy_config_signature</string>
|
||||||
|
|
||||||
<string name="other">other</string>
|
<string name="other">other</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@@ -19,6 +19,7 @@ package com.android.server;
|
|||||||
import static com.android.internal.util.ArrayUtils.appendInt;
|
import static com.android.internal.util.ArrayUtils.appendInt;
|
||||||
|
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
|
import android.annotation.Nullable;
|
||||||
import android.app.ActivityManager;
|
import android.app.ActivityManager;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.content.pm.FeatureInfo;
|
import android.content.pm.FeatureInfo;
|
||||||
@@ -238,6 +239,14 @@ public class SystemConfig {
|
|||||||
*/
|
*/
|
||||||
private Map<String, Map<String, String>> mNamedActors = null;
|
private Map<String, Map<String, String>> mNamedActors = null;
|
||||||
|
|
||||||
|
// Package name of the package pre-installed on a read-only
|
||||||
|
// partition that is used to verify if an overlay package fulfills
|
||||||
|
// the 'config_signature' policy by comparing their signatures:
|
||||||
|
// if the overlay package is signed with the same certificate as
|
||||||
|
// the package declared in 'config-signature' tag, then the
|
||||||
|
// overlay package fulfills the 'config_signature' policy.
|
||||||
|
private String mOverlayConfigSignaturePackage;
|
||||||
|
|
||||||
public static SystemConfig getInstance() {
|
public static SystemConfig getInstance() {
|
||||||
if (!isSystemProcess()) {
|
if (!isSystemProcess()) {
|
||||||
Slog.wtf(TAG, "SystemConfig is being accessed by a process other than "
|
Slog.wtf(TAG, "SystemConfig is being accessed by a process other than "
|
||||||
@@ -433,6 +442,12 @@ public class SystemConfig {
|
|||||||
return mNamedActors != null ? mNamedActors : Collections.emptyMap();
|
return mNamedActors != null ? mNamedActors : Collections.emptyMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public String getOverlayConfigSignaturePackage() {
|
||||||
|
return TextUtils.isEmpty(mOverlayConfigSignaturePackage)
|
||||||
|
? null : mOverlayConfigSignaturePackage;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Only use for testing. Do NOT use in production code.
|
* Only use for testing. Do NOT use in production code.
|
||||||
* @param readPermissions false to create an empty SystemConfig; true to read the permissions.
|
* @param readPermissions false to create an empty SystemConfig; true to read the permissions.
|
||||||
@@ -1151,6 +1166,27 @@ public class SystemConfig {
|
|||||||
}
|
}
|
||||||
XmlUtils.skipCurrentTag(parser);
|
XmlUtils.skipCurrentTag(parser);
|
||||||
} break;
|
} break;
|
||||||
|
case "overlay-config-signature": {
|
||||||
|
if (allowAll) {
|
||||||
|
String pkgName = parser.getAttributeValue(null, "package");
|
||||||
|
if (pkgName == null) {
|
||||||
|
Slog.w(TAG, "<" + name + "> without package in " + permFile
|
||||||
|
+ " at " + parser.getPositionDescription());
|
||||||
|
} else {
|
||||||
|
if (TextUtils.isEmpty(mOverlayConfigSignaturePackage)) {
|
||||||
|
mOverlayConfigSignaturePackage = pkgName.intern();
|
||||||
|
} else {
|
||||||
|
throw new IllegalStateException("Reference signature package "
|
||||||
|
+ "defined as both "
|
||||||
|
+ mOverlayConfigSignaturePackage
|
||||||
|
+ " and " + pkgName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logNotAllowedInPartition(name, permFile, parser);
|
||||||
|
}
|
||||||
|
XmlUtils.skipCurrentTag(parser);
|
||||||
|
} break;
|
||||||
case "rollback-whitelisted-app": {
|
case "rollback-whitelisted-app": {
|
||||||
String pkgname = parser.getAttributeValue(null, "package");
|
String pkgname = parser.getAttributeValue(null, "package");
|
||||||
if (pkgname == null) {
|
if (pkgname == null) {
|
||||||
|
|||||||
@@ -1717,6 +1717,10 @@ struct ResTable_overlayable_policy_header
|
|||||||
// The overlay must be signed with the same signature as the actor declared for the target
|
// The overlay must be signed with the same signature as the actor declared for the target
|
||||||
// resource
|
// resource
|
||||||
ACTOR_SIGNATURE = 0x00000080,
|
ACTOR_SIGNATURE = 0x00000080,
|
||||||
|
|
||||||
|
// The overlay must be signed with the same signature as the reference package declared
|
||||||
|
// in the SystemConfig
|
||||||
|
CONFIG_SIGNATURE = 0x00000100,
|
||||||
};
|
};
|
||||||
|
|
||||||
using PolicyBitmask = uint32_t;
|
using PolicyBitmask = uint32_t;
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ public abstract class PackageManagerInternal {
|
|||||||
public static final int PACKAGE_WIFI = 13;
|
public static final int PACKAGE_WIFI = 13;
|
||||||
public static final int PACKAGE_COMPANION = 14;
|
public static final int PACKAGE_COMPANION = 14;
|
||||||
public static final int PACKAGE_RETAIL_DEMO = 15;
|
public static final int PACKAGE_RETAIL_DEMO = 15;
|
||||||
|
public static final int PACKAGE_OVERLAY_CONFIG_SIGNATURE = 16;
|
||||||
|
|
||||||
@IntDef(flag = true, prefix = "RESOLVE_", value = {
|
@IntDef(flag = true, prefix = "RESOLVE_", value = {
|
||||||
RESOLVE_NON_BROWSER_ONLY,
|
RESOLVE_NON_BROWSER_ONLY,
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import android.content.pm.PackageInfo;
|
|||||||
import android.os.Build.VERSION_CODES;
|
import android.os.Build.VERSION_CODES;
|
||||||
import android.os.OverlayablePolicy;
|
import android.os.OverlayablePolicy;
|
||||||
import android.os.SystemProperties;
|
import android.os.SystemProperties;
|
||||||
|
import android.text.TextUtils;
|
||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -53,11 +54,20 @@ final class IdmapManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private final IdmapDaemon mIdmapDaemon;
|
private final IdmapDaemon mIdmapDaemon;
|
||||||
private final OverlayableInfoCallback mOverlayableCallback;
|
private final PackageManagerHelper mPackageManager;
|
||||||
|
|
||||||
IdmapManager(final IdmapDaemon idmapDaemon, final OverlayableInfoCallback verifyCallback) {
|
/**
|
||||||
mOverlayableCallback = verifyCallback;
|
* Package name of the reference package defined in 'config-signature' tag of
|
||||||
|
* SystemConfig or empty String if tag not defined. This package is vetted on scan by
|
||||||
|
* PackageManagerService that it's a system package and is used to check if overlay matches
|
||||||
|
* its signature in order to fulfill the config_signature policy.
|
||||||
|
*/
|
||||||
|
private final String mConfigSignaturePackage;
|
||||||
|
|
||||||
|
IdmapManager(final IdmapDaemon idmapDaemon, final PackageManagerHelper packageManager) {
|
||||||
|
mPackageManager = packageManager;
|
||||||
mIdmapDaemon = idmapDaemon;
|
mIdmapDaemon = idmapDaemon;
|
||||||
|
mConfigSignaturePackage = packageManager.getConfigSignaturePackage();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -139,7 +149,7 @@ final class IdmapManager {
|
|||||||
int fulfilledPolicies = OverlayablePolicy.PUBLIC;
|
int fulfilledPolicies = OverlayablePolicy.PUBLIC;
|
||||||
|
|
||||||
// Overlay matches target signature
|
// Overlay matches target signature
|
||||||
if (mOverlayableCallback.signaturesMatching(targetPackage.packageName,
|
if (mPackageManager.signaturesMatching(targetPackage.packageName,
|
||||||
overlayPackage.packageName, userId)) {
|
overlayPackage.packageName, userId)) {
|
||||||
fulfilledPolicies |= OverlayablePolicy.SIGNATURE;
|
fulfilledPolicies |= OverlayablePolicy.SIGNATURE;
|
||||||
}
|
}
|
||||||
@@ -149,6 +159,16 @@ final class IdmapManager {
|
|||||||
fulfilledPolicies |= OverlayablePolicy.ACTOR_SIGNATURE;
|
fulfilledPolicies |= OverlayablePolicy.ACTOR_SIGNATURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If SystemConfig defines 'config-signature' package, given that
|
||||||
|
// this package is vetted by OverlayManagerService that it's a
|
||||||
|
// preinstalled package, check if overlay matches its signature.
|
||||||
|
if (!TextUtils.isEmpty(mConfigSignaturePackage)
|
||||||
|
&& mPackageManager.signaturesMatching(mConfigSignaturePackage,
|
||||||
|
overlayPackage.packageName,
|
||||||
|
userId)) {
|
||||||
|
fulfilledPolicies |= OverlayablePolicy.CONFIG_SIGNATURE;
|
||||||
|
}
|
||||||
|
|
||||||
// Vendor partition (/vendor)
|
// Vendor partition (/vendor)
|
||||||
if (ai.isVendor()) {
|
if (ai.isVendor()) {
|
||||||
return fulfilledPolicies | OverlayablePolicy.VENDOR_PARTITION;
|
return fulfilledPolicies | OverlayablePolicy.VENDOR_PARTITION;
|
||||||
@@ -183,12 +203,12 @@ final class IdmapManager {
|
|||||||
String targetOverlayableName = overlayPackage.targetOverlayableName;
|
String targetOverlayableName = overlayPackage.targetOverlayableName;
|
||||||
if (targetOverlayableName != null) {
|
if (targetOverlayableName != null) {
|
||||||
try {
|
try {
|
||||||
OverlayableInfo overlayableInfo = mOverlayableCallback.getOverlayableForTarget(
|
OverlayableInfo overlayableInfo = mPackageManager.getOverlayableForTarget(
|
||||||
targetPackage.packageName, targetOverlayableName, userId);
|
targetPackage.packageName, targetOverlayableName, userId);
|
||||||
if (overlayableInfo != null && overlayableInfo.actor != null) {
|
if (overlayableInfo != null && overlayableInfo.actor != null) {
|
||||||
String actorPackageName = OverlayActorEnforcer.getPackageNameForActor(
|
String actorPackageName = OverlayActorEnforcer.getPackageNameForActor(
|
||||||
overlayableInfo.actor, mOverlayableCallback.getNamedActors()).first;
|
overlayableInfo.actor, mPackageManager.getNamedActors()).first;
|
||||||
if (mOverlayableCallback.signaturesMatching(actorPackageName,
|
if (mPackageManager.signaturesMatching(actorPackageName,
|
||||||
overlayPackage.packageName, userId)) {
|
overlayPackage.packageName, userId)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ public class OverlayActorEnforcer {
|
|||||||
// By default, the reason is not logged to prevent leaks of why it failed
|
// By default, the reason is not logged to prevent leaks of why it failed
|
||||||
private static final boolean DEBUG_REASON = false;
|
private static final boolean DEBUG_REASON = false;
|
||||||
|
|
||||||
private final OverlayableInfoCallback mOverlayableCallback;
|
private final PackageManagerHelper mPackageManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return nullable actor result with {@link ActorState} failure status
|
* @return nullable actor result with {@link ActorState} failure status
|
||||||
@@ -79,8 +79,8 @@ public class OverlayActorEnforcer {
|
|||||||
return Pair.create(packageName, ActorState.ALLOWED);
|
return Pair.create(packageName, ActorState.ALLOWED);
|
||||||
}
|
}
|
||||||
|
|
||||||
public OverlayActorEnforcer(@NonNull OverlayableInfoCallback overlayableCallback) {
|
public OverlayActorEnforcer(@NonNull PackageManagerHelper packageManager) {
|
||||||
mOverlayableCallback = overlayableCallback;
|
mPackageManager = packageManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
void enforceActor(@NonNull OverlayInfo overlayInfo, @NonNull String methodName,
|
void enforceActor(@NonNull OverlayInfo overlayInfo, @NonNull String methodName,
|
||||||
@@ -110,7 +110,7 @@ public class OverlayActorEnforcer {
|
|||||||
return ActorState.ALLOWED;
|
return ActorState.ALLOWED;
|
||||||
}
|
}
|
||||||
|
|
||||||
String[] callingPackageNames = mOverlayableCallback.getPackagesForUid(callingUid);
|
String[] callingPackageNames = mPackageManager.getPackagesForUid(callingUid);
|
||||||
if (ArrayUtils.isEmpty(callingPackageNames)) {
|
if (ArrayUtils.isEmpty(callingPackageNames)) {
|
||||||
return ActorState.NO_PACKAGES_FOR_UID;
|
return ActorState.NO_PACKAGES_FOR_UID;
|
||||||
}
|
}
|
||||||
@@ -125,12 +125,12 @@ public class OverlayActorEnforcer {
|
|||||||
|
|
||||||
if (TextUtils.isEmpty(targetOverlayableName)) {
|
if (TextUtils.isEmpty(targetOverlayableName)) {
|
||||||
try {
|
try {
|
||||||
if (mOverlayableCallback.doesTargetDefineOverlayable(targetPackageName, userId)) {
|
if (mPackageManager.doesTargetDefineOverlayable(targetPackageName, userId)) {
|
||||||
return ActorState.MISSING_TARGET_OVERLAYABLE_NAME;
|
return ActorState.MISSING_TARGET_OVERLAYABLE_NAME;
|
||||||
} else {
|
} else {
|
||||||
// If there's no overlayable defined, fallback to the legacy permission check
|
// If there's no overlayable defined, fallback to the legacy permission check
|
||||||
try {
|
try {
|
||||||
mOverlayableCallback.enforcePermission(
|
mPackageManager.enforcePermission(
|
||||||
android.Manifest.permission.CHANGE_OVERLAY_PACKAGES, methodName);
|
android.Manifest.permission.CHANGE_OVERLAY_PACKAGES, methodName);
|
||||||
|
|
||||||
// If the previous method didn't throw, check passed
|
// If the previous method didn't throw, check passed
|
||||||
@@ -146,7 +146,7 @@ public class OverlayActorEnforcer {
|
|||||||
|
|
||||||
OverlayableInfo targetOverlayable;
|
OverlayableInfo targetOverlayable;
|
||||||
try {
|
try {
|
||||||
targetOverlayable = mOverlayableCallback.getOverlayableForTarget(targetPackageName,
|
targetOverlayable = mPackageManager.getOverlayableForTarget(targetPackageName,
|
||||||
targetOverlayableName, userId);
|
targetOverlayableName, userId);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
return ActorState.UNABLE_TO_GET_TARGET;
|
return ActorState.UNABLE_TO_GET_TARGET;
|
||||||
@@ -160,7 +160,7 @@ public class OverlayActorEnforcer {
|
|||||||
if (TextUtils.isEmpty(actor)) {
|
if (TextUtils.isEmpty(actor)) {
|
||||||
// If there's no actor defined, fallback to the legacy permission check
|
// If there's no actor defined, fallback to the legacy permission check
|
||||||
try {
|
try {
|
||||||
mOverlayableCallback.enforcePermission(
|
mPackageManager.enforcePermission(
|
||||||
android.Manifest.permission.CHANGE_OVERLAY_PACKAGES, methodName);
|
android.Manifest.permission.CHANGE_OVERLAY_PACKAGES, methodName);
|
||||||
|
|
||||||
// If the previous method didn't throw, check passed
|
// If the previous method didn't throw, check passed
|
||||||
@@ -170,7 +170,7 @@ public class OverlayActorEnforcer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, Map<String, String>> namedActors = mOverlayableCallback.getNamedActors();
|
Map<String, Map<String, String>> namedActors = mPackageManager.getNamedActors();
|
||||||
Pair<String, ActorState> actorUriPair = getPackageNameForActor(actor, namedActors);
|
Pair<String, ActorState> actorUriPair = getPackageNameForActor(actor, namedActors);
|
||||||
ActorState actorUriState = actorUriPair.second;
|
ActorState actorUriState = actorUriPair.second;
|
||||||
if (actorUriState != ActorState.ALLOWED) {
|
if (actorUriState != ActorState.ALLOWED) {
|
||||||
@@ -178,7 +178,7 @@ public class OverlayActorEnforcer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String packageName = actorUriPair.first;
|
String packageName = actorUriPair.first;
|
||||||
PackageInfo packageInfo = mOverlayableCallback.getPackageInfo(packageName, userId);
|
PackageInfo packageInfo = mPackageManager.getPackageInfo(packageName, userId);
|
||||||
if (packageInfo == null) {
|
if (packageInfo == null) {
|
||||||
return ActorState.MISSING_APP_INFO;
|
return ActorState.MISSING_APP_INFO;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1053,8 +1053,7 @@ public final class OverlayManagerService extends SystemService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final class PackageManagerHelperImpl implements PackageManagerHelper,
|
private static final class PackageManagerHelperImpl implements PackageManagerHelper {
|
||||||
OverlayableInfoCallback {
|
|
||||||
|
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
private final IPackageManager mPackageManager;
|
private final IPackageManager mPackageManager;
|
||||||
@@ -1127,6 +1126,14 @@ public final class OverlayManagerService extends SystemService {
|
|||||||
return overlays;
|
return overlays;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getConfigSignaturePackage() {
|
||||||
|
final String[] pkgs = mPackageManagerInternal.getKnownPackageNames(
|
||||||
|
PackageManagerInternal.PACKAGE_OVERLAY_CONFIG_SIGNATURE,
|
||||||
|
UserHandle.USER_SYSTEM);
|
||||||
|
return (pkgs.length == 0) ? null : pkgs[0];
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public OverlayableInfo getOverlayableForTarget(@NonNull String packageName,
|
public OverlayableInfo getOverlayableForTarget(@NonNull String packageName,
|
||||||
|
|||||||
@@ -1,83 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.android.server.om;
|
|
||||||
|
|
||||||
|
|
||||||
import android.annotation.NonNull;
|
|
||||||
import android.annotation.Nullable;
|
|
||||||
import android.content.om.OverlayableInfo;
|
|
||||||
import android.content.pm.PackageInfo;
|
|
||||||
import android.content.pm.PackageManager;
|
|
||||||
|
|
||||||
import com.android.server.pm.PackageManagerServiceUtils;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delegate to the system for querying information about overlayables and packages.
|
|
||||||
*/
|
|
||||||
public interface OverlayableInfoCallback {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Read from the APK and AndroidManifest of a package to return the overlayable defined for
|
|
||||||
* a given name.
|
|
||||||
*
|
|
||||||
* @throws IOException if the target can't be read
|
|
||||||
*/
|
|
||||||
@Nullable
|
|
||||||
OverlayableInfo getOverlayableForTarget(@NonNull String packageName,
|
|
||||||
@NonNull String targetOverlayableName, int userId)
|
|
||||||
throws IOException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see PackageManager#getPackagesForUid(int)
|
|
||||||
*/
|
|
||||||
@Nullable
|
|
||||||
String[] getPackagesForUid(int uid);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param userId user to filter package visibility by
|
|
||||||
* @see PackageManager#getPackageInfo(String, int)
|
|
||||||
*/
|
|
||||||
@Nullable
|
|
||||||
PackageInfo getPackageInfo(@NonNull String packageName, int userId);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return map of system pre-defined, uniquely named actors; keys are namespace,
|
|
||||||
* value maps actor name to package name
|
|
||||||
*/
|
|
||||||
@NonNull
|
|
||||||
Map<String, Map<String, String>> getNamedActors();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return true if the target package has declared an overlayable
|
|
||||||
*/
|
|
||||||
boolean doesTargetDefineOverlayable(String targetPackageName, int userId) throws IOException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @throws SecurityException containing message if the caller doesn't have the given
|
|
||||||
* permission
|
|
||||||
*/
|
|
||||||
void enforcePermission(String permission, String message) throws SecurityException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return true if {@link PackageManagerServiceUtils#compareSignatures} run on both packages
|
|
||||||
* in the system returns {@link PackageManager#SIGNATURE_MATCH}
|
|
||||||
*/
|
|
||||||
boolean signaturesMatching(@NonNull String pkgName1, @NonNull String pkgName2, int userId);
|
|
||||||
}
|
|
||||||
@@ -17,11 +17,17 @@
|
|||||||
package com.android.server.om;
|
package com.android.server.om;
|
||||||
|
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
|
import android.annotation.Nullable;
|
||||||
|
import android.content.om.OverlayableInfo;
|
||||||
import android.content.pm.PackageInfo;
|
import android.content.pm.PackageInfo;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.pm.PackageManagerInternal;
|
import android.content.pm.PackageManagerInternal;
|
||||||
|
|
||||||
|
import com.android.server.pm.PackageManagerServiceUtils;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delegate for {@link PackageManager} and {@link PackageManagerInternal} functionality,
|
* Delegate for {@link PackageManager} and {@link PackageManagerInternal} functionality,
|
||||||
@@ -30,7 +36,65 @@ import java.util.List;
|
|||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
interface PackageManagerHelper {
|
interface PackageManagerHelper {
|
||||||
PackageInfo getPackageInfo(@NonNull String packageName, int userId);
|
/**
|
||||||
boolean signaturesMatching(@NonNull String pkgName1, @NonNull String pkgName2, int userId);
|
* @return true if the target package has declared an overlayable
|
||||||
|
*/
|
||||||
|
boolean doesTargetDefineOverlayable(String targetPackageName, int userId) throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws SecurityException containing message if the caller doesn't have the given
|
||||||
|
* permission
|
||||||
|
*/
|
||||||
|
void enforcePermission(String permission, String message) throws SecurityException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the package name of the reference package defined in 'overlay-config-signature' tag
|
||||||
|
* of SystemConfig. This package is vetted on scan by PackageManagerService that it's a system
|
||||||
|
* package and is used to check if overlay matches its signature in order to fulfill the
|
||||||
|
* config_signature policy.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
String getConfigSignaturePackage();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return map of system pre-defined, uniquely named actors; keys are namespace,
|
||||||
|
* value maps actor name to package name
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
Map<String, Map<String, String>> getNamedActors();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see PackageManagerInternal#getOverlayPackages(int)
|
||||||
|
*/
|
||||||
List<PackageInfo> getOverlayPackages(int userId);
|
List<PackageInfo> getOverlayPackages(int userId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read from the APK and AndroidManifest of a package to return the overlayable defined for
|
||||||
|
* a given name.
|
||||||
|
*
|
||||||
|
* @throws IOException if the target can't be read
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
OverlayableInfo getOverlayableForTarget(@NonNull String packageName,
|
||||||
|
@NonNull String targetOverlayableName, int userId)
|
||||||
|
throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see PackageManager#getPackagesForUid(int)
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
String[] getPackagesForUid(int uid);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param userId user to filter package visibility by
|
||||||
|
* @see PackageManager#getPackageInfo(String, int)
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
PackageInfo getPackageInfo(@NonNull String packageName, int userId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if {@link PackageManagerServiceUtils#compareSignatures} run on both packages
|
||||||
|
* in the system returns {@link PackageManager#SIGNATURE_MATCH}
|
||||||
|
*/
|
||||||
|
boolean signaturesMatching(@NonNull String pkgName1, @NonNull String pkgName2, int userId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -120,6 +120,7 @@ import static com.android.server.pm.InstructionSets.getDexCodeInstructionSet;
|
|||||||
import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets;
|
import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets;
|
||||||
import static com.android.server.pm.InstructionSets.getPreferredInstructionSet;
|
import static com.android.server.pm.InstructionSets.getPreferredInstructionSet;
|
||||||
import static com.android.server.pm.PackageManagerServiceCompilerMapping.getDefaultCompilerFilter;
|
import static com.android.server.pm.PackageManagerServiceCompilerMapping.getDefaultCompilerFilter;
|
||||||
|
import static com.android.server.pm.PackageManagerServiceUtils.comparePackageSignatures;
|
||||||
import static com.android.server.pm.PackageManagerServiceUtils.compareSignatures;
|
import static com.android.server.pm.PackageManagerServiceUtils.compareSignatures;
|
||||||
import static com.android.server.pm.PackageManagerServiceUtils.compressedFileExists;
|
import static com.android.server.pm.PackageManagerServiceUtils.compressedFileExists;
|
||||||
import static com.android.server.pm.PackageManagerServiceUtils.decompressFile;
|
import static com.android.server.pm.PackageManagerServiceUtils.decompressFile;
|
||||||
@@ -1114,6 +1115,7 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
public @Nullable String storageManagerPackage;
|
public @Nullable String storageManagerPackage;
|
||||||
public @Nullable String defaultTextClassifierPackage;
|
public @Nullable String defaultTextClassifierPackage;
|
||||||
public @Nullable String systemTextClassifierPackage;
|
public @Nullable String systemTextClassifierPackage;
|
||||||
|
public @Nullable String overlayConfigSignaturePackage;
|
||||||
public ViewCompiler viewCompiler;
|
public ViewCompiler viewCompiler;
|
||||||
public @Nullable String wellbeingPackage;
|
public @Nullable String wellbeingPackage;
|
||||||
public @Nullable String retailDemoPackage;
|
public @Nullable String retailDemoPackage;
|
||||||
@@ -1646,6 +1648,7 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
final @Nullable String mServicesExtensionPackageName;
|
final @Nullable String mServicesExtensionPackageName;
|
||||||
final @Nullable String mSharedSystemSharedLibraryPackageName;
|
final @Nullable String mSharedSystemSharedLibraryPackageName;
|
||||||
final @Nullable String mRetailDemoPackage;
|
final @Nullable String mRetailDemoPackage;
|
||||||
|
final @Nullable String mOverlayConfigSignaturePackage;
|
||||||
|
|
||||||
private final PackageUsage mPackageUsage = new PackageUsage();
|
private final PackageUsage mPackageUsage = new PackageUsage();
|
||||||
private final CompilerStats mCompilerStats = new CompilerStats();
|
private final CompilerStats mCompilerStats = new CompilerStats();
|
||||||
@@ -2808,6 +2811,7 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
mIncidentReportApproverPackage = testParams.incidentReportApproverPackage;
|
mIncidentReportApproverPackage = testParams.incidentReportApproverPackage;
|
||||||
mServicesExtensionPackageName = testParams.servicesExtensionPackageName;
|
mServicesExtensionPackageName = testParams.servicesExtensionPackageName;
|
||||||
mSharedSystemSharedLibraryPackageName = testParams.sharedSystemSharedLibraryPackageName;
|
mSharedSystemSharedLibraryPackageName = testParams.sharedSystemSharedLibraryPackageName;
|
||||||
|
mOverlayConfigSignaturePackage = testParams.overlayConfigSignaturePackage;
|
||||||
|
|
||||||
mResolveComponentName = testParams.resolveComponentName;
|
mResolveComponentName = testParams.resolveComponentName;
|
||||||
mPackages.putAll(testParams.packages);
|
mPackages.putAll(testParams.packages);
|
||||||
@@ -3373,6 +3377,7 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
mAppPredictionServicePackage = getAppPredictionServicePackageName();
|
mAppPredictionServicePackage = getAppPredictionServicePackageName();
|
||||||
mIncidentReportApproverPackage = getIncidentReportApproverPackageName();
|
mIncidentReportApproverPackage = getIncidentReportApproverPackageName();
|
||||||
mRetailDemoPackage = getRetailDemoPackageName();
|
mRetailDemoPackage = getRetailDemoPackageName();
|
||||||
|
mOverlayConfigSignaturePackage = getOverlayConfigSignaturePackageName();
|
||||||
|
|
||||||
// Now that we know all of the shared libraries, update all clients to have
|
// Now that we know all of the shared libraries, update all clients to have
|
||||||
// the correct library paths.
|
// the correct library paths.
|
||||||
@@ -12100,12 +12105,8 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
if (sharedUserSetting != null && sharedUserSetting.isPrivileged()) {
|
if (sharedUserSetting != null && sharedUserSetting.isPrivileged()) {
|
||||||
// Exempt SharedUsers signed with the platform key.
|
// Exempt SharedUsers signed with the platform key.
|
||||||
PackageSetting platformPkgSetting = mSettings.mPackages.get("android");
|
PackageSetting platformPkgSetting = mSettings.mPackages.get("android");
|
||||||
if ((platformPkgSetting.signatures.mSigningDetails
|
if (!comparePackageSignatures(platformPkgSetting,
|
||||||
!= PackageParser.SigningDetails.UNKNOWN)
|
pkg.getSigningDetails().signatures)) {
|
||||||
&& (compareSignatures(
|
|
||||||
platformPkgSetting.signatures.mSigningDetails.signatures,
|
|
||||||
pkg.getSigningDetails().signatures)
|
|
||||||
!= PackageManager.SIGNATURE_MATCH)) {
|
|
||||||
throw new PackageManagerException("Apps that share a user with a " +
|
throw new PackageManagerException("Apps that share a user with a " +
|
||||||
"privileged app must themselves be marked as privileged. " +
|
"privileged app must themselves be marked as privileged. " +
|
||||||
pkg.getPackageName() + " shares privileged user " +
|
pkg.getPackageName() + " shares privileged user " +
|
||||||
@@ -12152,12 +12153,8 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.Q) {
|
if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.Q) {
|
||||||
final PackageSetting platformPkgSetting =
|
final PackageSetting platformPkgSetting =
|
||||||
mSettings.getPackageLPr("android");
|
mSettings.getPackageLPr("android");
|
||||||
if ((platformPkgSetting.signatures.mSigningDetails
|
if (!comparePackageSignatures(platformPkgSetting,
|
||||||
!= PackageParser.SigningDetails.UNKNOWN)
|
pkg.getSigningDetails().signatures)) {
|
||||||
&& (compareSignatures(
|
|
||||||
platformPkgSetting.signatures.mSigningDetails.signatures,
|
|
||||||
pkg.getSigningDetails().signatures)
|
|
||||||
!= PackageManager.SIGNATURE_MATCH)) {
|
|
||||||
throw new PackageManagerException("Overlay "
|
throw new PackageManagerException("Overlay "
|
||||||
+ pkg.getPackageName()
|
+ pkg.getPackageName()
|
||||||
+ " must target Q or later, "
|
+ " must target Q or later, "
|
||||||
@@ -12166,24 +12163,35 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
}
|
}
|
||||||
|
|
||||||
// A non-preloaded overlay package, without <overlay android:targetName>, will
|
// A non-preloaded overlay package, without <overlay android:targetName>, will
|
||||||
// only be used if it is signed with the same certificate as its target. If the
|
// only be used if it is signed with the same certificate as its target OR if
|
||||||
// target is already installed, check this here to augment the last line of
|
// it is signed with the same certificate as a reference package declared
|
||||||
// defence which is OMS.
|
// in 'config-signature' tag of SystemConfig.
|
||||||
|
// If the target is already installed or 'config-signature' tag in SystemConfig
|
||||||
|
// is set, check this here to augment the last line of defence which is OMS.
|
||||||
if (pkg.getOverlayTargetName() == null) {
|
if (pkg.getOverlayTargetName() == null) {
|
||||||
final PackageSetting targetPkgSetting =
|
final PackageSetting targetPkgSetting =
|
||||||
mSettings.getPackageLPr(pkg.getOverlayTarget());
|
mSettings.getPackageLPr(pkg.getOverlayTarget());
|
||||||
if (targetPkgSetting != null) {
|
if (targetPkgSetting != null) {
|
||||||
if ((targetPkgSetting.signatures.mSigningDetails
|
if (!comparePackageSignatures(targetPkgSetting,
|
||||||
!= PackageParser.SigningDetails.UNKNOWN)
|
pkg.getSigningDetails().signatures)) {
|
||||||
&& (compareSignatures(
|
// check reference signature
|
||||||
targetPkgSetting.signatures.mSigningDetails.signatures,
|
if (mOverlayConfigSignaturePackage == null) {
|
||||||
pkg.getSigningDetails().signatures)
|
throw new PackageManagerException("Overlay "
|
||||||
!= PackageManager.SIGNATURE_MATCH)) {
|
+ pkg.getPackageName() + " and target "
|
||||||
throw new PackageManagerException("Overlay "
|
+ pkg.getOverlayTarget() + " signed with"
|
||||||
+ pkg.getPackageName() + " and target "
|
+ " different certificates, and the overlay lacks"
|
||||||
+ pkg.getOverlayTarget() + " signed with"
|
+ " <overlay android:targetName>");
|
||||||
+ " different certificates, and the overlay lacks"
|
}
|
||||||
+ " <overlay android:targetName>");
|
final PackageSetting refPkgSetting =
|
||||||
|
mSettings.getPackageLPr(mOverlayConfigSignaturePackage);
|
||||||
|
if (!comparePackageSignatures(refPkgSetting,
|
||||||
|
pkg.getSigningDetails().signatures)) {
|
||||||
|
throw new PackageManagerException("Overlay "
|
||||||
|
+ pkg.getPackageName() + " signed with a different "
|
||||||
|
+ "certificate than both the reference package and "
|
||||||
|
+ "target " + pkg.getOverlayTarget() + ", and the "
|
||||||
|
+ "overlay lacks <overlay android:targetName>");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -20716,6 +20724,11 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
return ensureSystemPackageName(contentCaptureServiceComponentName.getPackageName());
|
return ensureSystemPackageName(contentCaptureServiceComponentName.getPackageName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getOverlayConfigSignaturePackageName() {
|
||||||
|
return ensureSystemPackageName(SystemConfig.getInstance()
|
||||||
|
.getOverlayConfigSignaturePackage());
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private String getRetailDemoPackageName() {
|
private String getRetailDemoPackageName() {
|
||||||
final String predefinedPkgName = mContext.getString(R.string.config_retailDemoPackage);
|
final String predefinedPkgName = mContext.getString(R.string.config_retailDemoPackage);
|
||||||
@@ -24232,6 +24245,8 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
return TextUtils.isEmpty(mRetailDemoPackage)
|
return TextUtils.isEmpty(mRetailDemoPackage)
|
||||||
? ArrayUtils.emptyArray(String.class)
|
? ArrayUtils.emptyArray(String.class)
|
||||||
: new String[] {mRetailDemoPackage};
|
: new String[] {mRetailDemoPackage};
|
||||||
|
case PackageManagerInternal.PACKAGE_OVERLAY_CONFIG_SIGNATURE:
|
||||||
|
return filterOnlySystemPackages(getOverlayConfigSignaturePackageName());
|
||||||
default:
|
default:
|
||||||
return ArrayUtils.emptyArray(String.class);
|
return ArrayUtils.emptyArray(String.class);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -487,6 +487,18 @@ public class PackageManagerServiceUtils {
|
|||||||
return PackageManager.SIGNATURE_NO_MATCH;
|
return PackageManager.SIGNATURE_NO_MATCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the signature set of the package is identical to the specified signature
|
||||||
|
* set or if the signing details of the package are unknown.
|
||||||
|
*/
|
||||||
|
public static boolean comparePackageSignatures(PackageSetting pkgSetting,
|
||||||
|
Signature[] signatures) {
|
||||||
|
return pkgSetting.signatures.mSigningDetails
|
||||||
|
== PackageParser.SigningDetails.UNKNOWN
|
||||||
|
|| compareSignatures(pkgSetting.signatures.mSigningDetails.signatures, signatures)
|
||||||
|
== PackageManager.SIGNATURE_MATCH;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used for backward compatibility to make sure any packages with
|
* Used for backward compatibility to make sure any packages with
|
||||||
* certificate chains get upgraded to the new style. {@code existingSigs}
|
* certificate chains get upgraded to the new style. {@code existingSigs}
|
||||||
|
|||||||
@@ -160,7 +160,7 @@ class OverlayActorEnforcerTests {
|
|||||||
private val hasPermission: Boolean = false,
|
private val hasPermission: Boolean = false,
|
||||||
private val overlayableInfo: OverlayableInfo? = null,
|
private val overlayableInfo: OverlayableInfo? = null,
|
||||||
private vararg val packageNames: String = arrayOf("com.test.actor.one")
|
private vararg val packageNames: String = arrayOf("com.test.actor.one")
|
||||||
) : OverlayableInfoCallback {
|
) : PackageManagerHelper {
|
||||||
|
|
||||||
override fun getNamedActors() = if (isActor) {
|
override fun getNamedActors() = if (isActor) {
|
||||||
mapOf(NAMESPACE to mapOf(ACTOR_NAME to ACTOR_PKG_NAME))
|
mapOf(NAMESPACE to mapOf(ACTOR_NAME to ACTOR_PKG_NAME))
|
||||||
@@ -195,6 +195,14 @@ class OverlayActorEnforcerTests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun getConfigSignaturePackage(): String {
|
||||||
|
throw UnsupportedOperationException()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getOverlayPackages(userId: Int): MutableList<PackageInfo> {
|
||||||
|
throw UnsupportedOperationException()
|
||||||
|
}
|
||||||
|
|
||||||
override fun signaturesMatching(pkgName1: String, pkgName2: String, userId: Int): Boolean {
|
override fun signaturesMatching(pkgName1: String, pkgName2: String, userId: Int): Boolean {
|
||||||
throw UnsupportedOperationException()
|
throw UnsupportedOperationException()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,9 +44,9 @@ public class OverlayManagerServiceImplRebootTests extends OverlayManagerServiceI
|
|||||||
@Test
|
@Test
|
||||||
public void testUpdateOverlaysForUser() {
|
public void testUpdateOverlaysForUser() {
|
||||||
final OverlayManagerServiceImpl impl = getImpl();
|
final OverlayManagerServiceImpl impl = getImpl();
|
||||||
addSystemPackage(target(TARGET), USER);
|
addPackage(target(TARGET), USER);
|
||||||
addSystemPackage(target("some.other.target"), USER);;
|
addPackage(target("some.other.target"), USER);
|
||||||
addSystemPackage(overlay(OVERLAY, TARGET), USER);
|
addPackage(overlay(OVERLAY, TARGET), USER);
|
||||||
|
|
||||||
// do nothing, expect no change
|
// do nothing, expect no change
|
||||||
final List<String> a = impl.updateOverlaysForUser(USER);
|
final List<String> a = impl.updateOverlaysForUser(USER);
|
||||||
@@ -54,7 +54,7 @@ public class OverlayManagerServiceImplRebootTests extends OverlayManagerServiceI
|
|||||||
assertTrue(a.contains(TARGET));
|
assertTrue(a.contains(TARGET));
|
||||||
|
|
||||||
// upgrade overlay, keep target
|
// upgrade overlay, keep target
|
||||||
addSystemPackage(overlay(OVERLAY, TARGET), USER);
|
addPackage(overlay(OVERLAY, TARGET), USER);
|
||||||
|
|
||||||
final List<String> b = impl.updateOverlaysForUser(USER);
|
final List<String> b = impl.updateOverlaysForUser(USER);
|
||||||
assertEquals(1, b.size());
|
assertEquals(1, b.size());
|
||||||
@@ -66,7 +66,7 @@ public class OverlayManagerServiceImplRebootTests extends OverlayManagerServiceI
|
|||||||
assertTrue(c.contains(TARGET));
|
assertTrue(c.contains(TARGET));
|
||||||
|
|
||||||
// upgrade overlay, switch to new target
|
// upgrade overlay, switch to new target
|
||||||
addSystemPackage(overlay(OVERLAY, "some.other.target"), USER);
|
addPackage(overlay(OVERLAY, "some.other.target"), USER);
|
||||||
final List<String> d = impl.updateOverlaysForUser(USER);
|
final List<String> d = impl.updateOverlaysForUser(USER);
|
||||||
assertEquals(2, d.size());
|
assertEquals(2, d.size());
|
||||||
assertTrue(d.containsAll(Arrays.asList(TARGET, "some.other.target")));
|
assertTrue(d.containsAll(Arrays.asList(TARGET, "some.other.target")));
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ package com.android.server.om;
|
|||||||
import static android.content.om.OverlayInfo.STATE_DISABLED;
|
import static android.content.om.OverlayInfo.STATE_DISABLED;
|
||||||
import static android.content.om.OverlayInfo.STATE_ENABLED;
|
import static android.content.om.OverlayInfo.STATE_ENABLED;
|
||||||
import static android.content.om.OverlayInfo.STATE_MISSING_TARGET;
|
import static android.content.om.OverlayInfo.STATE_MISSING_TARGET;
|
||||||
|
import static android.os.OverlayablePolicy.CONFIG_SIGNATURE;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
@@ -49,6 +50,10 @@ public class OverlayManagerServiceImplTests extends OverlayManagerServiceImplTes
|
|||||||
private static final String OVERLAY3 = OVERLAY + "3";
|
private static final String OVERLAY3 = OVERLAY + "3";
|
||||||
private static final int USER3 = USER2 + 1;
|
private static final int USER3 = USER2 + 1;
|
||||||
|
|
||||||
|
private static final String CONFIG_SIGNATURE_REFERENCE_PKG = "com.dummy.ref";
|
||||||
|
private static final String CERT_CONFIG_OK = "config_certificate_ok";
|
||||||
|
private static final String CERT_CONFIG_NOK = "config_certificate_nok";
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetOverlayInfo() {
|
public void testGetOverlayInfo() {
|
||||||
installNewPackage(overlay(OVERLAY, TARGET), USER);
|
installNewPackage(overlay(OVERLAY, TARGET), USER);
|
||||||
@@ -204,4 +209,87 @@ public class OverlayManagerServiceImplTests extends OverlayManagerServiceImplTes
|
|||||||
impl.setEnabled(OVERLAY, true, USER);
|
impl.setEnabled(OVERLAY, true, USER);
|
||||||
assertEquals(0, listener.count);
|
assertEquals(0, listener.count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testConfigSignaturePolicyOk() {
|
||||||
|
setConfigSignaturePackageName(CONFIG_SIGNATURE_REFERENCE_PKG);
|
||||||
|
reinitializeImpl();
|
||||||
|
|
||||||
|
addPackage(target(CONFIG_SIGNATURE_REFERENCE_PKG).setCertificate(CERT_CONFIG_OK), USER);
|
||||||
|
installNewPackage(target(TARGET), USER);
|
||||||
|
installNewPackage(overlay(OVERLAY, TARGET).setCertificate(CERT_CONFIG_OK), USER);
|
||||||
|
|
||||||
|
final DummyIdmapDaemon idmapd = getIdmapd();
|
||||||
|
final DummyDeviceState state = getState();
|
||||||
|
String overlayPath = state.select(OVERLAY, USER).apkPath;
|
||||||
|
assertTrue(idmapd.idmapExists(overlayPath, USER));
|
||||||
|
|
||||||
|
DummyIdmapDaemon.IdmapHeader idmap = idmapd.getIdmap(overlayPath);
|
||||||
|
assertTrue((CONFIG_SIGNATURE & idmap.policies) == CONFIG_SIGNATURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testConfigSignaturePolicyCertNok() {
|
||||||
|
setConfigSignaturePackageName(CONFIG_SIGNATURE_REFERENCE_PKG);
|
||||||
|
reinitializeImpl();
|
||||||
|
|
||||||
|
addPackage(target(CONFIG_SIGNATURE_REFERENCE_PKG).setCertificate(CERT_CONFIG_OK), USER);
|
||||||
|
installNewPackage(target(TARGET), USER);
|
||||||
|
installNewPackage(overlay(OVERLAY, TARGET).setCertificate(CERT_CONFIG_NOK), USER);
|
||||||
|
|
||||||
|
final DummyIdmapDaemon idmapd = getIdmapd();
|
||||||
|
final DummyDeviceState state = getState();
|
||||||
|
String overlayPath = state.select(OVERLAY, USER).apkPath;
|
||||||
|
assertTrue(idmapd.idmapExists(overlayPath, USER));
|
||||||
|
|
||||||
|
DummyIdmapDaemon.IdmapHeader idmap = idmapd.getIdmap(overlayPath);
|
||||||
|
assertTrue((CONFIG_SIGNATURE & idmap.policies) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testConfigSignaturePolicyNoConfig() {
|
||||||
|
addPackage(target(CONFIG_SIGNATURE_REFERENCE_PKG).setCertificate(CERT_CONFIG_OK), USER);
|
||||||
|
installNewPackage(target(TARGET), USER);
|
||||||
|
installNewPackage(overlay(OVERLAY, TARGET).setCertificate(CERT_CONFIG_NOK), USER);
|
||||||
|
|
||||||
|
final DummyIdmapDaemon idmapd = getIdmapd();
|
||||||
|
final DummyDeviceState state = getState();
|
||||||
|
String overlayPath = state.select(OVERLAY, USER).apkPath;
|
||||||
|
assertTrue(idmapd.idmapExists(overlayPath, USER));
|
||||||
|
|
||||||
|
DummyIdmapDaemon.IdmapHeader idmap = idmapd.getIdmap(overlayPath);
|
||||||
|
assertTrue((CONFIG_SIGNATURE & idmap.policies) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testConfigSignaturePolicyNoRefPkg() {
|
||||||
|
installNewPackage(target(TARGET), USER);
|
||||||
|
installNewPackage(overlay(OVERLAY, TARGET).setCertificate(CERT_CONFIG_NOK), USER);
|
||||||
|
|
||||||
|
final DummyIdmapDaemon idmapd = getIdmapd();
|
||||||
|
final DummyDeviceState state = getState();
|
||||||
|
String overlayPath = state.select(OVERLAY, USER).apkPath;
|
||||||
|
assertTrue(idmapd.idmapExists(overlayPath, USER));
|
||||||
|
|
||||||
|
DummyIdmapDaemon.IdmapHeader idmap = idmapd.getIdmap(overlayPath);
|
||||||
|
assertTrue((CONFIG_SIGNATURE & idmap.policies) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testConfigSignaturePolicyRefPkgNotSystem() {
|
||||||
|
setConfigSignaturePackageName(CONFIG_SIGNATURE_REFERENCE_PKG);
|
||||||
|
reinitializeImpl();
|
||||||
|
|
||||||
|
addPackage(app(CONFIG_SIGNATURE_REFERENCE_PKG).setCertificate(CERT_CONFIG_OK), USER);
|
||||||
|
installNewPackage(target(TARGET), USER);
|
||||||
|
installNewPackage(overlay(OVERLAY, TARGET).setCertificate(CERT_CONFIG_NOK), USER);
|
||||||
|
|
||||||
|
final DummyIdmapDaemon idmapd = getIdmapd();
|
||||||
|
final DummyDeviceState state = getState();
|
||||||
|
String overlayPath = state.select(OVERLAY, USER).apkPath;
|
||||||
|
assertTrue(idmapd.idmapExists(overlayPath, USER));
|
||||||
|
|
||||||
|
DummyIdmapDaemon.IdmapHeader idmap = idmapd.getIdmap(overlayPath);
|
||||||
|
assertTrue((CONFIG_SIGNATURE & idmap.policies) == 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import android.content.om.OverlayInfo.State;
|
|||||||
import android.content.om.OverlayableInfo;
|
import android.content.om.OverlayableInfo;
|
||||||
import android.content.pm.ApplicationInfo;
|
import android.content.pm.ApplicationInfo;
|
||||||
import android.content.pm.PackageInfo;
|
import android.content.pm.PackageInfo;
|
||||||
|
import android.text.TextUtils;
|
||||||
import android.util.ArrayMap;
|
import android.util.ArrayMap;
|
||||||
import android.util.ArraySet;
|
import android.util.ArraySet;
|
||||||
|
|
||||||
@@ -52,6 +53,7 @@ class OverlayManagerServiceImplTestsBase {
|
|||||||
private DummyPackageManagerHelper mPackageManager;
|
private DummyPackageManagerHelper mPackageManager;
|
||||||
private DummyIdmapDaemon mIdmapDaemon;
|
private DummyIdmapDaemon mIdmapDaemon;
|
||||||
private OverlayConfig mOverlayConfig;
|
private OverlayConfig mOverlayConfig;
|
||||||
|
private String mConfigSignaturePackageName;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
@@ -83,6 +85,18 @@ class OverlayManagerServiceImplTestsBase {
|
|||||||
return mListener;
|
return mListener;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DummyIdmapDaemon getIdmapd() {
|
||||||
|
return mIdmapDaemon;
|
||||||
|
}
|
||||||
|
|
||||||
|
DummyDeviceState getState() {
|
||||||
|
return mState;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setConfigSignaturePackageName(String packageName) {
|
||||||
|
mConfigSignaturePackageName = packageName;
|
||||||
|
}
|
||||||
|
|
||||||
void assertState(@State int expected, final String overlayPackageName, int userId) {
|
void assertState(@State int expected, final String overlayPackageName, int userId) {
|
||||||
final OverlayInfo info = mImpl.getOverlayInfo(overlayPackageName, userId);
|
final OverlayInfo info = mImpl.getOverlayInfo(overlayPackageName, userId);
|
||||||
if (info == null) {
|
if (info == null) {
|
||||||
@@ -102,9 +116,14 @@ class OverlayManagerServiceImplTestsBase {
|
|||||||
assertEquals(expected, actual);
|
assertEquals(expected, actual);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DummyDeviceState.PackageBuilder app(String packageName) {
|
||||||
|
return new DummyDeviceState.PackageBuilder(packageName, null /* targetPackageName */,
|
||||||
|
null /* targetOverlayableName */, "data");
|
||||||
|
}
|
||||||
|
|
||||||
DummyDeviceState.PackageBuilder target(String packageName) {
|
DummyDeviceState.PackageBuilder target(String packageName) {
|
||||||
return new DummyDeviceState.PackageBuilder(packageName, null /* targetPackageName */,
|
return new DummyDeviceState.PackageBuilder(packageName, null /* targetPackageName */,
|
||||||
null /* targetOverlayableName */);
|
null /* targetOverlayableName */, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
DummyDeviceState.PackageBuilder overlay(String packageName, String targetPackageName) {
|
DummyDeviceState.PackageBuilder overlay(String packageName, String targetPackageName) {
|
||||||
@@ -114,10 +133,10 @@ class OverlayManagerServiceImplTestsBase {
|
|||||||
DummyDeviceState.PackageBuilder overlay(String packageName, String targetPackageName,
|
DummyDeviceState.PackageBuilder overlay(String packageName, String targetPackageName,
|
||||||
String targetOverlayableName) {
|
String targetOverlayableName) {
|
||||||
return new DummyDeviceState.PackageBuilder(packageName, targetPackageName,
|
return new DummyDeviceState.PackageBuilder(packageName, targetPackageName,
|
||||||
targetOverlayableName);
|
targetOverlayableName, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
void addSystemPackage(DummyDeviceState.PackageBuilder pkg, int userId) {
|
void addPackage(DummyDeviceState.PackageBuilder pkg, int userId) {
|
||||||
mState.add(pkg, userId);
|
mState.add(pkg, userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -242,15 +261,17 @@ class OverlayManagerServiceImplTestsBase {
|
|||||||
private String packageName;
|
private String packageName;
|
||||||
private String targetPackage;
|
private String targetPackage;
|
||||||
private String certificate = "[default]";
|
private String certificate = "[default]";
|
||||||
|
private String partition;
|
||||||
private int version = 0;
|
private int version = 0;
|
||||||
private ArrayList<String> overlayableNames = new ArrayList<>();
|
private ArrayList<String> overlayableNames = new ArrayList<>();
|
||||||
private String targetOverlayableName;
|
private String targetOverlayableName;
|
||||||
|
|
||||||
private PackageBuilder(String packageName, String targetPackage,
|
private PackageBuilder(String packageName, String targetPackage,
|
||||||
String targetOverlayableName) {
|
String targetOverlayableName, String partition) {
|
||||||
this.packageName = packageName;
|
this.packageName = packageName;
|
||||||
this.targetPackage = targetPackage;
|
this.targetPackage = targetPackage;
|
||||||
this.targetOverlayableName = targetOverlayableName;
|
this.targetOverlayableName = targetOverlayableName;
|
||||||
|
this.partition = partition;
|
||||||
}
|
}
|
||||||
|
|
||||||
PackageBuilder setCertificate(String certificate) {
|
PackageBuilder setCertificate(String certificate) {
|
||||||
@@ -269,9 +290,19 @@ class OverlayManagerServiceImplTestsBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Package build() {
|
Package build() {
|
||||||
final String apkPath = String.format("%s/%s/base.apk",
|
String path = "";
|
||||||
targetPackage == null ? "/system/app/:" : "/vendor/overlay/:",
|
if (TextUtils.isEmpty(partition)) {
|
||||||
packageName);
|
if (targetPackage == null) {
|
||||||
|
path = "/system/app";
|
||||||
|
} else {
|
||||||
|
path = "/vendor/overlay";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
String type = targetPackage == null ? "app" : "overlay";
|
||||||
|
path = String.format("%s/%s", partition, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
final String apkPath = String.format("%s/%s/base.apk", path, packageName);
|
||||||
final Package newPackage = new Package(packageName, targetPackage,
|
final Package newPackage = new Package(packageName, targetPackage,
|
||||||
targetOverlayableName, version, apkPath, certificate);
|
targetOverlayableName, version, apkPath, certificate);
|
||||||
newPackage.overlayableNames.addAll(overlayableNames);
|
newPackage.overlayableNames.addAll(overlayableNames);
|
||||||
@@ -302,8 +333,7 @@ class OverlayManagerServiceImplTestsBase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static final class DummyPackageManagerHelper implements PackageManagerHelper,
|
final class DummyPackageManagerHelper implements PackageManagerHelper {
|
||||||
OverlayableInfoCallback {
|
|
||||||
private final DummyDeviceState mState;
|
private final DummyDeviceState mState;
|
||||||
|
|
||||||
private DummyPackageManagerHelper(DummyDeviceState state) {
|
private DummyPackageManagerHelper(DummyDeviceState state) {
|
||||||
@@ -343,6 +373,11 @@ class OverlayManagerServiceImplTestsBase {
|
|||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NonNull String getConfigSignaturePackage() {
|
||||||
|
return mConfigSignaturePackageName;
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public OverlayableInfo getOverlayableForTarget(@NonNull String packageName,
|
public OverlayableInfo getOverlayableForTarget(@NonNull String packageName,
|
||||||
|
|||||||
@@ -168,6 +168,7 @@ message OverlayableItem {
|
|||||||
ODM = 6;
|
ODM = 6;
|
||||||
OEM = 7;
|
OEM = 7;
|
||||||
ACTOR = 8;
|
ACTOR = 8;
|
||||||
|
CONFIG_SIGNATURE = 9;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The location of the <item> declaration in source.
|
// The location of the <item> declaration in source.
|
||||||
|
|||||||
@@ -776,6 +776,7 @@ TEST_F(TableFlattenerTest, FlattenMultipleOverlayable) {
|
|||||||
OverlayableItem overlayable_item_three(group_one);
|
OverlayableItem overlayable_item_three(group_one);
|
||||||
overlayable_item_three.policies |= PolicyFlags::SIGNATURE;
|
overlayable_item_three.policies |= PolicyFlags::SIGNATURE;
|
||||||
overlayable_item_three.policies |= PolicyFlags::ACTOR_SIGNATURE;
|
overlayable_item_three.policies |= PolicyFlags::ACTOR_SIGNATURE;
|
||||||
|
overlayable_item_three.policies |= PolicyFlags::CONFIG_SIGNATURE;
|
||||||
|
|
||||||
std::unique_ptr<ResourceTable> table =
|
std::unique_ptr<ResourceTable> table =
|
||||||
test::ResourceTableBuilder()
|
test::ResourceTableBuilder()
|
||||||
@@ -830,7 +831,8 @@ TEST_F(TableFlattenerTest, FlattenMultipleOverlayable) {
|
|||||||
EXPECT_EQ(result_overlayable.overlayable->name, "OtherName");
|
EXPECT_EQ(result_overlayable.overlayable->name, "OtherName");
|
||||||
EXPECT_EQ(result_overlayable.overlayable->actor, "overlay://customization");
|
EXPECT_EQ(result_overlayable.overlayable->actor, "overlay://customization");
|
||||||
EXPECT_EQ(result_overlayable.policies, PolicyFlags::SIGNATURE
|
EXPECT_EQ(result_overlayable.policies, PolicyFlags::SIGNATURE
|
||||||
| PolicyFlags::ACTOR_SIGNATURE);
|
| PolicyFlags::ACTOR_SIGNATURE
|
||||||
|
| PolicyFlags::CONFIG_SIGNATURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TableFlattenerTest, FlattenOverlayableNoPolicyFails) {
|
TEST_F(TableFlattenerTest, FlattenOverlayableNoPolicyFails) {
|
||||||
|
|||||||
@@ -404,6 +404,9 @@ bool DeserializeOverlayableItemFromPb(const pb::OverlayableItem& pb_overlayable,
|
|||||||
case pb::OverlayableItem::ACTOR:
|
case pb::OverlayableItem::ACTOR:
|
||||||
out_overlayable->policies |= PolicyFlags::ACTOR_SIGNATURE;
|
out_overlayable->policies |= PolicyFlags::ACTOR_SIGNATURE;
|
||||||
break;
|
break;
|
||||||
|
case pb::OverlayableItem::CONFIG_SIGNATURE:
|
||||||
|
out_overlayable->policies |= PolicyFlags::CONFIG_SIGNATURE;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
*out_error = "unknown overlayable policy";
|
*out_error = "unknown overlayable policy";
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -325,6 +325,9 @@ static void SerializeOverlayableItemToPb(const OverlayableItem& overlayable_item
|
|||||||
if (overlayable_item.policies & PolicyFlags::ACTOR_SIGNATURE) {
|
if (overlayable_item.policies & PolicyFlags::ACTOR_SIGNATURE) {
|
||||||
pb_overlayable_item->add_policy(pb::OverlayableItem::ACTOR);
|
pb_overlayable_item->add_policy(pb::OverlayableItem::ACTOR);
|
||||||
}
|
}
|
||||||
|
if (overlayable_item.policies & PolicyFlags::CONFIG_SIGNATURE) {
|
||||||
|
pb_overlayable_item->add_policy(pb::OverlayableItem::CONFIG_SIGNATURE);
|
||||||
|
}
|
||||||
|
|
||||||
if (source_pool != nullptr) {
|
if (source_pool != nullptr) {
|
||||||
SerializeSourceToPb(overlayable_item.source, source_pool,
|
SerializeSourceToPb(overlayable_item.source, source_pool,
|
||||||
|
|||||||
Reference in New Issue
Block a user