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

Commit cb5aa649 authored by Ivan Chiang's avatar Ivan Chiang
Browse files

[PM] Use callingUid instead of binder#getCallingUid for uninstall

When the system checks whether the caller can uninstall an app
silently, we should use callingUid to instead of the callingUid from
the Binder. Because the archive caller calls uninstall method in the
handler of PackageManagerService. The callingUid from the Binder is
system server at this time.

Flag: EXEMPT bugfix
Bug: 352325525
Test: atest UninstallationViaIntentActionDeleteTest
Test: atest UninstallationViaIntentActionUninstallPackageTest
Test: atest UninstallationViaPackageInstallerApiTest
Test: atest UninstallTest
Test: atest PackageInstallerArchiveTest
Test: atest ArchiveTest
Test: manual. call requestArchive in a system app that is granted
      DELETE_PACKAGES. The user confirm dialog pops up.
Test: manual. Settings can restore and archive apps.
Change-Id: I3e95fa7690a69ca379fa4c108012ecfec841a9c8
parent aa960910
Loading
Loading
Loading
Loading
+17 −5
Original line number Diff line number Diff line
@@ -690,7 +690,13 @@ final class DeletePackageHelper {
    public void deletePackageVersionedInternal(VersionedPackage versionedPackage,
            final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags,
            final boolean allowSilentUninstall) {
        final int callingUid = Binder.getCallingUid();
        deletePackageVersionedInternal(versionedPackage, observer, userId, deleteFlags,
                Binder.getCallingUid(), allowSilentUninstall);
    }

    public void deletePackageVersionedInternal(VersionedPackage versionedPackage,
            final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags,
            final int callingUid, final boolean allowSilentUninstall) {
        mPm.mContext.enforceCallingOrSelfPermission(
                android.Manifest.permission.DELETE_PACKAGES, null);
        final Computer snapshot = mPm.snapshotComputer();
@@ -720,16 +726,22 @@ final class DeletePackageHelper {
        final String internalPackageName =
                snapshot.resolveInternalPackageName(packageName, versionCode);

        final int uid = Binder.getCallingUid();
        if (!isOrphaned(snapshot, internalPackageName)
                && !allowSilentUninstall
                && !isCallerAllowedToSilentlyUninstall(
                        snapshot, uid, internalPackageName, userId)) {
                        snapshot, callingUid, internalPackageName, userId)) {
            mPm.mHandler.post(() -> {
                try {
                    final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
                    intent.setData(Uri.fromParts(PACKAGE_SCHEME, packageName, null));
                    intent.putExtra(PackageInstaller.EXTRA_CALLBACK, observer.asBinder());
                    intent.putExtra(PackageInstaller.EXTRA_CALLBACK,
                            new PackageManager.UninstallCompleteCallback(observer.asBinder()));
                    if ((deleteFlags & PackageManager.DELETE_ARCHIVE) != 0) {
                        // Delete flags are passed to the uninstaller activity so it can be
                        // preserved in the follow-up uninstall operation after the user
                        // confirmation
                        intent.putExtra(PackageInstaller.EXTRA_DELETE_FLAGS, deleteFlags);
                    }
                    observer.onUserActionRequired(intent);
                } catch (RemoteException re) {
                }
@@ -738,7 +750,7 @@ final class DeletePackageHelper {
        }
        final boolean deleteAllUsers = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0;
        final int[] users = deleteAllUsers ? mUserManagerInternal.getUserIds() : new int[]{userId};
        if (UserHandle.getUserId(uid) != userId || (deleteAllUsers && users.length > 1)) {
        if (UserHandle.getUserId(callingUid) != userId || (deleteAllUsers && users.length > 1)) {
            mPm.mContext.enforceCallingOrSelfPermission(
                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
                    "deletePackage for user " + userId);
+2 −1
Original line number Diff line number Diff line
@@ -1438,7 +1438,8 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
        if (mContext.checkPermission(Manifest.permission.DELETE_PACKAGES, callingPid, callingUid)
                == PackageManager.PERMISSION_GRANTED) {
            // Sweet, call straight through!
            mPm.deletePackageVersioned(versionedPackage, adapter.getBinder(), userId, flags);
            mPm.deletePackageVersioned(versionedPackage, adapter.getBinder(), userId, flags,
                    callingUid);
        } else if (canSilentlyInstallPackage) {
            // Allow the device owner and affiliated profile owner to silently delete packages
            // Need to clear the calling identity to get DELETE_PACKAGES permission
+9 −1
Original line number Diff line number Diff line
@@ -3322,10 +3322,18 @@ public class PackageManagerService implements PackageSender, TestUtilityService
                versionedPackage, observer, userId);
    }

    public void deletePackageVersioned(VersionedPackage versionedPackage,
            final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags,
            final int callingUid) {
        mDeletePackageHelper.deletePackageVersionedInternal(
                versionedPackage, observer, userId, deleteFlags, callingUid,
                /* allowSilentUninstall= */ false);
    }

    public void deletePackageVersioned(VersionedPackage versionedPackage,
            final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags) {
        mDeletePackageHelper.deletePackageVersionedInternal(
                versionedPackage, observer, userId, deleteFlags, false);
                versionedPackage, observer, userId, deleteFlags, /* allowSilentUninstall= */ false);
    }

    boolean isCallerVerifier(@NonNull Computer snapshot, int callingUid) {