summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/res/res/values/attrs_manifest.xml3
-rw-r--r--services/core/java/com/android/server/uri/UriGrantsManagerService.java50
2 files changed, 47 insertions, 6 deletions
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 47410125fd65..340368a108b0 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -3287,7 +3287,8 @@
{@link java.lang.SecurityException}.
<p> Note that the enforcement works for content URIs inside
- {@link android.content.Intent#getData} and {@link android.content.Intent#getClipData}.
+ {@link android.content.Intent#getData}, {@link android.content.Intent#EXTRA_STREAM},
+ and {@link android.content.Intent#getClipData}.
@FlaggedApi("android.security.content_uri_permission_apis") -->
<attr name="requireContentUriPermissionFromCaller" format="string">
<!-- Default, no specific permissions are required. -->
diff --git a/services/core/java/com/android/server/uri/UriGrantsManagerService.java b/services/core/java/com/android/server/uri/UriGrantsManagerService.java
index d2f6701e313e..4af8c616b2bc 100644
--- a/services/core/java/com/android/server/uri/UriGrantsManagerService.java
+++ b/services/core/java/com/android/server/uri/UriGrantsManagerService.java
@@ -65,6 +65,7 @@ import android.content.pm.ParceledListSlice;
import android.content.pm.PathPermission;
import android.content.pm.ProviderInfo;
import android.net.Uri;
+import android.os.BadParcelableException;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
@@ -630,16 +631,24 @@ public class UriGrantsManagerService extends IUriGrantsManager.Stub implements
if (intent == null) {
return null;
}
- Uri data = intent.getData();
- ClipData clip = intent.getClipData();
- if (data == null && clip == null) {
- return null;
- }
+
// Default userId for uris in the intent (if they don't specify it themselves)
int contentUserHint = intent.getContentUserHint();
if (contentUserHint == UserHandle.USER_CURRENT) {
contentUserHint = UserHandle.getUserId(callingUid);
}
+
+ if (android.security.Flags.contentUriPermissionApis()) {
+ enforceRequireContentUriPermissionFromCallerOnIntentExtraStream(intent, contentUserHint,
+ mode, callingUid, requireContentUriPermissionFromCaller);
+ }
+
+ Uri data = intent.getData();
+ ClipData clip = intent.getClipData();
+ if (data == null && clip == null) {
+ return null;
+ }
+
int targetUid;
if (needed != null) {
targetUid = needed.targetUid;
@@ -733,6 +742,37 @@ public class UriGrantsManagerService extends IUriGrantsManager.Stub implements
}
}
+ private void enforceRequireContentUriPermissionFromCallerOnIntentExtraStream(Intent intent,
+ int contentUserHint, int mode, int callingUid,
+ @RequiredContentUriPermission Integer requireContentUriPermissionFromCaller) {
+ try {
+ final Uri uri = intent.getParcelableExtra(Intent.EXTRA_STREAM, Uri.class);
+ if (uri != null) {
+ final GrantUri grantUri = GrantUri.resolve(contentUserHint, uri, mode);
+ enforceRequireContentUriPermissionFromCaller(
+ requireContentUriPermissionFromCaller, grantUri, callingUid);
+ }
+ } catch (BadParcelableException e) {
+ Slog.w(TAG, "Failed to unparcel an URI in EXTRA_STREAM, skipping"
+ + " requireContentUriPermissionFromCaller: " + e);
+ }
+
+ try {
+ final ArrayList<Uri> uris = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM,
+ Uri.class);
+ if (uris != null) {
+ for (int i = uris.size() - 1; i >= 0; i--) {
+ final GrantUri grantUri = GrantUri.resolve(contentUserHint, uris.get(i), mode);
+ enforceRequireContentUriPermissionFromCaller(
+ requireContentUriPermissionFromCaller, grantUri, callingUid);
+ }
+ }
+ } catch (BadParcelableException e) {
+ Slog.w(TAG, "Failed to unparcel an ArrayList of URIs in EXTRA_STREAM, skipping"
+ + " requireContentUriPermissionFromCaller: " + e);
+ }
+ }
+
@GuardedBy("mLock")
private void readGrantedUriPermissionsLocked() {
if (DEBUG) Slog.v(TAG, "readGrantedUriPermissions()");