diff options
author | Jeff Sharkey <jsharkey@android.com> | 2016-09-16 17:06:48 -0600 |
---|---|---|
committer | Jeff Sharkey <jsharkey@android.com> | 2016-09-16 17:06:48 -0600 |
commit | 1d0dcb200d466cd4b03f65fa03f16c7944a0b6c1 (patch) | |
tree | 42776831a9f277f9dd9c119bbcdf085ff3d8381e /src/com/android/providers/downloads | |
parent | 85a6e20a85c4c1d2fb8167b4572230c6fdccfb38 (diff) | |
parent | 40238b9a601d58d2b4f88da7b14823e8c0340bc6 (diff) | |
download | android_packages_providers_DownloadProvider-1d0dcb200d466cd4b03f65fa03f16c7944a0b6c1.tar.gz android_packages_providers_DownloadProvider-1d0dcb200d466cd4b03f65fa03f16c7944a0b6c1.tar.bz2 android_packages_providers_DownloadProvider-1d0dcb200d466cd4b03f65fa03f16c7944a0b6c1.zip |
Merge commit '40238b9a601d58d2b4f88da7b14823e8c0340bc6' into manual_merge_40238b9
Change-Id: I0d8441c4bae392726e7d41c77b1d9ac5eda1c09c
Diffstat (limited to 'src/com/android/providers/downloads')
-rw-r--r-- | src/com/android/providers/downloads/DownloadProvider.java | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/src/com/android/providers/downloads/DownloadProvider.java b/src/com/android/providers/downloads/DownloadProvider.java index d30018f7..4a64743e 100644 --- a/src/com/android/providers/downloads/DownloadProvider.java +++ b/src/com/android/providers/downloads/DownloadProvider.java @@ -468,6 +468,19 @@ public final class DownloadProvider extends ContentProvider { if (appInfo != null) { mDefContainerUid = appInfo.uid; } + + // Grant access permissions for all known downloads to the owning apps + final SQLiteDatabase db = mOpenHelper.getReadableDatabase(); + final Cursor cursor = db.query(DB_TABLE, new String[] { + Downloads.Impl._ID, Constants.UID }, null, null, null, null, null); + try { + while (cursor.moveToNext()) { + grantAllDownloadsPermission(cursor.getLong(0), cursor.getInt(1)); + } + } finally { + cursor.close(); + } + return true; } @@ -690,6 +703,7 @@ public final class DownloadProvider extends ContentProvider { } insertRequestHeaders(db, rowID, values); + grantAllDownloadsPermission(rowID, Binder.getCallingUid()); notifyContentChanged(uri, match); final long token = Binder.clearCallingIdentity(); @@ -1212,6 +1226,7 @@ public final class DownloadProvider extends ContentProvider { final long id = cursor.getLong(0); scheduler.cancel((int) id); + revokeAllDownloadsPermission(id); DownloadStorageProvider.onDownloadProviderDelete(getContext(), id); final String path = cursor.getString(1); @@ -1260,6 +1275,19 @@ public final class DownloadProvider extends ContentProvider { logVerboseOpenFileInfo(uri, mode); } + // Perform normal query to enforce caller identity access before + // clearing it to reach internal-only columns + final Cursor probeCursor = query(uri, new String[] { + Downloads.Impl._DATA }, null, null, null); + try { + if ((probeCursor == null) || (probeCursor.getCount() == 0)) { + throw new FileNotFoundException( + "No file found for " + uri + " as UID " + Binder.getCallingUid()); + } + } finally { + IoUtils.closeQuietly(probeCursor); + } + final Cursor cursor = queryCleared(uri, new String[] { Downloads.Impl._DATA, Downloads.Impl.COLUMN_STATUS, Downloads.Impl.COLUMN_DESTINATION, Downloads.Impl.COLUMN_MEDIA_SCANNED }, null, @@ -1442,4 +1470,20 @@ public final class DownloadProvider extends ContentProvider { to.put(key, defaultValue); } } + + private void grantAllDownloadsPermission(long id, int uid) { + final String[] packageNames = getContext().getPackageManager().getPackagesForUid(uid); + if (packageNames == null || packageNames.length == 0) return; + + // We only need to grant to the first package, since the + // platform internally tracks based on UIDs + final Uri uri = ContentUris.withAppendedId(Downloads.Impl.ALL_DOWNLOADS_CONTENT_URI, id); + getContext().grantUriPermission(packageNames[0], uri, + Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); + } + + private void revokeAllDownloadsPermission(long id) { + final Uri uri = ContentUris.withAppendedId(Downloads.Impl.ALL_DOWNLOADS_CONTENT_URI, id); + getContext().revokeUriPermission(uri, ~0); + } } |