diff options
| author | 2024-08-02 16:14:53 +0000 | |
|---|---|---|
| committer | 2024-08-05 07:57:57 +0000 | |
| commit | cb5aa6495171fe6ea66de6fecb4752cb528d7ea3 (patch) | |
| tree | 490a2d5052e554f25cc22ca0d6029daba7439ed6 | |
| parent | aa96091053edb7c0a6eb6168899e643657d98439 (diff) | |
[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
3 files changed, 28 insertions, 7 deletions
diff --git a/services/core/java/com/android/server/pm/DeletePackageHelper.java b/services/core/java/com/android/server/pm/DeletePackageHelper.java index b56e119d0a19..8398ffc75f0d 100644 --- a/services/core/java/com/android/server/pm/DeletePackageHelper.java +++ b/services/core/java/com/android/server/pm/DeletePackageHelper.java @@ -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); diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java index 7156795ba771..be6fa14952c8 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerService.java +++ b/services/core/java/com/android/server/pm/PackageInstallerService.java @@ -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 diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 33ca8a8e0f9e..20859da4dd56 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -3323,9 +3323,17 @@ public class PackageManagerService implements PackageSender, TestUtilityService } 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) { |