diff options
| author | Jeff Sharkey <jsharkey@android.com> | 2013-09-04 14:30:31 -0700 |
|---|---|---|
| committer | Jeff Sharkey <jsharkey@android.com> | 2013-09-04 18:43:34 -0700 |
| commit | e37ea6123d1aa3cd3e8804988886b1f6046d79d6 (patch) | |
| tree | 1fee5a31a764f5aaa5228dd13e8add9924eeacc1 /core/java/android | |
| parent | 954be0232655d316bc5decbbd35579af902c75c2 (diff) | |
| download | frameworks_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.java | 38 |
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); |
