From 5bd7689ddddf74b5f4f97bcab4e3c1f2a5011d06 Mon Sep 17 00:00:00 2001 From: Oli Lan Date: Thu, 5 May 2022 11:58:02 +0100 Subject: [PATCH] Allow profiles of an admin user to remove system app updates. This modifies a change made earlier that prevented non-admin users from removing updates to system apps. This was intended to prevent users such as guests from reverting updates, but an unintentional effect was that profiles of the admin user (such as a work profile) also became unable to do this. This change allows a profile to revert updates if the parent is an admin user. Bug: 229719733 Test: atest DeletePackageHelperTest Change-Id: Ie9065dfa6a0117f8cf1f49382a8e44655b17cec1 --- .../server/pm/DeletePackageHelper.java | 5 ++- .../server/pm/DeletePackageHelperTest.kt | 44 ++++++++++++++++++- 2 files changed, 45 insertions(+), 4 deletions(-) diff --git a/services/core/java/com/android/server/pm/DeletePackageHelper.java b/services/core/java/com/android/server/pm/DeletePackageHelper.java index cb38d522f3bdd..0cdf7bf62f55a 100644 --- a/services/core/java/com/android/server/pm/DeletePackageHelper.java +++ b/services/core/java/com/android/server/pm/DeletePackageHelper.java @@ -166,9 +166,10 @@ final class DeletePackageHelper { if (PackageManagerServiceUtils.isSystemApp(uninstalledPs)) { UserInfo userInfo = mUserManagerInternal.getUserInfo(userId); - if (userInfo == null || !userInfo.isAdmin()) { + if (userInfo == null || (!userInfo.isAdmin() && !mUserManagerInternal.getUserInfo( + mUserManagerInternal.getProfileParentId(userId)).isAdmin())) { Slog.w(TAG, "Not removing package " + packageName - + " as only admin user may downgrade system apps"); + + " as only admin user (or their profile) may downgrade system apps"); EventLog.writeEvent(0x534e4554, "170646036", -1, packageName); return PackageManager.DELETE_FAILED_USER_RESTRICTED; } diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/DeletePackageHelperTest.kt b/services/tests/mockingservicestests/src/com/android/server/pm/DeletePackageHelperTest.kt index c9598bdc88231..e30f3d26119fc 100644 --- a/services/tests/mockingservicestests/src/com/android/server/pm/DeletePackageHelperTest.kt +++ b/services/tests/mockingservicestests/src/com/android/server/pm/DeletePackageHelperTest.kt @@ -69,13 +69,34 @@ class DeletePackageHelperTest { } @Test - fun deleteSystemPackageFailsIfNotAdmin() { + fun deleteSystemPackageFailsIfNotAdminAndNotProfile() { val ps = mPms.mSettings.getPackageLPr("a.data.package") whenever(PackageManagerServiceUtils.isSystemApp(ps)).thenReturn(true) whenever(mUserManagerInternal.getUserInfo(1)).thenReturn(UserInfo(1, "test", 0)) + whenever(mUserManagerInternal.getProfileParentId(1)).thenReturn(1) val dph = DeletePackageHelper(mPms) - val result = dph.deletePackageX("a.data.package", 1L, 1, 0, false) + val result = dph.deletePackageX("a.data.package", 1L, 1, + PackageManager.DELETE_SYSTEM_APP, false) + + assertThat(result).isEqualTo(PackageManager.DELETE_FAILED_USER_RESTRICTED) + } + + @Test + fun deleteSystemPackageFailsIfProfileOfNonAdmin() { + val userId = 1 + val parentId = 5 + val ps = mPms.mSettings.getPackageLPr("a.data.package") + whenever(PackageManagerServiceUtils.isSystemApp(ps)).thenReturn(true) + whenever(mUserManagerInternal.getUserInfo(userId)).thenReturn( + UserInfo(userId, "test", UserInfo.FLAG_PROFILE)) + whenever(mUserManagerInternal.getProfileParentId(userId)).thenReturn(parentId) + whenever(mUserManagerInternal.getUserInfo(parentId)).thenReturn( + UserInfo(userId, "testparent", 0)) + + val dph = DeletePackageHelper(mPms) + val result = dph.deletePackageX("a.data.package", 1L, userId, + PackageManager.DELETE_SYSTEM_APP, false) assertThat(result).isEqualTo(PackageManager.DELETE_FAILED_USER_RESTRICTED) } @@ -93,4 +114,23 @@ class DeletePackageHelperTest { assertThat(result).isEqualTo(PackageManager.DELETE_SUCCEEDED) } + + @Test + fun deleteSystemPackageSucceedsIfProfileOfAdmin() { + val userId = 1 + val parentId = 5 + val ps = mPms.mSettings.getPackageLPr("a.data.package") + whenever(PackageManagerServiceUtils.isSystemApp(ps)).thenReturn(true) + whenever(mUserManagerInternal.getUserInfo(userId)).thenReturn( + UserInfo(userId, "test", UserInfo.FLAG_PROFILE)) + whenever(mUserManagerInternal.getProfileParentId(userId)).thenReturn(parentId) + whenever(mUserManagerInternal.getUserInfo(parentId)).thenReturn( + UserInfo(userId, "testparent", UserInfo.FLAG_ADMIN)) + + val dph = DeletePackageHelper(mPms) + val result = dph.deletePackageX("a.data.package", 1L, userId, + PackageManager.DELETE_SYSTEM_APP, false) + + assertThat(result).isEqualTo(PackageManager.DELETE_SUCCEEDED) + } } \ No newline at end of file