Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 13313007 authored by Ryan Mitchell's avatar Ryan Mitchell Committed by Android (Google) Code Review
Browse files

Merge "Revert "Persist implicit overlay configurator actor policy"" into rvc-dev

parents 8761fbb5 e88ef742
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -61,8 +61,7 @@ Result<Unit> CheckOverlayable(const LoadedPackage& target_package,
                              const ResourceId& target_resource) {
  static constexpr const PolicyBitmask sDefaultPolicies =
      PolicyFlags::ODM_PARTITION | PolicyFlags::OEM_PARTITION | PolicyFlags::SYSTEM_PARTITION |
      PolicyFlags::VENDOR_PARTITION | PolicyFlags::PRODUCT_PARTITION | PolicyFlags::SIGNATURE |
      PolicyFlags::ACTOR_SIGNATURE;
      PolicyFlags::VENDOR_PARTITION | PolicyFlags::PRODUCT_PARTITION | PolicyFlags::SIGNATURE;

  // If the resource does not have an overlayable definition, allow the resource to be overlaid if
  // the overlay is preinstalled or signed with the same signature as the target.
+55 −15
Original line number Diff line number Diff line
@@ -287,26 +287,66 @@ TEST(ResourceMappingTests, ResourcesFromApkAssetsNoDefinedOverlayableAndNoTarget
                              R::overlay::string::str4, false /* rewrite */));
}


// Overlays that are pre-installed or are signed with the same signature as the target/actor can
// Overlays that are neither pre-installed nor signed with the same signature as the target cannot
// overlay packages that have not defined overlayable resources.
TEST(ResourceMappingTests, ResourcesFromApkAssetsDefaultPolicies) {
  constexpr PolicyBitmask kDefaultPolicies =
      PolicyFlags::SIGNATURE | PolicyFlags::ACTOR_SIGNATURE | PolicyFlags::PRODUCT_PARTITION |
      PolicyFlags::SYSTEM_PARTITION | PolicyFlags::VENDOR_PARTITION | PolicyFlags::ODM_PARTITION |
      PolicyFlags::OEM_PARTITION;
TEST(ResourceMappingTests, ResourcesFromApkAssetsDefaultPoliciesPublicFail) {
  auto resources = TestGetResourceMapping("/target/target-no-overlayable.apk",
                                          "/overlay/overlay-no-name.apk", PolicyFlags::PUBLIC,
                                          /* enforce_overlayable */ true);

  ASSERT_TRUE(resources) << resources.GetErrorMessage();
  ASSERT_EQ(resources->GetTargetToOverlayMap().size(), 0U);
}

  for (PolicyBitmask policy = 1U << (sizeof(PolicyBitmask) * 8 - 1); policy > 0;
       policy = policy >> 1U) {
// Overlays that are pre-installed or are signed with the same signature as the target can overlay
// packages that have not defined overlayable resources.
TEST(ResourceMappingTests, ResourcesFromApkAssetsDefaultPolicies) {
  auto CheckEntries = [&](const PolicyBitmask& fulfilled_policies) -> void {
    auto resources = TestGetResourceMapping("/target/target-no-overlayable.apk",
                                            "/system-overlay-invalid/system-overlay-invalid.apk",
                                            policy, /* enforce_overlayable */ true);
    ASSERT_TRUE(resources) << resources.GetErrorMessage();
                                            fulfilled_policies,
                                            /* enforce_overlayable */ true);

    const size_t expected_overlaid = (policy & kDefaultPolicies) != 0 ? 10U : 0U;
    ASSERT_EQ(expected_overlaid, resources->GetTargetToOverlayMap().size())
        << "Incorrect number of resources overlaid through policy " << policy;
  }
    ASSERT_TRUE(resources) << resources.GetErrorMessage();
    auto& res = *resources;
    ASSERT_EQ(resources->GetTargetToOverlayMap().size(), 10U);
    ASSERT_RESULT(MappingExists(res, R::target::string::not_overlayable, Res_value::TYPE_REFERENCE,
                                R::system_overlay_invalid::string::not_overlayable,
                                false /* rewrite */));
    ASSERT_RESULT(MappingExists(res, R::target::string::other, Res_value::TYPE_REFERENCE,
                                R::system_overlay_invalid::string::other, false /* rewrite */));
    ASSERT_RESULT(MappingExists(res, R::target::string::policy_actor, Res_value::TYPE_REFERENCE,
                                R::system_overlay_invalid::string::policy_actor,
                                false /* rewrite */));
    ASSERT_RESULT(MappingExists(res, R::target::string::policy_odm, Res_value::TYPE_REFERENCE,
                                R::system_overlay_invalid::string::policy_odm,
                                false /* rewrite */));
    ASSERT_RESULT(MappingExists(res, R::target::string::policy_oem, Res_value::TYPE_REFERENCE,
                                R::system_overlay_invalid::string::policy_oem,
                                false /* rewrite */));
    ASSERT_RESULT(MappingExists(res, R::target::string::policy_product, Res_value::TYPE_REFERENCE,
                                R::system_overlay_invalid::string::policy_product,
                                false /* rewrite */));
    ASSERT_RESULT(MappingExists(res, R::target::string::policy_public, Res_value::TYPE_REFERENCE,
                                R::system_overlay_invalid::string::policy_public,
                                false /* rewrite */));
    ASSERT_RESULT(MappingExists(res, R::target::string::policy_signature, Res_value::TYPE_REFERENCE,
                                R::system_overlay_invalid::string::policy_signature,
                                false /* rewrite */));
    ASSERT_RESULT(MappingExists(res, R::target::string::policy_system, Res_value::TYPE_REFERENCE,
                                R::system_overlay_invalid::string::policy_system,
                                false /* rewrite */));
    ASSERT_RESULT(MappingExists(
        res, R::target::string::policy_system_vendor, Res_value::TYPE_REFERENCE,
        R::system_overlay_invalid::string::policy_system_vendor, false /* rewrite */));
  };

  CheckEntries(PolicyFlags::SIGNATURE);
  CheckEntries(PolicyFlags::PRODUCT_PARTITION);
  CheckEntries(PolicyFlags::SYSTEM_PARTITION);
  CheckEntries(PolicyFlags::VENDOR_PARTITION);
  CheckEntries(PolicyFlags::ODM_PARTITION);
  CheckEntries(PolicyFlags::OEM_PARTITION);
}

}  // namespace android::idmap2
+22 −8
Original line number Diff line number Diff line
@@ -29,15 +29,18 @@ import android.os.OverlayablePolicy;
import android.os.SystemProperties;
import android.util.Slog;

import com.android.internal.util.ArrayUtils;

import java.io.IOException;

/**
 * Handle the creation and deletion of idmap files.
 *
 * The actual work is performed by idmap2d.
 * @see IdmapDaemon
 * The actual work is performed by the idmap binary, launched through idmap2d.
 *
 * Note: this class is subclassed in the OMS unit tests, and hence not marked as final.
 */
final class IdmapManager {
class IdmapManager {
    private static final boolean VENDOR_IS_Q_OR_LATER;
    static {
        final String value = SystemProperties.get("ro.vndk.version", "29");
@@ -54,10 +57,14 @@ final class IdmapManager {

    private final IdmapDaemon mIdmapDaemon;
    private final OverlayableInfoCallback mOverlayableCallback;
    private final String mOverlayableConfigurator;
    private final String[] mOverlayableConfiguratorTargets;

    IdmapManager(final IdmapDaemon idmapDaemon, final OverlayableInfoCallback verifyCallback) {
        mOverlayableCallback = verifyCallback;
        mIdmapDaemon = idmapDaemon;
        mOverlayableConfigurator = verifyCallback.getOverlayableConfigurator();
        mOverlayableConfiguratorTargets = verifyCallback.getOverlayableConfiguratorTargets() ;
    }

    /**
@@ -65,7 +72,7 @@ final class IdmapManager {
     * modified.
     */
    boolean createIdmap(@NonNull final PackageInfo targetPackage,
            @NonNull final PackageInfo overlayPackage, int additionalPolicies, int userId) {
            @NonNull final PackageInfo overlayPackage, int userId) {
        if (DEBUG) {
            Slog.d(TAG, "create idmap for " + targetPackage.packageName + " and "
                    + overlayPackage.packageName);
@@ -73,14 +80,13 @@ final class IdmapManager {
        final String targetPath = targetPackage.applicationInfo.getBaseCodePath();
        final String overlayPath = overlayPackage.applicationInfo.getBaseCodePath();
        try {
            int policies = calculateFulfilledPolicies(targetPackage, overlayPackage, userId);
            boolean enforce = enforceOverlayable(overlayPackage);
            int policies = calculateFulfilledPolicies(targetPackage, overlayPackage, userId)
                    | additionalPolicies;
            if (mIdmapDaemon.verifyIdmap(targetPath, overlayPath, policies, enforce, userId)) {
                return false;
            }
            return mIdmapDaemon.createIdmap(targetPath, overlayPath, policies, enforce, userId)
                    != null;
            return mIdmapDaemon.createIdmap(targetPath, overlayPath, policies,
                    enforce, userId) != null;
        } catch (Exception e) {
            Slog.w(TAG, "failed to generate idmap for " + targetPath + " and "
                    + overlayPath + ": " + e.getMessage());
@@ -184,6 +190,14 @@ final class IdmapManager {
        String targetOverlayableName = overlayPackage.targetOverlayableName;
        if (targetOverlayableName != null) {
            try {
                if (!mOverlayableConfigurator.isEmpty()
                        && ArrayUtils.contains(mOverlayableConfiguratorTargets,
                                targetPackage.packageName)
                        && mOverlayableCallback.signaturesMatching(mOverlayableConfigurator,
                                overlayPackage.packageName, userId)) {
                    return true;
                }

                OverlayableInfo overlayableInfo = mOverlayableCallback.getOverlayableForTarget(
                        targetPackage.packageName, targetOverlayableName, userId);
                if (overlayableInfo != null && overlayableInfo.actor != null) {
+12 −24
Original line number Diff line number Diff line
@@ -252,8 +252,7 @@ public final class OverlayManagerService extends SystemService {
            mSettings = new OverlayManagerSettings();
            mImpl = new OverlayManagerServiceImpl(mPackageManager, im, mSettings,
                    OverlayConfig.getSystemInstance(), getDefaultOverlayPackages(),
                    new OverlayChangeListener(), getOverlayableConfigurator(),
                    getOverlayableConfiguratorTargets());
                    new OverlayChangeListener());
            mActorEnforcer = new OverlayActorEnforcer(mPackageManager);

            final IntentFilter packageFilter = new IntentFilter();
@@ -336,28 +335,6 @@ public final class OverlayManagerService extends SystemService {
        return defaultPackages.toArray(new String[defaultPackages.size()]);
    }


    /**
     * Retrieves the package name that is recognized as an actor for the packages specified by
     * {@link #getOverlayableConfiguratorTargets()}.
     */
    @Nullable
    private String getOverlayableConfigurator() {
        return TextUtils.nullIfEmpty(Resources.getSystem()
                .getString(R.string.config_overlayableConfigurator));
    }

    /**
     * Retrieves the target packages that recognize the {@link #getOverlayableConfigurator} as an
     * actor for itself. Overlays targeting one of the specified targets that are signed with the
     * same signature as the overlayable configurator will be granted the "actor" policy.
     */
    @Nullable
    private String[] getOverlayableConfiguratorTargets() {
        return Resources.getSystem().getStringArray(
                R.array.config_overlayableConfiguratorTargets);
    }

    private final class PackageReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(@NonNull final Context context, @NonNull final Intent intent) {
@@ -1143,6 +1120,17 @@ public final class OverlayManagerService extends SystemService {
            return false;
        }

        @Override
        public String getOverlayableConfigurator() {
            return Resources.getSystem().getString(R.string.config_overlayableConfigurator);
        }

        @Override
        public String[] getOverlayableConfiguratorTargets() {
            return Resources.getSystem().getStringArray(
                    R.array.config_overlayableConfiguratorTargets);
        }

        @Override
        public List<PackageInfo> getOverlayPackages(final int userId) {
            final List<PackageInfo> overlays = mPackageManagerInternal.getOverlayPackages(userId);
+2 −28
Original line number Diff line number Diff line
@@ -31,7 +31,6 @@ import android.annotation.Nullable;
import android.content.om.OverlayInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.os.OverlayablePolicy;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
@@ -74,9 +73,6 @@ final class OverlayManagerServiceImpl {
    private final String[] mDefaultOverlays;
    private final OverlayChangeListener mListener;

    private final String mOverlayableConfigurator;
    private final String[] mOverlayableConfiguratorTargets;

    /**
     * Helper method to merge the overlay manager's (as read from overlays.xml)
     * and package manager's (as parsed from AndroidManifest.xml files) views
@@ -119,17 +115,13 @@ final class OverlayManagerServiceImpl {
            @NonNull final OverlayManagerSettings settings,
            @NonNull final OverlayConfig overlayConfig,
            @NonNull final String[] defaultOverlays,
            @NonNull final OverlayChangeListener listener,
            @Nullable final String overlayableConfigurator,
            @Nullable final String[] overlayableConfiguratorTargets) {
            @NonNull final OverlayChangeListener listener) {
        mPackageManager = packageManager;
        mIdmapManager = idmapManager;
        mSettings = settings;
        mOverlayConfig = overlayConfig;
        mDefaultOverlays = defaultOverlays;
        mListener = listener;
        mOverlayableConfigurator = overlayableConfigurator;
        mOverlayableConfiguratorTargets = overlayableConfiguratorTargets;
    }

    /**
@@ -714,25 +706,7 @@ final class OverlayManagerServiceImpl {
        if (targetPackage != null && overlayPackage != null
                && !("android".equals(targetPackageName)
                    && !isPackageConfiguredMutable(overlayPackageName))) {

            int additionalPolicies = 0;
            if (TextUtils.nullIfEmpty(mOverlayableConfigurator) != null
                    && ArrayUtils.contains(mOverlayableConfiguratorTargets, targetPackageName)
                    && isPackageConfiguredMutable(overlayPackageName)
                    && mPackageManager.signaturesMatching(mOverlayableConfigurator,
                            overlayPackageName, userId)) {
                // The overlay targets a package that has the overlayable configurator configured as
                // its actor. The overlay and this actor are signed with the same signature, so
                // the overlay fulfills the actor policy.
                modified |= mSettings.setHasConfiguratorActorPolicy(overlayPackageName, userId,
                        true);
                additionalPolicies |= OverlayablePolicy.ACTOR_SIGNATURE;
            } else if (mSettings.hasConfiguratorActorPolicy(overlayPackageName, userId)) {
                additionalPolicies |= OverlayablePolicy.ACTOR_SIGNATURE;
            }

            modified |= mIdmapManager.createIdmap(targetPackage, overlayPackage, additionalPolicies,
                    userId);
            modified |= mIdmapManager.createIdmap(targetPackage, overlayPackage, userId);
        }

        if (overlayPackage != null) {
Loading