Fix cross user package visibility leakage for queryInstrumentation
Returns false for querying instrumentation APIs if the target package
does not installed in the calling user.
Also adding a user id parameter to APIs for the system modules to
specify the correct user id when querying the instrumentation.
NoNonSdkCheck: The equivalent apis are available in PackageManager.
Bug: 229684723
Test: atest CrossUserPackageVisibilityTests
Change-Id: I0798e543705cb8866231ee376e07b853b419b6f3
diff --git a/cmds/am/src/com/android/commands/am/Instrument.java b/cmds/am/src/com/android/commands/am/Instrument.java
index 7ff4bc4..2604497 100644
--- a/cmds/am/src/com/android/commands/am/Instrument.java
+++ b/cmds/am/src/com/android/commands/am/Instrument.java
@@ -425,7 +425,8 @@
if (cn == null) throw new IllegalArgumentException("Bad component name: " + cnArg);
return cn;
} else {
- List<InstrumentationInfo> infos = mPm.queryInstrumentation(null, 0).getList();
+ List<InstrumentationInfo> infos = mPm.queryInstrumentationAsUser(
+ null, 0, userId).getList();
final int numInfos = infos == null ? 0: infos.size();
ArrayList<ComponentName> cns = new ArrayList<>();
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 69868ab..c87f3c4 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -6863,9 +6863,12 @@
private InstrumentationInfo prepareInstrumentation(AppBindData data) {
final InstrumentationInfo ii;
try {
- ii = new ApplicationPackageManager(null, getPackageManager())
- .getInstrumentationInfo(data.instrumentationName, 0);
- } catch (PackageManager.NameNotFoundException e) {
+ ii = getPackageManager().getInstrumentationInfoAsUser(data.instrumentationName,
+ 0 /* flags */, UserHandle.myUserId());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ if (ii == null) {
throw new RuntimeException(
"Unable to find instrumentation info for: " + data.instrumentationName);
}
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index e9ebd72..fea3027 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -1695,8 +1695,8 @@
ComponentName className, int flags)
throws NameNotFoundException {
try {
- InstrumentationInfo ii = mPM.getInstrumentationInfo(
- className, flags);
+ InstrumentationInfo ii = mPM.getInstrumentationInfoAsUser(
+ className, flags, getUserId());
if (ii != null) {
return ii;
}
@@ -1713,7 +1713,7 @@
String targetPackage, int flags) {
try {
ParceledListSlice<InstrumentationInfo> parceledList =
- mPM.queryInstrumentation(targetPackage, flags);
+ mPM.queryInstrumentationAsUser(targetPackage, flags, getUserId());
if (parceledList == null) {
return Collections.emptyList();
}
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 6bb7e3e..1b1143a 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -201,13 +201,11 @@
ParceledListSlice queryContentProviders(
String processName, int uid, long flags, String metaDataKey);
- @UnsupportedAppUsage
- InstrumentationInfo getInstrumentationInfo(
- in ComponentName className, int flags);
+ InstrumentationInfo getInstrumentationInfoAsUser(
+ in ComponentName className, int flags, int userId);
- @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
- ParceledListSlice queryInstrumentation(
- String targetPackage, int flags);
+ ParceledListSlice queryInstrumentationAsUser(
+ String targetPackage, int flags, int userId);
void finishPackageInstall(int token, boolean didLaunch);
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index b0ab89c..27f04f9 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -14528,6 +14528,7 @@
if (arguments != null && arguments.hasFileDescriptors()) {
throw new IllegalArgumentException("File descriptors passed in Bundle");
}
+ final IPackageManager pm = AppGlobals.getPackageManager();
synchronized(this) {
InstrumentationInfo ii = null;
@@ -14536,11 +14537,8 @@
boolean noRestart = (flags & INSTR_FLAG_NO_RESTART) != 0;
try {
- ii = mContext.getPackageManager().getInstrumentationInfo(
- className, STOCK_PM_FLAGS);
- ai = AppGlobals.getPackageManager().getApplicationInfo(
- ii.targetPackage, STOCK_PM_FLAGS, userId);
- } catch (PackageManager.NameNotFoundException e) {
+ ii = pm.getInstrumentationInfoAsUser(className, STOCK_PM_FLAGS, userId);
+ ai = pm.getApplicationInfo(ii.targetPackage, STOCK_PM_FLAGS, userId);
} catch (RemoteException e) {
}
if (ii == null) {
@@ -14568,8 +14566,7 @@
int match = SIGNATURE_NO_MATCH;
try {
- match = AppGlobals.getPackageManager().checkSignatures(
- ii.targetPackage, ii.packageName, userId);
+ match = pm.checkSignatures(ii.targetPackage, ii.packageName, userId);
} catch (RemoteException e) {
}
if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
diff --git a/services/core/java/com/android/server/pm/Computer.java b/services/core/java/com/android/server/pm/Computer.java
index dfe06cf..33e9b2f 100644
--- a/services/core/java/com/android/server/pm/Computer.java
+++ b/services/core/java/com/android/server/pm/Computer.java
@@ -452,11 +452,12 @@
@PackageManager.ComponentInfoFlagsBits long flags, @Nullable String metaDataKey);
@Nullable
- InstrumentationInfo getInstrumentationInfo(@NonNull ComponentName component, int flags);
+ InstrumentationInfo getInstrumentationInfoAsUser(@NonNull ComponentName component, int flags,
+ int userId);
@NonNull
- ParceledListSlice<InstrumentationInfo> queryInstrumentation(
- @NonNull String targetPackage, int flags);
+ ParceledListSlice<InstrumentationInfo> queryInstrumentationAsUser(
+ @NonNull String targetPackage, int flags, int userId);
@NonNull
List<PackageStateInternal> findSharedNonSystemLibraries(
diff --git a/services/core/java/com/android/server/pm/ComputerEngine.java b/services/core/java/com/android/server/pm/ComputerEngine.java
index 45a139d..ad0b455 100644
--- a/services/core/java/com/android/server/pm/ComputerEngine.java
+++ b/services/core/java/com/android/server/pm/ComputerEngine.java
@@ -4927,32 +4927,33 @@
@Nullable
@Override
- public InstrumentationInfo getInstrumentationInfo(@NonNull ComponentName component, int flags) {
+ public InstrumentationInfo getInstrumentationInfoAsUser(@NonNull ComponentName component,
+ int flags, int userId) {
final int callingUid = Binder.getCallingUid();
- final int callingUserId = UserHandle.getUserId(callingUid);
+ enforceCrossUserPermission(callingUid, userId, false /* requireFullPermission */,
+ false /* checkShell */, "getInstrumentationInfoAsUser");
+ if (!mUserManager.exists(userId)) return null;
String packageName = component.getPackageName();
final PackageStateInternal ps = mSettings.getPackage(packageName);
AndroidPackage pkg = mPackages.get(packageName);
if (ps == null || pkg == null) return null;
if (shouldFilterApplication(
- ps, callingUid, component, TYPE_UNKNOWN, callingUserId)) {
+ ps, callingUid, component, TYPE_UNKNOWN, userId)) {
return null;
}
final ParsedInstrumentation i = mInstrumentation.get(component);
- return PackageInfoUtils.generateInstrumentationInfo(i, pkg, flags, callingUserId, ps);
+ final PackageUserStateInternal state = ps.getUserStateOrDefault(userId);
+ return PackageInfoUtils.generateInstrumentationInfo(i, pkg, flags, state, userId, ps);
}
@NonNull
@Override
- public ParceledListSlice<InstrumentationInfo> queryInstrumentation(
- @NonNull String targetPackage, int flags) {
+ public ParceledListSlice<InstrumentationInfo> queryInstrumentationAsUser(
+ @NonNull String targetPackage, int flags, int userId) {
final int callingUid = Binder.getCallingUid();
- final int callingUserId = UserHandle.getUserId(callingUid);
- final PackageStateInternal ps = mSettings.getPackage(targetPackage);
- if (shouldFilterApplication(ps, callingUid, callingUserId)) {
- return ParceledListSlice.emptyList();
- }
-
+ enforceCrossUserPermission(callingUid, userId, false /* requireFullPermission */,
+ false /* checkShell */, "queryInstrumentationAsUser");
+ if (!mUserManager.exists(userId)) return ParceledListSlice.emptyList();
ArrayList<InstrumentationInfo> finalList = new ArrayList<>();
final int numInstrumentations = mInstrumentation.size();
@@ -4963,12 +4964,15 @@
String packageName = p.getPackageName();
AndroidPackage pkg = mPackages.get(packageName);
PackageStateInternal pkgSetting = getPackageStateInternal(packageName);
- if (pkg != null) {
- InstrumentationInfo ii = PackageInfoUtils.generateInstrumentationInfo(p,
- pkg, flags, callingUserId, pkgSetting);
- if (ii != null) {
- finalList.add(ii);
- }
+ if (pkg == null || pkgSetting == null
+ || shouldFilterApplication(pkgSetting, callingUid, userId)) {
+ continue;
+ }
+ final PackageUserStateInternal state = pkgSetting.getUserStateOrDefault(userId);
+ InstrumentationInfo ii = PackageInfoUtils.generateInstrumentationInfo(p,
+ pkg, flags, state, userId, pkgSetting);
+ if (ii != null) {
+ finalList.add(ii);
}
}
}
diff --git a/services/core/java/com/android/server/pm/IPackageManagerBase.java b/services/core/java/com/android/server/pm/IPackageManagerBase.java
index 3754131..c16071d 100644
--- a/services/core/java/com/android/server/pm/IPackageManagerBase.java
+++ b/services/core/java/com/android/server/pm/IPackageManagerBase.java
@@ -533,9 +533,9 @@
@Nullable
@Override
@Deprecated
- public final InstrumentationInfo getInstrumentationInfo(@NonNull ComponentName component,
- int flags) {
- return snapshot().getInstrumentationInfo(component, flags);
+ public final InstrumentationInfo getInstrumentationInfoAsUser(@NonNull ComponentName component,
+ int flags, int userId) {
+ return snapshot().getInstrumentationInfoAsUser(component, flags, userId);
}
@Override
@@ -1017,9 +1017,9 @@
@NonNull
@Override
@Deprecated
- public final ParceledListSlice<InstrumentationInfo> queryInstrumentation(
- @NonNull String targetPackage, int flags) {
- return snapshot().queryInstrumentation(targetPackage, flags);
+ public final ParceledListSlice<InstrumentationInfo> queryInstrumentationAsUser(
+ @NonNull String targetPackage, int flags, int userId) {
+ return snapshot().queryInstrumentationAsUser(targetPackage, flags, userId);
}
@Override
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index f5981e2..5906c3f 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -788,7 +788,9 @@
}
final List<InstrumentationInfo> list =
- mInterface.queryInstrumentation(targetPackage, 0 /*flags*/).getList();
+ mInterface.queryInstrumentationAsUser(
+ targetPackage, PackageManager.MATCH_KNOWN_PACKAGES, UserHandle.USER_SYSTEM)
+ .getList();
// sort by target package
Collections.sort(list, new Comparator<InstrumentationInfo>() {
diff --git a/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java b/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java
index 4f0f2a8..9c620c4 100644
--- a/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java
+++ b/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java
@@ -204,7 +204,8 @@
info.instrumentation = new InstrumentationInfo[N];
for (int i = 0; i < N; i++) {
info.instrumentation[i] = generateInstrumentationInfo(
- pkg.getInstrumentations().get(i), pkg, flags, userId, pkgSetting);
+ pkg.getInstrumentations().get(i), pkg, flags, state,
+ userId, pkgSetting);
}
}
}
@@ -363,9 +364,12 @@
*/
@Nullable
public static InstrumentationInfo generateInstrumentationInfo(ParsedInstrumentation i,
- AndroidPackage pkg, @PackageManager.ComponentInfoFlagsBits long flags, int userId,
- @Nullable PackageStateInternal pkgSetting) {
+ AndroidPackage pkg, @PackageManager.ComponentInfoFlagsBits long flags,
+ PackageUserStateInternal state, int userId, @Nullable PackageStateInternal pkgSetting) {
if (i == null) return null;
+ if (!checkUseInstalledOrHidden(pkg, pkgSetting, state, flags)) {
+ return null;
+ }
InstrumentationInfo info =
PackageInfoWithoutStateUtils.generateInstrumentationInfo(i, pkg, flags, userId,