summaryrefslogtreecommitdiffstats
path: root/core/java/android
diff options
context:
space:
mode:
authorJeff Sharkey <jsharkey@android.com>2013-09-04 14:30:31 -0700
committerJeff Sharkey <jsharkey@android.com>2013-09-04 18:43:34 -0700
commite37ea6123d1aa3cd3e8804988886b1f6046d79d6 (patch)
tree1fee5a31a764f5aaa5228dd13e8add9924eeacc1 /core/java/android
parent954be0232655d316bc5decbbd35579af902c75c2 (diff)
downloadframeworks_base-e37ea6123d1aa3cd3e8804988886b1f6046d79d6.zip
frameworks_base-e37ea6123d1aa3cd3e8804988886b1f6046d79d6.tar.gz
frameworks_base-e37ea6123d1aa3cd3e8804988886b1f6046d79d6.tar.bz2
Fix document management permission enforcement.
Allow both explicit holders of the MANAGE_DOCUMENTS permission and those holding Uri grants to perform management tasks. Extend grants for newly created documents when caller doesn't have permission. Revoke grants when deleting documents. Test now writes actual content into picked file. Workaround updated flags for Drive app. Bug: 10623211 Change-Id: Ia8e90b33e0fac8294b2cacb96d083c43fdf75aab
Diffstat (limited to 'core/java/android')
-rw-r--r--core/java/android/provider/DocumentsProvider.java38
1 files changed, 31 insertions, 7 deletions
diff --git a/core/java/android/provider/DocumentsProvider.java b/core/java/android/provider/DocumentsProvider.java
index 09f4866..07cb2a9 100644
--- a/core/java/android/provider/DocumentsProvider.java
+++ b/core/java/android/provider/DocumentsProvider.java
@@ -28,11 +28,13 @@ import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.UriMatcher;
+import android.content.pm.PackageManager;
import android.content.pm.ProviderInfo;
import android.content.res.AssetFileDescriptor;
import android.database.Cursor;
import android.graphics.Point;
import android.net.Uri;
+import android.os.Binder;
import android.os.Bundle;
import android.os.CancellationSignal;
import android.os.ParcelFileDescriptor;
@@ -40,6 +42,8 @@ import android.os.ParcelFileDescriptor.OnCloseListener;
import android.provider.DocumentsContract.Document;
import android.util.Log;
+import com.android.internal.util.ArrayUtils;
+
import libcore.io.IoUtils;
import java.io.FileNotFoundException;
@@ -328,16 +332,24 @@ public abstract class DocumentsProvider extends ContentProvider {
@Override
public final Bundle callFromPackage(
String callingPackage, String method, String arg, Bundle extras) {
+ final Context context = getContext();
+
if (!method.startsWith("android:")) {
// Let non-platform methods pass through
return super.callFromPackage(callingPackage, method, arg, extras);
}
- // Require that caller can manage given document
final String documentId = extras.getString(Document.COLUMN_DOCUMENT_ID);
final Uri documentUri = DocumentsContract.buildDocumentUri(mAuthority, documentId);
- getContext().enforceCallingOrSelfUriPermission(
- documentUri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION, method);
+
+ // Require that caller can manage given document
+ final boolean callerHasManage =
+ context.checkCallingOrSelfPermission(android.Manifest.permission.MANAGE_DOCUMENTS)
+ == PackageManager.PERMISSION_GRANTED;
+ if (!callerHasManage) {
+ getContext().enforceCallingOrSelfUriPermission(
+ documentUri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION, method);
+ }
final Bundle out = new Bundle();
try {
@@ -345,14 +357,26 @@ public abstract class DocumentsProvider extends ContentProvider {
final String mimeType = extras.getString(Document.COLUMN_MIME_TYPE);
final String displayName = extras.getString(Document.COLUMN_DISPLAY_NAME);
- // TODO: issue Uri grant towards calling package
- // TODO: enforce that package belongs to caller
final String newDocumentId = createDocument(documentId, mimeType, displayName);
out.putString(Document.COLUMN_DOCUMENT_ID, newDocumentId);
+ // Extend permission grant towards caller if needed
+ if (!callerHasManage) {
+ final Uri newDocumentUri = DocumentsContract.buildDocumentUri(
+ mAuthority, newDocumentId);
+ context.grantUriPermission(callingPackage, newDocumentUri,
+ Intent.FLAG_GRANT_READ_URI_PERMISSION
+ | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
+ | Intent.FLAG_PERSIST_GRANT_URI_PERMISSION);
+ }
+
} else if (METHOD_DELETE_DOCUMENT.equals(method)) {
- final String docId = extras.getString(Document.COLUMN_DOCUMENT_ID);
- deleteDocument(docId);
+ deleteDocument(documentId);
+
+ // Document no longer exists, clean up any grants
+ context.revokeUriPermission(documentUri, Intent.FLAG_GRANT_READ_URI_PERMISSION
+ | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
+ | Intent.FLAG_PERSIST_GRANT_URI_PERMISSION);
} else {
throw new UnsupportedOperationException("Method not supported " + method);