Skip to content

Commit 41b850d

Browse files
RyanMitch16Android (Google) Code Review
authored andcommitted
Merge "Persist implicit overlay configurator actor policy" into rvc-dev
2 parents 1aced77 + af93f5d commit 41b850d

10 files changed

Lines changed: 269 additions & 168 deletions

File tree

cmds/idmap2/libidmap2/ResourceMapping.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,8 @@ Result<Unit> CheckOverlayable(const LoadedPackage& target_package,
6161
const ResourceId& target_resource) {
6262
static constexpr const PolicyBitmask sDefaultPolicies =
6363
PolicyFlags::ODM_PARTITION | PolicyFlags::OEM_PARTITION | PolicyFlags::SYSTEM_PARTITION |
64-
PolicyFlags::VENDOR_PARTITION | PolicyFlags::PRODUCT_PARTITION | PolicyFlags::SIGNATURE;
64+
PolicyFlags::VENDOR_PARTITION | PolicyFlags::PRODUCT_PARTITION | PolicyFlags::SIGNATURE |
65+
PolicyFlags::ACTOR_SIGNATURE;
6566

6667
// If the resource does not have an overlayable definition, allow the resource to be overlaid if
6768
// the overlay is preinstalled or signed with the same signature as the target.

cmds/idmap2/tests/ResourceMappingTests.cpp

Lines changed: 15 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -287,66 +287,26 @@ TEST(ResourceMappingTests, ResourcesFromApkAssetsNoDefinedOverlayableAndNoTarget
287287
R::overlay::string::str4, false /* rewrite */));
288288
}
289289

290-
// Overlays that are neither pre-installed nor signed with the same signature as the target cannot
291-
// overlay packages that have not defined overlayable resources.
292-
TEST(ResourceMappingTests, ResourcesFromApkAssetsDefaultPoliciesPublicFail) {
293-
auto resources = TestGetResourceMapping("/target/target-no-overlayable.apk",
294-
"/overlay/overlay-no-name.apk", PolicyFlags::PUBLIC,
295-
/* enforce_overlayable */ true);
296-
297-
ASSERT_TRUE(resources) << resources.GetErrorMessage();
298-
ASSERT_EQ(resources->GetTargetToOverlayMap().size(), 0U);
299-
}
300290

301-
// Overlays that are pre-installed or are signed with the same signature as the target can overlay
302-
// packages that have not defined overlayable resources.
291+
// Overlays that are pre-installed or are signed with the same signature as the target/actor can
292+
// overlay packages that have not defined overlayable resources.
303293
TEST(ResourceMappingTests, ResourcesFromApkAssetsDefaultPolicies) {
304-
auto CheckEntries = [&](const PolicyBitmask& fulfilled_policies) -> void {
294+
constexpr PolicyBitmask kDefaultPolicies =
295+
PolicyFlags::SIGNATURE | PolicyFlags::ACTOR_SIGNATURE | PolicyFlags::PRODUCT_PARTITION |
296+
PolicyFlags::SYSTEM_PARTITION | PolicyFlags::VENDOR_PARTITION | PolicyFlags::ODM_PARTITION |
297+
PolicyFlags::OEM_PARTITION;
298+
299+
for (PolicyBitmask policy = 1U << (sizeof(PolicyBitmask) * 8 - 1); policy > 0;
300+
policy = policy >> 1U) {
305301
auto resources = TestGetResourceMapping("/target/target-no-overlayable.apk",
306302
"/system-overlay-invalid/system-overlay-invalid.apk",
307-
fulfilled_policies,
308-
/* enforce_overlayable */ true);
309-
303+
policy, /* enforce_overlayable */ true);
310304
ASSERT_TRUE(resources) << resources.GetErrorMessage();
311-
auto& res = *resources;
312-
ASSERT_EQ(resources->GetTargetToOverlayMap().size(), 10U);
313-
ASSERT_RESULT(MappingExists(res, R::target::string::not_overlayable, Res_value::TYPE_REFERENCE,
314-
R::system_overlay_invalid::string::not_overlayable,
315-
false /* rewrite */));
316-
ASSERT_RESULT(MappingExists(res, R::target::string::other, Res_value::TYPE_REFERENCE,
317-
R::system_overlay_invalid::string::other, false /* rewrite */));
318-
ASSERT_RESULT(MappingExists(res, R::target::string::policy_actor, Res_value::TYPE_REFERENCE,
319-
R::system_overlay_invalid::string::policy_actor,
320-
false /* rewrite */));
321-
ASSERT_RESULT(MappingExists(res, R::target::string::policy_odm, Res_value::TYPE_REFERENCE,
322-
R::system_overlay_invalid::string::policy_odm,
323-
false /* rewrite */));
324-
ASSERT_RESULT(MappingExists(res, R::target::string::policy_oem, Res_value::TYPE_REFERENCE,
325-
R::system_overlay_invalid::string::policy_oem,
326-
false /* rewrite */));
327-
ASSERT_RESULT(MappingExists(res, R::target::string::policy_product, Res_value::TYPE_REFERENCE,
328-
R::system_overlay_invalid::string::policy_product,
329-
false /* rewrite */));
330-
ASSERT_RESULT(MappingExists(res, R::target::string::policy_public, Res_value::TYPE_REFERENCE,
331-
R::system_overlay_invalid::string::policy_public,
332-
false /* rewrite */));
333-
ASSERT_RESULT(MappingExists(res, R::target::string::policy_signature, Res_value::TYPE_REFERENCE,
334-
R::system_overlay_invalid::string::policy_signature,
335-
false /* rewrite */));
336-
ASSERT_RESULT(MappingExists(res, R::target::string::policy_system, Res_value::TYPE_REFERENCE,
337-
R::system_overlay_invalid::string::policy_system,
338-
false /* rewrite */));
339-
ASSERT_RESULT(MappingExists(
340-
res, R::target::string::policy_system_vendor, Res_value::TYPE_REFERENCE,
341-
R::system_overlay_invalid::string::policy_system_vendor, false /* rewrite */));
342-
};
343-
344-
CheckEntries(PolicyFlags::SIGNATURE);
345-
CheckEntries(PolicyFlags::PRODUCT_PARTITION);
346-
CheckEntries(PolicyFlags::SYSTEM_PARTITION);
347-
CheckEntries(PolicyFlags::VENDOR_PARTITION);
348-
CheckEntries(PolicyFlags::ODM_PARTITION);
349-
CheckEntries(PolicyFlags::OEM_PARTITION);
305+
306+
const size_t expected_overlaid = (policy & kDefaultPolicies) != 0 ? 10U : 0U;
307+
ASSERT_EQ(expected_overlaid, resources->GetTargetToOverlayMap().size())
308+
<< "Incorrect number of resources overlaid through policy " << policy;
309+
}
350310
}
351311

352312
} // namespace android::idmap2

services/core/java/com/android/server/om/IdmapManager.java

Lines changed: 8 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -29,18 +29,15 @@
2929
import android.os.SystemProperties;
3030
import android.util.Slog;
3131

32-
import com.android.internal.util.ArrayUtils;
33-
3432
import java.io.IOException;
3533

3634
/**
3735
* Handle the creation and deletion of idmap files.
3836
*
39-
* The actual work is performed by the idmap binary, launched through idmap2d.
40-
*
41-
* Note: this class is subclassed in the OMS unit tests, and hence not marked as final.
37+
* The actual work is performed by idmap2d.
38+
* @see IdmapDaemon
4239
*/
43-
class IdmapManager {
40+
final class IdmapManager {
4441
private static final boolean VENDOR_IS_Q_OR_LATER;
4542
static {
4643
final String value = SystemProperties.get("ro.vndk.version", "29");
@@ -57,36 +54,33 @@ class IdmapManager {
5754

5855
private final IdmapDaemon mIdmapDaemon;
5956
private final OverlayableInfoCallback mOverlayableCallback;
60-
private final String mOverlayableConfigurator;
61-
private final String[] mOverlayableConfiguratorTargets;
6257

6358
IdmapManager(final IdmapDaemon idmapDaemon, final OverlayableInfoCallback verifyCallback) {
6459
mOverlayableCallback = verifyCallback;
6560
mIdmapDaemon = idmapDaemon;
66-
mOverlayableConfigurator = verifyCallback.getOverlayableConfigurator();
67-
mOverlayableConfiguratorTargets = verifyCallback.getOverlayableConfiguratorTargets() ;
6861
}
6962

7063
/**
7164
* Creates the idmap for the target/overlay combination and returns whether the idmap file was
7265
* modified.
7366
*/
7467
boolean createIdmap(@NonNull final PackageInfo targetPackage,
75-
@NonNull final PackageInfo overlayPackage, int userId) {
68+
@NonNull final PackageInfo overlayPackage, int additionalPolicies, int userId) {
7669
if (DEBUG) {
7770
Slog.d(TAG, "create idmap for " + targetPackage.packageName + " and "
7871
+ overlayPackage.packageName);
7972
}
8073
final String targetPath = targetPackage.applicationInfo.getBaseCodePath();
8174
final String overlayPath = overlayPackage.applicationInfo.getBaseCodePath();
8275
try {
83-
int policies = calculateFulfilledPolicies(targetPackage, overlayPackage, userId);
8476
boolean enforce = enforceOverlayable(overlayPackage);
77+
int policies = calculateFulfilledPolicies(targetPackage, overlayPackage, userId)
78+
| additionalPolicies;
8579
if (mIdmapDaemon.verifyIdmap(targetPath, overlayPath, policies, enforce, userId)) {
8680
return false;
8781
}
88-
return mIdmapDaemon.createIdmap(targetPath, overlayPath, policies,
89-
enforce, userId) != null;
82+
return mIdmapDaemon.createIdmap(targetPath, overlayPath, policies, enforce, userId)
83+
!= null;
9084
} catch (Exception e) {
9185
Slog.w(TAG, "failed to generate idmap for " + targetPath + " and "
9286
+ overlayPath + ": " + e.getMessage());
@@ -190,14 +184,6 @@ private boolean matchesActorSignature(@NonNull PackageInfo targetPackage,
190184
String targetOverlayableName = overlayPackage.targetOverlayableName;
191185
if (targetOverlayableName != null) {
192186
try {
193-
if (!mOverlayableConfigurator.isEmpty()
194-
&& ArrayUtils.contains(mOverlayableConfiguratorTargets,
195-
targetPackage.packageName)
196-
&& mOverlayableCallback.signaturesMatching(mOverlayableConfigurator,
197-
overlayPackage.packageName, userId)) {
198-
return true;
199-
}
200-
201187
OverlayableInfo overlayableInfo = mOverlayableCallback.getOverlayableForTarget(
202188
targetPackage.packageName, targetOverlayableName, userId);
203189
if (overlayableInfo != null && overlayableInfo.actor != null) {

services/core/java/com/android/server/om/OverlayManagerService.java

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,8 @@ public OverlayManagerService(@NonNull final Context context) {
252252
mSettings = new OverlayManagerSettings();
253253
mImpl = new OverlayManagerServiceImpl(mPackageManager, im, mSettings,
254254
OverlayConfig.getSystemInstance(), getDefaultOverlayPackages(),
255-
new OverlayChangeListener());
255+
new OverlayChangeListener(), getOverlayableConfigurator(),
256+
getOverlayableConfiguratorTargets());
256257
mActorEnforcer = new OverlayActorEnforcer(mPackageManager);
257258

258259
final IntentFilter packageFilter = new IntentFilter();
@@ -335,6 +336,28 @@ private static String[] getDefaultOverlayPackages() {
335336
return defaultPackages.toArray(new String[defaultPackages.size()]);
336337
}
337338

339+
340+
/**
341+
* Retrieves the package name that is recognized as an actor for the packages specified by
342+
* {@link #getOverlayableConfiguratorTargets()}.
343+
*/
344+
@Nullable
345+
private String getOverlayableConfigurator() {
346+
return TextUtils.nullIfEmpty(Resources.getSystem()
347+
.getString(R.string.config_overlayableConfigurator));
348+
}
349+
350+
/**
351+
* Retrieves the target packages that recognize the {@link #getOverlayableConfigurator} as an
352+
* actor for itself. Overlays targeting one of the specified targets that are signed with the
353+
* same signature as the overlayable configurator will be granted the "actor" policy.
354+
*/
355+
@Nullable
356+
private String[] getOverlayableConfiguratorTargets() {
357+
return Resources.getSystem().getStringArray(
358+
R.array.config_overlayableConfiguratorTargets);
359+
}
360+
338361
private final class PackageReceiver extends BroadcastReceiver {
339362
@Override
340363
public void onReceive(@NonNull final Context context, @NonNull final Intent intent) {
@@ -1120,17 +1143,6 @@ public boolean signaturesMatching(@NonNull final String packageName1,
11201143
return false;
11211144
}
11221145

1123-
@Override
1124-
public String getOverlayableConfigurator() {
1125-
return Resources.getSystem().getString(R.string.config_overlayableConfigurator);
1126-
}
1127-
1128-
@Override
1129-
public String[] getOverlayableConfiguratorTargets() {
1130-
return Resources.getSystem().getStringArray(
1131-
R.array.config_overlayableConfiguratorTargets);
1132-
}
1133-
11341146
@Override
11351147
public List<PackageInfo> getOverlayPackages(final int userId) {
11361148
final List<PackageInfo> overlays = mPackageManagerInternal.getOverlayPackages(userId);

services/core/java/com/android/server/om/OverlayManagerServiceImpl.java

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import android.content.om.OverlayInfo;
3232
import android.content.pm.ApplicationInfo;
3333
import android.content.pm.PackageInfo;
34+
import android.os.OverlayablePolicy;
3435
import android.text.TextUtils;
3536
import android.util.ArrayMap;
3637
import android.util.ArraySet;
@@ -73,6 +74,9 @@ final class OverlayManagerServiceImpl {
7374
private final String[] mDefaultOverlays;
7475
private final OverlayChangeListener mListener;
7576

77+
private final String mOverlayableConfigurator;
78+
private final String[] mOverlayableConfiguratorTargets;
79+
7680
/**
7781
* Helper method to merge the overlay manager's (as read from overlays.xml)
7882
* and package manager's (as parsed from AndroidManifest.xml files) views
@@ -115,13 +119,17 @@ private boolean mustReinitializeOverlay(@NonNull final PackageInfo theTruth,
115119
@NonNull final OverlayManagerSettings settings,
116120
@NonNull final OverlayConfig overlayConfig,
117121
@NonNull final String[] defaultOverlays,
118-
@NonNull final OverlayChangeListener listener) {
122+
@NonNull final OverlayChangeListener listener,
123+
@Nullable final String overlayableConfigurator,
124+
@Nullable final String[] overlayableConfiguratorTargets) {
119125
mPackageManager = packageManager;
120126
mIdmapManager = idmapManager;
121127
mSettings = settings;
122128
mOverlayConfig = overlayConfig;
123129
mDefaultOverlays = defaultOverlays;
124130
mListener = listener;
131+
mOverlayableConfigurator = overlayableConfigurator;
132+
mOverlayableConfiguratorTargets = overlayableConfiguratorTargets;
125133
}
126134

127135
/**
@@ -706,7 +714,25 @@ private boolean updateState(@NonNull final String targetPackageName,
706714
if (targetPackage != null && overlayPackage != null
707715
&& !("android".equals(targetPackageName)
708716
&& !isPackageConfiguredMutable(overlayPackageName))) {
709-
modified |= mIdmapManager.createIdmap(targetPackage, overlayPackage, userId);
717+
718+
int additionalPolicies = 0;
719+
if (TextUtils.nullIfEmpty(mOverlayableConfigurator) != null
720+
&& ArrayUtils.contains(mOverlayableConfiguratorTargets, targetPackageName)
721+
&& isPackageConfiguredMutable(overlayPackageName)
722+
&& mPackageManager.signaturesMatching(mOverlayableConfigurator,
723+
overlayPackageName, userId)) {
724+
// The overlay targets a package that has the overlayable configurator configured as
725+
// its actor. The overlay and this actor are signed with the same signature, so
726+
// the overlay fulfills the actor policy.
727+
modified |= mSettings.setHasConfiguratorActorPolicy(overlayPackageName, userId,
728+
true);
729+
additionalPolicies |= OverlayablePolicy.ACTOR_SIGNATURE;
730+
} else if (mSettings.hasConfiguratorActorPolicy(overlayPackageName, userId)) {
731+
additionalPolicies |= OverlayablePolicy.ACTOR_SIGNATURE;
732+
}
733+
734+
modified |= mIdmapManager.createIdmap(targetPackage, overlayPackage, additionalPolicies,
735+
userId);
710736
}
711737

712738
if (overlayPackage != null) {

0 commit comments

Comments
 (0)