summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Todd Kennedy <toddke@google.com> 2017-05-16 15:47:01 -0700
committer Todd Kennedy <toddke@google.com> 2017-05-16 16:13:52 -0700
commite6393c95716e5ad9bfb52931eb6e4f23f7640f01 (patch)
tree46d3bec3bf09c4d419cf372b1ad6522d73a00793
parent9e6ef496bc2cdd01576a571eff86ebce100cba54 (diff)
Filter package related info
This is one of many CLs to go through the PackageManager API surface and filter access depending upon the requested information and the caller. In this change, we filter ActivityInfo, ApplicationInfo and PackageInfo. Bug: 35871369 Test: bit FrameworksCoreTests:android.content.pm.PackageManagerTests Test: cts-tradefed run commandAndExit cts-dev -m CtsAppSecurityHostTestCases -t android.appsecurity.cts.EphemeralTest Change-Id: Iaefd73f912ab1c7e1844e72625388455f783a362
-rw-r--r--packages/SystemUI/AndroidManifest.xml3
-rw-r--r--services/core/java/com/android/server/pm/EphemeralResolverConnection.java2
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java123
3 files changed, 105 insertions, 23 deletions
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 5460304e8678..79b02a5286e0 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -187,6 +187,9 @@
<!-- to access ResolverRankerServices -->
<uses-permission android:name="android.permission.BIND_RESOLVER_RANKER_SERVICE" />
+ <!-- to access instant apps -->
+ <uses-permission android:name="android.permission.ACCESS_INSTANT_APPS" />
+
<application
android:name=".SystemUIApplication"
android:persistent="true"
diff --git a/services/core/java/com/android/server/pm/EphemeralResolverConnection.java b/services/core/java/com/android/server/pm/EphemeralResolverConnection.java
index 1de3936dce5d..562ab3319d64 100644
--- a/services/core/java/com/android/server/pm/EphemeralResolverConnection.java
+++ b/services/core/java/com/android/server/pm/EphemeralResolverConnection.java
@@ -96,7 +96,7 @@ final class EphemeralResolverConnection implements DeathRecipient {
return mGetEphemeralResolveInfoCaller
.getEphemeralResolveInfoList(target, hashPrefix, token);
} catch (TimeoutException e) {
- throw new ConnectionException(ConnectionException.FAILURE_BIND);
+ throw new ConnectionException(ConnectionException.FAILURE_CALL);
} catch (RemoteException ignore) {
}
} finally {
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 39639a2fd27a..a12b99fe5e7a 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -3510,7 +3510,7 @@ public class PackageManagerService extends IPackageManager.Stub
if (ps == null) {
return null;
}
- final PackageParser.Package p = ps.pkg;
+ PackageParser.Package p = ps.pkg;
if (p == null) {
return null;
}
@@ -3638,8 +3638,9 @@ public class PackageManagerService extends IPackageManager.Stub
private PackageInfo getPackageInfoInternal(String packageName, int versionCode,
int flags, int userId) {
if (!sUserManager.exists(userId)) return null;
+ final int callingUid = Binder.getCallingUid();
flags = updateFlagsForPackage(flags, userId, packageName);
- enforceCrossUserPermission(Binder.getCallingUid(), userId,
+ enforceCrossUserPermission(callingUid, userId,
false /* requireFullPermission */, false /* checkShell */, "get package info");
// reader
@@ -3651,7 +3652,10 @@ public class PackageManagerService extends IPackageManager.Stub
if (matchFactoryOnly) {
final PackageSetting ps = mSettings.getDisabledSystemPkgLPr(packageName);
if (ps != null) {
- if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId, flags)) {
+ if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
+ return null;
+ }
+ if (filterAppAccessLPr(ps, callingUid, userId)) {
return null;
}
return generatePackageInfo(ps, flags, userId);
@@ -3665,15 +3669,22 @@ public class PackageManagerService extends IPackageManager.Stub
if (DEBUG_PACKAGE_INFO)
Log.v(TAG, "getPackageInfo " + packageName + ": " + p);
if (p != null) {
- if (filterSharedLibPackageLPr((PackageSetting) p.mExtras,
- Binder.getCallingUid(), userId, flags)) {
+ final PackageSetting ps = (PackageSetting) p.mExtras;
+ if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
+ return null;
+ }
+ if (ps != null && filterAppAccessLPr(ps, callingUid, userId)) {
return null;
}
return generatePackageInfo((PackageSetting)p.mExtras, flags, userId);
}
if (!matchFactoryOnly && (flags & MATCH_KNOWN_PACKAGES) != 0) {
final PackageSetting ps = mSettings.mPackages.get(packageName);
- if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId, flags)) {
+ if (ps == null) return null;
+ if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
+ return null;
+ }
+ if (filterAppAccessLPr(ps, callingUid, userId)) {
return null;
}
return generatePackageInfo(ps, flags, userId);
@@ -3682,6 +3693,57 @@ public class PackageManagerService extends IPackageManager.Stub
return null;
}
+ /**
+ * Returns whether or not access to the application should be filtered.
+ * <p>
+ * Access may be limited based upon whether the calling or target applications
+ * are instant applications.
+ *
+ * @see #canAccessInstantApps(int)
+ */
+ private boolean filterAppAccessLPr(@NonNull PackageSetting ps, int callingUid,
+ @Nullable ComponentName component, boolean componentVisibleToInstantApp, int userId) {
+ // if we're in an isolated process, get the real calling UID
+ if (Process.isIsolated(callingUid)) {
+ callingUid = mIsolatedOwners.get(callingUid);
+ }
+ // if the target and caller are the same application, don't filter
+ if (isCallerSameApp(ps.name, callingUid)) {
+ return false;
+ }
+ final String instantAppPkgName = getInstantAppPackageName(callingUid);
+ final boolean callerIsInstantApp = instantAppPkgName != null;
+ if (callerIsInstantApp) {
+ // request for a specific component; if it hasn't been explicitly exposed, filter
+ if (component != null) {
+ return !componentVisibleToInstantApp;
+ }
+ // request for application; if no components have been explicitly exposed, filter
+ return !ps.pkg.visibleToInstantApps;
+ }
+ if (ps.getInstantApp(userId)) {
+ // caller can see all components of all instant applications, don't filter
+ if (canAccessInstantApps(callingUid)) {
+ return false;
+ }
+ // request for a specific instant application component, filter
+ if (component != null) {
+ return true;
+ }
+ // request for an instant application; if the caller hasn't been granted access, filter
+ return !mInstantAppRegistry.isInstantAccessGranted(
+ userId, UserHandle.getAppId(callingUid), ps.appId);
+ }
+ return false;
+ }
+
+ /**
+ * @see #filterAppAccessLPr(PackageSetting, int, ComponentName, boolean, int)
+ */
+ private boolean filterAppAccessLPr(@NonNull PackageSetting ps, int callingUid, int userId) {
+ return filterAppAccessLPr(ps, callingUid, null, false, userId);
+ }
+
private boolean filterSharedLibPackageLPr(@Nullable PackageSetting ps, int uid, int userId,
int flags) {
// Callers can access only the libs they depend on, otherwise they need to explicitly
@@ -3890,6 +3952,9 @@ public class PackageManagerService extends IPackageManager.Stub
if (filterSharedLibPackageLPr(ps, uid, userId, flags)) {
return null;
}
+ if (filterAppAccessLPr(ps, uid, userId)) {
+ return null;
+ }
if (ps.pkg == null) {
final PackageInfo pInfo = generatePackageInfo(ps, flags, userId);
if (pInfo != null) {
@@ -3931,6 +3996,9 @@ public class PackageManagerService extends IPackageManager.Stub
if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId, flags)) {
return null;
}
+ if (filterAppAccessLPr(ps, Binder.getCallingUid(), userId)) {
+ return null;
+ }
// Note: isEnabledLP() does not apply here - always return info
ApplicationInfo ai = PackageParser.generateApplicationInfo(
p, flags, ps.readUserState(userId), userId);
@@ -4230,15 +4298,15 @@ public class PackageManagerService extends IPackageManager.Stub
*/
int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid) {
return updateFlagsForResolve(flags, userId, intent, callingUid,
- false /*includeInstantApps*/, false /*onlyExposedExplicitly*/);
+ false /*wantInstantApps*/, false /*onlyExposedExplicitly*/);
}
int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid,
- boolean includeInstantApps) {
+ boolean wantInstantApps) {
return updateFlagsForResolve(flags, userId, intent, callingUid,
- includeInstantApps, false /*onlyExposedExplicitly*/);
+ wantInstantApps, false /*onlyExposedExplicitly*/);
}
int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid,
- boolean includeInstantApps, boolean onlyExposedExplicitly) {
+ boolean wantInstantApps, boolean onlyExposedExplicitly) {
// Safe mode means we shouldn't match any third-party components
if (mSafeMode) {
flags |= PackageManager.MATCH_SYSTEM_ONLY;
@@ -4251,18 +4319,11 @@ public class PackageManagerService extends IPackageManager.Stub
flags |= PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY;
flags |= PackageManager.MATCH_INSTANT;
} else {
- // Otherwise, prevent leaking ephemeral components
- final boolean isSpecialProcess =
- callingUid == Process.SYSTEM_UID
- || callingUid == Process.SHELL_UID
- || callingUid == 0;
final boolean allowMatchInstant =
- (includeInstantApps
+ (wantInstantApps
&& Intent.ACTION_VIEW.equals(intent.getAction())
&& hasWebURI(intent))
- || isSpecialProcess
- || mContext.checkCallingOrSelfPermission(
- android.Manifest.permission.ACCESS_INSTANT_APPS) == PERMISSION_GRANTED;
+ || canAccessInstantApps(callingUid);
flags &= ~(PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY
| PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY);
if (!allowMatchInstant) {
@@ -4293,8 +4354,9 @@ public class PackageManagerService extends IPackageManager.Stub
@Override
public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
if (!sUserManager.exists(userId)) return null;
+ final int callingUid = Binder.getCallingUid();
flags = updateFlagsForComponent(flags, userId, component);
- enforceCrossUserPermission(Binder.getCallingUid(), userId,
+ enforceCrossUserPermission(callingUid, userId,
false /* requireFullPermission */, false /* checkShell */, "get activity info");
synchronized (mPackages) {
PackageParser.Activity a = mActivities.mActivities.get(component);
@@ -4303,6 +4365,11 @@ public class PackageManagerService extends IPackageManager.Stub
if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
if (ps == null) return null;
+ final boolean visibleToInstantApp =
+ (a.info.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
+ if (filterAppAccessLPr(ps, callingUid, component, visibleToInstantApp, userId)) {
+ return null;
+ }
return generateActivityInfo(a, flags, ps.readUserState(userId), userId);
}
if (mResolveComponentName.equals(component)) {
@@ -4467,8 +4534,9 @@ public class PackageManagerService extends IPackageManager.Stub
@Override
public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
if (!sUserManager.exists(userId)) return null;
+ final int callingUid = Binder.getCallingUid();
flags = updateFlagsForComponent(flags, userId, component);
- enforceCrossUserPermission(Binder.getCallingUid(), userId,
+ enforceCrossUserPermission(callingUid, userId,
false /* requireFullPermission */, false /* checkShell */, "get service info");
synchronized (mPackages) {
PackageParser.Service s = mServices.mServices.get(component);
@@ -4477,6 +4545,11 @@ public class PackageManagerService extends IPackageManager.Stub
if (s != null && mSettings.isEnabledAndMatchLPr(s.info, flags, userId)) {
PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
if (ps == null) return null;
+ final boolean visibleToInstantApp =
+ (s.info.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
+ if (filterAppAccessLPr(ps, callingUid, component, visibleToInstantApp, userId)) {
+ return null;
+ }
ServiceInfo si = PackageParser.generateServiceInfo(s, flags,
ps.readUserState(userId), userId);
if (si != null) {
@@ -4491,8 +4564,9 @@ public class PackageManagerService extends IPackageManager.Stub
@Override
public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) {
if (!sUserManager.exists(userId)) return null;
+ final int callingUid = Binder.getCallingUid();
flags = updateFlagsForComponent(flags, userId, component);
- enforceCrossUserPermission(Binder.getCallingUid(), userId,
+ enforceCrossUserPermission(callingUid, userId,
false /* requireFullPermission */, false /* checkShell */, "get provider info");
synchronized (mPackages) {
PackageParser.Provider p = mProviders.mProviders.get(component);
@@ -4501,6 +4575,11 @@ public class PackageManagerService extends IPackageManager.Stub
if (p != null && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
if (ps == null) return null;
+ final boolean visibleToInstantApp =
+ (p.info.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
+ if (filterAppAccessLPr(ps, callingUid, component, visibleToInstantApp, userId)) {
+ return null;
+ }
ProviderInfo pi = PackageParser.generateProviderInfo(p, flags,
ps.readUserState(userId), userId);
if (pi != null) {