Merge "Add pkg visibility checks to all hibernation APIs"

This commit is contained in:
Kevin Han
2022-02-07 18:57:37 +00:00
committed by Android (Google) Code Review
2 changed files with 45 additions and 7 deletions

View File

@@ -235,8 +235,10 @@ public final class AppHibernationService extends SystemService {
}
final Map<String, UserLevelState> packageStates = mUserStates.get(userId);
final UserLevelState pkgState = packageStates.get(packageName);
if (pkgState == null) {
Slog.e(TAG, String.format("Package %s is not installed for user %s",
if (pkgState == null
|| !mPackageManagerInternal.canQueryPackage(
Binder.getCallingUid(), packageName)) {
Slog.e(TAG, TextUtils.formatSimple("Package %s is not installed for user %s",
packageName, userId));
return false;
}
@@ -259,7 +261,9 @@ public final class AppHibernationService extends SystemService {
"Caller does not have MANAGE_APP_HIBERNATION permission.");
synchronized (mLock) {
GlobalLevelState state = mGlobalHibernationStates.get(packageName);
if (state == null) {
if (state == null
|| !mPackageManagerInternal.canQueryPackage(
Binder.getCallingUid(), packageName)) {
// This API can be legitimately called before installation finishes as part of
// dex optimization, so we just return false here.
return false;
@@ -290,8 +294,10 @@ public final class AppHibernationService extends SystemService {
}
final Map<String, UserLevelState> packageStates = mUserStates.get(realUserId);
final UserLevelState pkgState = packageStates.get(packageName);
if (pkgState == null) {
Slog.e(TAG, String.format("Package %s is not installed for user %s",
if (pkgState == null
|| !mPackageManagerInternal.canQueryPackage(
Binder.getCallingUid(), packageName)) {
Slog.e(TAG, TextUtils.formatSimple("Package %s is not installed for user %s",
packageName, realUserId));
return;
}
@@ -340,8 +346,11 @@ public final class AppHibernationService extends SystemService {
"Caller does not have MANAGE_APP_HIBERNATION permission.");
synchronized (mLock) {
GlobalLevelState state = mGlobalHibernationStates.get(packageName);
if (state == null) {
Slog.e(TAG, String.format("Package %s is not installed for any user", packageName));
if (state == null
|| !mPackageManagerInternal.canQueryPackage(
Binder.getCallingUid(), packageName)) {
Slog.e(TAG, TextUtils.formatSimple(
"Package %s is not installed for any user", packageName));
return;
}
if (state.hibernated != isHibernating) {
@@ -378,6 +387,12 @@ public final class AppHibernationService extends SystemService {
}
Map<String, UserLevelState> userStates = mUserStates.get(userId);
for (UserLevelState state : userStates.values()) {
String packageName = state.packageName;
if (!mPackageManagerInternal.canQueryPackage(
Binder.getCallingUid(), packageName)) {
// Package is not visible to caller
continue;
}
if (state.hibernated) {
hibernatingPackages.add(state.packageName);
}

View File

@@ -248,6 +248,29 @@ public final class AppHibernationServiceTest {
assertTrue(hibernatingPackages.contains(PACKAGE_NAME_2));
}
@Test
public void testGetHibernatingPackagesForUser_doesNotReturnPackagesThatArentVisible()
throws RemoteException {
// GIVEN an unlocked user with all packages installed but only some are visible to the
// caller
UserInfo userInfo =
addUser(USER_ID_2, new String[]{PACKAGE_NAME_1, PACKAGE_NAME_2, PACKAGE_NAME_3});
doReturn(false).when(mPackageManagerInternal).canQueryPackage(anyInt(), eq(PACKAGE_NAME_2));
doReturn(true).when(mUserManager).isUserUnlockingOrUnlocked(USER_ID_2);
mAppHibernationService.onUserUnlocking(new SystemService.TargetUser(userInfo));
// WHEN packages are hibernated for the user
mAppHibernationService.setHibernatingForUser(PACKAGE_NAME_1, USER_ID_2, true);
mAppHibernationService.setHibernatingForUser(PACKAGE_NAME_2, USER_ID_2, true);
// THEN the hibernating packages returned does not contain the package that was not visible
List<String> hibernatingPackages =
mAppHibernationService.getHibernatingPackagesForUser(USER_ID_2);
assertEquals(1, hibernatingPackages.size());
assertTrue(hibernatingPackages.contains(PACKAGE_NAME_1));
assertFalse(hibernatingPackages.contains(PACKAGE_NAME_2));
}
@Test
public void testUserLevelStatesInitializedFromDisk() throws RemoteException {
// GIVEN states stored on disk that match with package manager's force-stop states