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

Commit 23403fdc authored by Nikita Ioffe's avatar Nikita Ioffe Committed by Android (Google) Code Review
Browse files

Merge "Add sys config to handle apexes that are allowed to be updated" into sc-dev

parents 42ff60e8 637be99a
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -62,6 +62,8 @@ interface IPackageInstaller {

    void bypassNextStagedInstallerCheck(boolean value);

    void bypassNextAllowedApexUpdateCheck(boolean value);

    void setAllowUnlimitedSilentUpdates(String installerPackageName);
    void setSilentUpdatesThrottleTime(long throttleTimeInSeconds);
}
+7 −0
Original line number Diff line number Diff line
@@ -1278,6 +1278,13 @@ public abstract class PackageManager {
     */
    public static final int INSTALL_STAGED = 0x00200000;

    /**
     * Flag parameter for {@link #installPackage} to indicate that check whether given APEX can be
     * updated should be disabled for this install.
     * @hide
     */
    public static final int INSTALL_DISABLE_ALLOWED_APEX_UPDATE_CHECK = 0x00400000;

    /** @hide */
    @IntDef(flag = true, value = {
            DONT_KILL_APP,
+20 −0
Original line number Diff line number Diff line
@@ -240,6 +240,7 @@ public class SystemConfig {

    private final ArraySet<String> mRollbackWhitelistedPackages = new ArraySet<>();
    private final ArraySet<String> mWhitelistedStagedInstallers = new ArraySet<>();
    private final ArraySet<String> mAllowedPartnerApexes = new ArraySet<>();

    /**
     * Map of system pre-defined, uniquely named actors; keys are namespace,
@@ -410,6 +411,10 @@ public class SystemConfig {
        return mWhitelistedStagedInstallers;
    }

    public Set<String> getAllowedPartnerApexes() {
        return mAllowedPartnerApexes;
    }

    public ArraySet<String> getAppDataIsolationWhitelistedApps() {
        return mAppDataIsolationWhitelistedApps;
    }
@@ -1212,6 +1217,21 @@ public class SystemConfig {
                        }
                        XmlUtils.skipCurrentTag(parser);
                    } break;
                    case "allowed-partner-apex": {
                        // TODO(b/189274479): should this be allowOemPermissions instead?
                        if (allowAppConfigs) {
                            String pkgName = parser.getAttributeValue(null, "package");
                            if (pkgName == null) {
                                Slog.w(TAG, "<" + name + "> without package in " + permFile
                                        + " at " + parser.getPositionDescription());
                            } else {
                                mAllowedPartnerApexes.add(pkgName);
                            }
                        } else {
                            logNotAllowedInPartition(name, permFile, parser);
                        }
                        XmlUtils.skipCurrentTag(parser);
                    } break;
                    default: {
                        Slog.w(TAG, "Tag " + name + " is unknown in "
                                + permFile + " at " + parser.getPositionDescription());
+18 −0
Original line number Diff line number Diff line
@@ -157,6 +157,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements

    private volatile boolean mOkToSendBroadcasts = false;
    private volatile boolean mBypassNextStagedInstallerCheck = false;
    private volatile boolean mBypassNextAllowedApexUpdateCheck = false;

    /**
     * File storing persisted {@link #mSessions} metadata.
@@ -650,6 +651,13 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
                throw new IllegalArgumentException(
                    "Non-staged APEX session doesn't support INSTALL_ENABLE_ROLLBACK");
            }
            if (isCalledBySystemOrShell(callingUid) || mBypassNextAllowedApexUpdateCheck) {
                params.installFlags |= PackageManager.INSTALL_DISABLE_ALLOWED_APEX_UPDATE_CHECK;
            } else {
                // Only specific APEX updates (installed through ADB, or for CTS tests) can disable
                // allowed APEX update check.
                params.installFlags &= ~PackageManager.INSTALL_DISABLE_ALLOWED_APEX_UPDATE_CHECK;
            }
        }

        if ((params.installFlags & PackageManager.INSTALL_INSTANT_APP) != 0
@@ -674,6 +682,8 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
        }

        mBypassNextStagedInstallerCheck = false;
        mBypassNextAllowedApexUpdateCheck = false;

        if (!params.isMultiPackage) {
            // Only system components can circumvent runtime permissions when installing.
            if ((params.installFlags & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0
@@ -1106,6 +1116,14 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
        mBypassNextStagedInstallerCheck = value;
    }

    @Override
    public void bypassNextAllowedApexUpdateCheck(boolean value) {
        if (!isCalledBySystemOrShell(Binder.getCallingUid())) {
            throw new SecurityException("Caller not allowed to bypass allowed apex update check");
        }
        mBypassNextAllowedApexUpdateCheck = value;
    }

    /**
     * Set an installer to allow for the unlimited silent updates.
     */
+26 −0
Original line number Diff line number Diff line
@@ -147,6 +147,7 @@ import com.android.internal.util.FrameworkStatsLog;
import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.Preconditions;
import com.android.server.LocalServices;
import com.android.server.SystemConfig;
import com.android.server.pm.Installer.InstallerException;
import com.android.server.pm.dex.DexManager;
import com.android.server.pm.parsing.pkg.AndroidPackage;
@@ -2238,6 +2239,26 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
                    .setAdmin(mInstallSource.installerPackageName)
                    .write();
        }

        // Check if APEX update is allowed. We do this check in handleInstall, since this is one of
        // the places that:
        //   * Shared between staged and non-staged APEX update flows.
        //   * Only is called after boot completes.
        // The later is important, since isApexUpdateAllowed check depends on the
        // ModuleInfoProvider, which is only populated after device has booted.
        if (isApexSession()) {
            boolean checkApexUpdateAllowed =
                    (params.installFlags & PackageManager.INSTALL_DISABLE_ALLOWED_APEX_UPDATE_CHECK)
                        == 0;
            synchronized (mLock) {
                if (checkApexUpdateAllowed && !isApexUpdateAllowed(mPackageName)) {
                    onSessionValidationFailure(PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE,
                            "Update of APEX package " + mPackageName + " is not allowed");
                    return;
                }
            }
        }

        if (params.isStaged) {
            mStagingManager.commitSession(mStagedSession);
            // TODO(b/136257624): CTS test fails if we don't send session finished broadcast, even
@@ -2776,6 +2797,11 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
        return sessionContains((s) -> !s.isApexSession());
    }

    private boolean isApexUpdateAllowed(String apexPackageName) {
        return mPm.getModuleInfo(apexPackageName, 0) != null
                || SystemConfig.getInstance().getAllowedPartnerApexes().contains(apexPackageName);
    }

    /**
     * Validate apex install.
     * <p>
Loading