summaryrefslogtreecommitdiffstats
path: root/services/core/java/com/android/server/am
diff options
context:
space:
mode:
authorJeff Sharkey <jsharkey@android.com>2016-11-16 17:22:48 -0700
committerBrinly Taylor <brinly@brinly.me>2017-03-13 04:54:31 +0000
commitca7312891adcdfc300f2b5c07222120de52030ea (patch)
treef1ee0b95da54e7576257412be0bbe363a45b80bd /services/core/java/com/android/server/am
parentcb323c7ee808d49d5e78aa05a35a743ea7ab71f0 (diff)
downloadframeworks_base-ca7312891adcdfc300f2b5c07222120de52030ea.zip
frameworks_base-ca7312891adcdfc300f2b5c07222120de52030ea.tar.gz
frameworks_base-ca7312891adcdfc300f2b5c07222120de52030ea.tar.bz2
DO NOT MERGE: Check provider access for content changes.
For an app to either send or receive content change notifications, require that they have some level of access to the underlying provider. Without these checks, a malicious app could sniff sensitive user data from the notifications of otherwise private providers. Test: builds, boots, PoC app now fails Bug: 32555637 Change-Id: If2dcd45cb0a9f1fb3b93e39fc7b8ae9c34c2fdef (cherry picked from commit c813f5dae231bd8f01864227c5dba10d43a89249) (cherry picked from commit db57376d6ccbd4d3e39fc35aa8cfb561bbca4bac) mh0rst: Backport from android-7.1.1_r21
Diffstat (limited to 'services/core/java/com/android/server/am')
-rwxr-xr-xservices/core/java/com/android/server/am/ActivityManagerService.java43
1 files changed, 43 insertions, 0 deletions
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 23f34e6..317dea4 100755
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -9623,6 +9623,44 @@ public final class ActivityManagerService extends ActivityManagerNative
}
/**
+ * Check if the calling UID has a possible chance at accessing the provider
+ * at the given authority and user.
+ */
+ public String checkContentProviderAccess(String authority, int userId) {
+ if (userId == UserHandle.USER_ALL) {
+ mContext.enforceCallingOrSelfPermission(
+ Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
+ userId = UserHandle.getCallingUserId();
+ }
+
+ ProviderInfo cpi = null;
+ try {
+ cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
+ STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS,
+ userId);
+ } catch (RemoteException ignored) {
+ }
+ if (cpi == null) {
+ // TODO: make this an outright failure in a future platform release;
+ // until then anonymous content notifications are unprotected
+ //return "Failed to find provider " + authority + " for user " + userId;
+ return null;
+ }
+
+ ProcessRecord r = null;
+ synchronized (mPidsSelfLocked) {
+ r = mPidsSelfLocked.get(Binder.getCallingPid());
+ }
+ if (r == null) {
+ return "Failed to find PID " + Binder.getCallingPid();
+ }
+
+ synchronized (this) {
+ return checkContentProviderPermissionLocked(cpi, r, userId, true);
+ }
+ }
+
+ /**
* Check if {@link ProcessRecord} has a possible chance at accessing the
* given {@link ProviderInfo}. Final permission checking is always done
* in {@link ContentProvider}.
@@ -21136,6 +21174,11 @@ public final class ActivityManagerService extends ActivityManagerNative
private final class LocalService extends ActivityManagerInternal {
@Override
+ public String checkContentProviderAccess(String authority, int userId) {
+ return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
+ }
+
+ @Override
public void onWakefulnessChanged(int wakefulness) {
ActivityManagerService.this.onWakefulnessChanged(wakefulness);
}