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

Commit eec488f4 authored by Sumedh Sen's avatar Sumedh Sen
Browse files

[piav2] Simplify UIDs in PacakgeInstaller app

Multiple UIDs were used in Pia, without distinctive use of each of them.
We must ensure each UID has a clear use in Pia.

This was implemented for Pia V1 in ag/26478352

Test: Manual. Install an APK and ensure app is installed
Bug: 26666746
Flag: android.content.pm.use_pia_v2
Change-Id: I9267817b97d8d004cce4b9604b6018c6904adbb6
parent 78d9c1b7
Loading
Loading
Loading
Loading
+25 −22
Original line number Diff line number Diff line
@@ -95,9 +95,22 @@ class InstallRepository(private val context: Context) {
     */
    var stagedSessionId = SessionInfo.INVALID_ID
        private set

    /**
     * UID of the last caller of Pia. This can point to a 3P installer if it uses intents to install
     * an APK, or receives a
     * [STATUS_PENDING_USER_ACTION][PackageInstaller.STATUS_PENDING_USER_ACTION] status code.
     * It may point to Pia, when it receives the STATUS_PENDING_USER_ACTION status code in case of
     * an update-ownership change.
     */
    private var callingUid = Process.INVALID_UID

    /**
     * UID of the origin of the installation. This UID is used to fetch the app-label of the
     * source of the install, and also check whether the source app has the AppOp to install other
     * apps.
     */
    private var originatingUid = Process.INVALID_UID
    private var originatingUidFromSessionInfo = Process.INVALID_UID
    private var callingPackage: String? = null
    private var sessionStager: SessionStager? = null
    private lateinit var intent: Intent
@@ -143,22 +156,19 @@ class InstallRepository(private val context: Context) {
            Log.e(LOG_TAG, "Could not determine the launching uid.")
        }

        originatingUidFromSessionInfo = callingUid
        originatingUid = callingUid
        val sessionInfo: SessionInfo? =
            if (sessionId != SessionInfo.INVALID_ID)
                packageInstaller.getSessionInfo(sessionId)
            else null
        if (sessionInfo != null) {
            callingPackage = sessionInfo.installerPackageName
            callingAttributionTag = sessionInfo.installerAttributionTag
            if (sessionInfo.originatingUid != Process.INVALID_UID) {
                originatingUidFromSessionInfo = sessionInfo.originatingUid
                originatingUid = sessionInfo.originatingUid
            }
        }

        val sourceInfo: ApplicationInfo? = getSourceInfo(callingPackage)
        // Uid of the source package, with a preference to uid from ApplicationInfo
        originatingUid = sourceInfo?.uid ?: callingUid
        appOpRequestInfo = AppOpRequestInfo(
            getPackageNameForUid(context, originatingUid, callingPackage),
            originatingUid, callingAttributionTag
@@ -180,24 +190,18 @@ class InstallRepository(private val context: Context) {
        }

        if ((sessionId != SessionInfo.INVALID_ID
                && !isCallerSessionOwner(packageInstaller, originatingUid, sessionId))
                && !isCallerSessionOwner(packageInstaller, callingUid, sessionId))
            || (stagedSessionId != SessionInfo.INVALID_ID
                && !isCallerSessionOwner(packageInstaller, Process.myUid(), stagedSessionId))
        ) {
            Log.e(LOG_TAG, "UID is not the owner of the session:\n" +
                "CallingUid: $originatingUid | SessionId: $sessionId\n" +
                "CallingUid: $callingUid | SessionId: $sessionId\n" +
                "My UID: ${Process.myUid()} | StagedSessionId: $stagedSessionId")
            return InstallAborted(ABORT_REASON_INTERNAL_ERROR)
        }

        isTrustedSource = isInstallRequestFromTrustedSource(sourceInfo, this.intent, originatingUid)
        if (!isInstallPermissionGrantedOrRequested(
                context, callingUid, originatingUid, isTrustedSource
            )
        ) {
            Log.e(LOG_TAG, "UID $originatingUid needs to declare " +
                Manifest.permission.REQUEST_INSTALL_PACKAGES
            )
        isTrustedSource = isInstallRequestFromTrustedSource(sourceInfo, this.intent, callingUid)
        if (!isInstallPermissionGrantedOrRequested(context, callingUid, isTrustedSource)) {
            return InstallAborted(ABORT_REASON_INTERNAL_ERROR)
        }

@@ -230,12 +234,12 @@ class InstallRepository(private val context: Context) {
    private fun isInstallRequestFromTrustedSource(
        sourceInfo: ApplicationInfo?,
        intent: Intent,
        originatingUid: Int,
        callingUid: Int,
    ): Boolean {
        val isNotUnknownSource = intent.getBooleanExtra(Intent.EXTRA_NOT_UNKNOWN_SOURCE, false)
        return (sourceInfo != null && sourceInfo.isPrivilegedApp
            && (isNotUnknownSource
            || isPermissionGranted(context, Manifest.permission.INSTALL_PACKAGES, originatingUid)))
            || isPermissionGranted(context, Manifest.permission.INSTALL_PACKAGES, callingUid)))
    }

    private fun getDevicePolicyRestrictions(): String? {
@@ -661,10 +665,9 @@ class InstallRepository(private val context: Context) {
        if (isAppUpdating(pkgInfo)) {
            val existingUpdateOwnerLabel = getExistingUpdateOwnerLabel(pkgInfo)

            val originatingPackageNameFromSessionInfo =
                getPackageNameForUid(context, originatingUidFromSessionInfo, callingPackage)
            val requestedUpdateOwnerLabel =
                getApplicationLabel(originatingPackageNameFromSessionInfo)
            val originatingPackageName =
                getPackageNameForUid(context, originatingUid, callingPackage)
            val requestedUpdateOwnerLabel = getApplicationLabel(originatingPackageName)

            if (!TextUtils.isEmpty(existingUpdateOwnerLabel)
                && userActionReason == PackageInstaller.REASON_REMIND_OWNERSHIP
+16 −16
Original line number Diff line number Diff line
@@ -128,18 +128,19 @@ object PackageUtil {

    /**
     * @param context the [Context] object
     * @param callingUid the UID of the caller who's permission is being checked
     * @param originatingUid the UID from where install is being originated. This could be same as
     * callingUid or it will be the UID of the package performing a session based install
     * @param isTrustedSource whether install request is coming from a privileged app or an app that
     * has [Manifest.permission.INSTALL_PACKAGES] permission granted
     * @return `true` if the package is granted the said permission
     * @param callingUid the UID of the caller of Pia
     * @param isTrustedSource indicates whether install request is coming from a privileged app
     * that has passed EXTRA_NOT_UNKNOWN_SOURCE as `true` in the installation intent, or that has
     * the [INSTALL_PACKAGES][Manifest.permission.INSTALL_PACKAGES] permission granted.
     *
     * @return `true` if the package is either a system downloads provider, a document manager,
     * a trusted source, or has declared the
     * [REQUEST_INSTALL_PACKAGES][Manifest.permission.REQUEST_INSTALL_PACKAGES] in its manifest.
     */
    @JvmStatic
    fun isInstallPermissionGrantedOrRequested(
        context: Context,
        callingUid: Int,
        originatingUid: Int,
        isTrustedSource: Boolean,
    ): Boolean {
        val isDocumentsManager =
@@ -148,19 +149,18 @@ object PackageUtil {
            getSystemDownloadsProviderInfo(context.packageManager, callingUid) != null

        if (!isTrustedSource && !isSystemDownloadsProvider && !isDocumentsManager) {
            val targetSdkVersion = getMaxTargetSdkVersionForUid(context, originatingUid)
            val targetSdkVersion = getMaxTargetSdkVersionForUid(context, callingUid)
            if (targetSdkVersion < 0) {
                // Invalid originating uid supplied. Abort install.
                Log.w(LOG_TAG, "Cannot get target sdk version for uid $originatingUid")
                // Invalid calling uid supplied. Abort install.
                Log.e(LOG_TAG, "Cannot get target SDK version for uid $callingUid")
                return false
            } else if (targetSdkVersion >= Build.VERSION_CODES.O
                && !isUidRequestingPermission(
                    context.packageManager, originatingUid,
                    Manifest.permission.REQUEST_INSTALL_PACKAGES
                    context.packageManager, callingUid, Manifest.permission.REQUEST_INSTALL_PACKAGES
                )
            ) {
                Log.e(
                    LOG_TAG, "Requesting uid " + originatingUid + " needs to declare permission "
                    LOG_TAG, "Requesting uid " + callingUid + " needs to declare permission "
                        + Manifest.permission.REQUEST_INSTALL_PACKAGES
                )
                return false
@@ -204,13 +204,13 @@ object PackageUtil {
     * @return `true` if the caller is the session owner
     */
    @JvmStatic
    fun isCallerSessionOwner(pi: PackageInstaller, originatingUid: Int, sessionId: Int): Boolean {
        if (originatingUid == Process.ROOT_UID) {
    fun isCallerSessionOwner(pi: PackageInstaller, callingUid: Int, sessionId: Int): Boolean {
        if (callingUid == Process.ROOT_UID) {
            return true
        }
        val sessionInfo = pi.getSessionInfo(sessionId) ?: return false
        val installerUid = sessionInfo.getInstallerUid()
        return originatingUid == installerUid
        return callingUid == installerUid
    }

    /**