diff options
Diffstat (limited to 'services/core/java/com/android/server/am')
-rwxr-xr-x | services/core/java/com/android/server/am/ActivityManagerService.java | 50 |
1 files changed, 50 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..3715620 100755 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -219,6 +219,7 @@ import android.os.UpdateLock; import android.os.UserHandle; import android.os.UserManager; import android.provider.Settings; +import android.provider.Downloads; import android.telecom.TelecomManager; import android.text.format.DateUtils; import android.text.format.Time; @@ -8181,6 +8182,12 @@ public final class ActivityManagerService extends ActivityManagerNative // Only inspect grants matching package if (packageName == null || perm.sourcePkg.equals(packageName) || perm.targetPkg.equals(packageName)) { + // Hacky solution as part of fixing a security bug; ignore + // grants associated with DownloadManager so we don't have + // to immediately launch it to regrant the permissions + if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority()) + && !persistable) continue; + persistChanged |= perm.revokeModes(persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); @@ -9623,6 +9630,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 +21181,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); } |