Fix cross user package visibility leakage for PackageManager (7/n)
For APIs: - PackageManager#clearApplicationUserData - PackageManager#getProperty - PackageManager#getPermissionControllerPackageName - PackageManager#setApplicationCategoryHint - PackageManager#getUnsuspendablePackages - PackageManager#setApplicationHiddenSettingAsUser Bug: 229684723 Test: atest CrossUserPackageVisibilityTests Change-Id: I70a20b4c41c870a160e808ee9707a6ec1a2da6e6
This commit is contained in:
@@ -387,12 +387,12 @@ public interface Computer extends PackageDataSnapshot {
|
||||
String[] getSystemSharedLibraryNames();
|
||||
|
||||
/**
|
||||
* @return the state if the given package has a state and isn't filtered by visibility.
|
||||
* @return the state if the given package is installed and isn't filtered by visibility.
|
||||
* Provides no guarantee that the package is in any usable state.
|
||||
*/
|
||||
@Nullable
|
||||
PackageStateInternal getPackageStateFiltered(@NonNull String packageName, int callingUid,
|
||||
@UserIdInt int userId);
|
||||
PackageStateInternal getPackageStateForInstalledAndFiltered(@NonNull String packageName,
|
||||
int callingUid, @UserIdInt int userId);
|
||||
|
||||
int checkSignatures(@NonNull String pkg1, @NonNull String pkg2, int userId);
|
||||
|
||||
|
||||
@@ -4238,10 +4238,11 @@ public class ComputerEngine implements Computer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public PackageStateInternal getPackageStateFiltered(@NonNull String packageName, int callingUid,
|
||||
@UserIdInt int userId) {
|
||||
public PackageStateInternal getPackageStateForInstalledAndFiltered(@NonNull String packageName,
|
||||
int callingUid, @UserIdInt int userId) {
|
||||
final PackageStateInternal packageState = getPackageStateInternal(packageName);
|
||||
if (packageState == null || shouldFilterApplication(packageState, callingUid, userId)) {
|
||||
if (packageState == null
|
||||
|| shouldFilterApplicationIncludingUninstalled(packageState, callingUid, userId)) {
|
||||
return null;
|
||||
}
|
||||
return packageState;
|
||||
|
||||
@@ -715,8 +715,8 @@ public abstract class IPackageManagerBase extends IPackageManager.Stub {
|
||||
String className) {
|
||||
Objects.requireNonNull(propertyName);
|
||||
Objects.requireNonNull(packageName);
|
||||
PackageStateInternal packageState = snapshot().getPackageStateFiltered(packageName,
|
||||
Binder.getCallingUid(), UserHandle.getCallingUserId());
|
||||
PackageStateInternal packageState = snapshot().getPackageStateForInstalledAndFiltered(
|
||||
packageName, Binder.getCallingUid(), UserHandle.getCallingUserId());
|
||||
if (packageState == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -4461,7 +4461,8 @@ public class PackageManagerService implements PackageSender, TestUtilityService
|
||||
snapshot.enforceCrossUserPermission(callingUid, userId, true /* requireFullPermission */,
|
||||
false /* checkShell */, "clear application data");
|
||||
|
||||
if (snapshot.getPackageStateFiltered(packageName, callingUid, userId) == null) {
|
||||
if (snapshot.getPackageStateForInstalledAndFiltered(
|
||||
packageName, callingUid, userId) == null) {
|
||||
if (observer != null) {
|
||||
mHandler.post(() -> {
|
||||
try {
|
||||
@@ -4918,9 +4919,10 @@ public class PackageManagerService implements PackageSender, TestUtilityService
|
||||
@Override
|
||||
public String getPermissionControllerPackageName() {
|
||||
final int callingUid = Binder.getCallingUid();
|
||||
final int callingUserId = UserHandle.getUserId(callingUid);
|
||||
final Computer snapshot = snapshotComputer();
|
||||
if (snapshot.getPackageStateFiltered(mRequiredPermissionControllerPackage,
|
||||
callingUid, UserHandle.getUserId(callingUid)) != null) {
|
||||
if (snapshot.getPackageStateForInstalledAndFiltered(
|
||||
mRequiredPermissionControllerPackage, callingUid, callingUserId) != null) {
|
||||
return mRequiredPermissionControllerPackage;
|
||||
}
|
||||
|
||||
@@ -4943,7 +4945,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService
|
||||
snapshot.enforceCrossUserPermission(
|
||||
callingUid, userId, false /* requireFullPermission */,
|
||||
false /* checkShell */, "getSplashScreenTheme");
|
||||
PackageStateInternal packageState = filterPackageStateForInstalledAndFiltered(snapshot,
|
||||
PackageStateInternal packageState = snapshot.getPackageStateForInstalledAndFiltered(
|
||||
packageName, callingUid, userId);
|
||||
return packageState == null ? null
|
||||
: packageState.getUserStateOrDefault(userId).getSplashScreenTheme();
|
||||
@@ -5350,8 +5352,8 @@ public class PackageManagerService implements PackageSender, TestUtilityService
|
||||
mInjector.getSystemService(AppOpsManager.class)
|
||||
.checkPackage(Binder.getCallingUid(), callerPackageName);
|
||||
|
||||
PackageStateInternal packageState = computer.getPackageStateFiltered(packageName,
|
||||
Binder.getCallingUid(), UserHandle.getCallingUserId());
|
||||
PackageStateInternal packageState = computer.getPackageStateForInstalledAndFiltered(
|
||||
packageName, Binder.getCallingUid(), UserHandle.getCallingUserId());
|
||||
if (packageState == null) {
|
||||
throw new IllegalArgumentException("Unknown target package " + packageName);
|
||||
}
|
||||
@@ -5420,7 +5422,8 @@ public class PackageManagerService implements PackageSender, TestUtilityService
|
||||
final long callingId = Binder.clearCallingIdentity();
|
||||
try {
|
||||
final PackageStateInternal packageState =
|
||||
snapshot.getPackageStateFiltered(packageName, callingUid, userId);
|
||||
snapshot.getPackageStateForInstalledAndFiltered(
|
||||
packageName, callingUid, userId);
|
||||
if (packageState == null) {
|
||||
return false;
|
||||
}
|
||||
@@ -5823,7 +5826,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService
|
||||
false /* checkShell */, "setSplashScreenTheme");
|
||||
enforceOwnerRights(snapshot, packageName, callingUid);
|
||||
|
||||
PackageStateInternal packageState = filterPackageStateForInstalledAndFiltered(snapshot,
|
||||
PackageStateInternal packageState = snapshot.getPackageStateForInstalledAndFiltered(
|
||||
packageName, callingUid, userId);
|
||||
if (packageState == null) {
|
||||
return;
|
||||
@@ -6395,7 +6398,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService
|
||||
public boolean registerInstalledLoadingProgressCallback(String packageName,
|
||||
PackageManagerInternal.InstalledLoadingProgressCallback callback, int userId) {
|
||||
final Computer snapshot = snapshotComputer();
|
||||
final PackageStateInternal ps = filterPackageStateForInstalledAndFiltered(snapshot,
|
||||
final PackageStateInternal ps = snapshot.getPackageStateForInstalledAndFiltered(
|
||||
packageName, Binder.getCallingUid(), userId);
|
||||
if (ps == null) {
|
||||
return false;
|
||||
@@ -6418,7 +6421,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService
|
||||
public IncrementalStatesInfo getIncrementalStatesInfo(
|
||||
@NonNull String packageName, int filterCallingUid, int userId) {
|
||||
final Computer snapshot = snapshotComputer();
|
||||
final PackageStateInternal ps = filterPackageStateForInstalledAndFiltered(snapshot,
|
||||
final PackageStateInternal ps = snapshot.getPackageStateForInstalledAndFiltered(
|
||||
packageName, filterCallingUid, userId);
|
||||
if (ps == null) {
|
||||
return null;
|
||||
@@ -6592,20 +6595,6 @@ public class PackageManagerService implements PackageSender, TestUtilityService
|
||||
return mSettings.getDisabledSystemPkgLPr(packageName);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private PackageStateInternal filterPackageStateForInstalledAndFiltered(
|
||||
@NonNull Computer computer, @NonNull String packageName, int callingUid,
|
||||
@UserIdInt int userId) {
|
||||
PackageStateInternal packageState =
|
||||
computer.getPackageStateInternal(packageName, callingUid);
|
||||
if (computer.shouldFilterApplicationIncludingUninstalled(
|
||||
packageState, callingUid, userId)) {
|
||||
return null;
|
||||
} else {
|
||||
return packageState;
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
void forEachPackageSetting(Consumer<PackageSetting> actionLocked) {
|
||||
synchronized (mLock) {
|
||||
|
||||
@@ -228,7 +228,8 @@ public final class SuspendPackageHelper {
|
||||
continue;
|
||||
}
|
||||
final PackageStateInternal packageState =
|
||||
snapshot.getPackageStateFiltered(packageNames[i], callingUid, userId);
|
||||
snapshot.getPackageStateForInstalledAndFiltered(
|
||||
packageNames[i], callingUid, userId);
|
||||
if (packageState == null) {
|
||||
Slog.w(TAG, "Could not find package setting for package: " + packageNames[i]);
|
||||
unactionablePackages.add(packageNames[i]);
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package com.android.server.pm.test.appenumeration;
|
||||
|
||||
import static android.Manifest.permission.CLEAR_APP_USER_DATA;
|
||||
|
||||
import static com.android.compatibility.common.util.ShellUtils.runShellCommand;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
@@ -25,10 +27,12 @@ import static org.junit.Assert.assertThrows;
|
||||
import android.app.AppGlobals;
|
||||
import android.app.Instrumentation;
|
||||
import android.content.Context;
|
||||
import android.content.pm.IPackageDataObserver;
|
||||
import android.content.pm.IPackageManager;
|
||||
import android.content.pm.KeySet;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Process;
|
||||
import android.os.RemoteException;
|
||||
import android.os.UserHandle;
|
||||
|
||||
import androidx.test.platform.app.InstrumentationRegistry;
|
||||
@@ -37,6 +41,7 @@ import com.android.bedstead.harrier.BedsteadJUnit4;
|
||||
import com.android.bedstead.harrier.DeviceState;
|
||||
import com.android.bedstead.harrier.annotations.EnsureHasSecondaryUser;
|
||||
import com.android.bedstead.nene.users.UserReference;
|
||||
import com.android.compatibility.common.util.TestUtils;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
@@ -46,6 +51,7 @@ import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* Verify that app without holding the {@link android.Manifest.permission.INTERACT_ACROSS_USERS}
|
||||
@@ -65,6 +71,8 @@ public class CrossUserPackageVisibilityTests {
|
||||
private static final File SHARED_USER_TEST_APK_FILE =
|
||||
new File(TEST_DATA_DIR, "AppEnumerationSharedUserTestApp.apk");
|
||||
|
||||
private static final long DEFAULT_TIMEOUT_MS = 5000;
|
||||
|
||||
@ClassRule
|
||||
@Rule
|
||||
public static final DeviceState sDeviceState = new DeviceState();
|
||||
@@ -99,6 +107,7 @@ public class CrossUserPackageVisibilityTests {
|
||||
public void tearDown() {
|
||||
uninstallPackage(CROSS_USER_TEST_PACKAGE_NAME);
|
||||
uninstallPackage(SHARED_USER_TEST_PACKAGE_NAME);
|
||||
mInstrumentation.getUiAutomation().dropShellPermissionIdentity();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -184,6 +193,34 @@ public class CrossUserPackageVisibilityTests {
|
||||
.isEqualTo(Process.INVALID_UID);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClearApplicationUserData_cannotDetectStubPkg() throws Exception {
|
||||
mInstrumentation.getUiAutomation().adoptShellPermissionIdentity(CLEAR_APP_USER_DATA);
|
||||
assertThat(clearApplicationUserData(CROSS_USER_TEST_PACKAGE_NAME)).isFalse();
|
||||
|
||||
installPackageForUser(CROSS_USER_TEST_APK_FILE, mOtherUser);
|
||||
|
||||
assertThat(clearApplicationUserData(CROSS_USER_TEST_PACKAGE_NAME)).isFalse();
|
||||
}
|
||||
|
||||
private boolean clearApplicationUserData(String packageName) throws Exception {
|
||||
final AtomicInteger result = new AtomicInteger(-1);
|
||||
final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
|
||||
@Override
|
||||
public void onRemoveCompleted(String removedPkgName, boolean succeeded)
|
||||
throws RemoteException {
|
||||
if (removedPkgName.equals(packageName)) {
|
||||
result.set(succeeded ? 1 : 0);
|
||||
result.notifyAll();
|
||||
}
|
||||
}
|
||||
};
|
||||
mIPackageManager.clearApplicationUserData(packageName, localObserver, mCurrentUser.id());
|
||||
TestUtils.waitOn(result, () -> result.get() != -1, DEFAULT_TIMEOUT_MS,
|
||||
"clearApplicationUserData: " + packageName);
|
||||
return result.get() == 1;
|
||||
}
|
||||
|
||||
private static void installPackage(File apk) {
|
||||
installPackageForUser(apk, null, false /* forceQueryable */);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user