diff options
author | Suprabh Shukla <suprabh@google.com> | 2017-02-27 15:56:11 -0800 |
---|---|---|
committer | Suprabh Shukla <suprabh@google.com> | 2017-03-07 15:03:01 -0800 |
commit | 2ab9a2d15c63cd567805adb8fa4b9c524afc5ceb (patch) | |
tree | 66b223080a37530a8df975f3ce4adc5fd9dcce81 /src/com | |
parent | 74d1965590fdaad79ba4c2f4631d187086501d43 (diff) | |
download | android_packages_providers_DownloadProvider-2ab9a2d15c63cd567805adb8fa4b9c524afc5ceb.tar.gz android_packages_providers_DownloadProvider-2ab9a2d15c63cd567805adb8fa4b9c524afc5ceb.tar.bz2 android_packages_providers_DownloadProvider-2ab9a2d15c63cd567805adb8fa4b9c524afc5ceb.zip |
Deleting downloads for removed uids on downloadprovider start
After uninstalling an app, if the system was shutdown before the
download provider received the broadcast for UID_REMOVED, another app
installed later in the same uid might be able to gain access to the
files downloaded by this app. Removing any such hanging downloads
at the start up of the download provider should fix this issue.
Test: Manually tested by uninstalling an app and killing and restarting
the process android.process.media, to check that the downloaded files of
the uninstalled app were deleted.
Bug:22011579
Change-Id: I7382c4846f99035b40412a01715aee5873efa9e6
Diffstat (limited to 'src/com')
-rw-r--r-- | src/com/android/providers/downloads/DownloadProvider.java | 55 |
1 files changed, 45 insertions, 10 deletions
diff --git a/src/com/android/providers/downloads/DownloadProvider.java b/src/com/android/providers/downloads/DownloadProvider.java index edb804ea..f3b7b6f3 100644 --- a/src/com/android/providers/downloads/DownloadProvider.java +++ b/src/com/android/providers/downloads/DownloadProvider.java @@ -474,17 +474,42 @@ public final class DownloadProvider extends ContentProvider { final SQLiteDatabase db = mOpenHelper.getReadableDatabase(); final Cursor cursor = db.query(DB_TABLE, new String[] { Downloads.Impl._ID, Constants.UID }, null, null, null, null, null); + final ArrayList<Long> idsToDelete = new ArrayList<>(); try { while (cursor.moveToNext()) { - grantAllDownloadsPermission(cursor.getLong(0), cursor.getInt(1)); + final long downloadId = cursor.getLong(0); + final int uid = cursor.getInt(1); + final String ownerPackage = getPackageForUid(uid); + if (ownerPackage == null) { + idsToDelete.add(downloadId); + } else { + grantAllDownloadsPermission(ownerPackage, downloadId); + } } } finally { cursor.close(); } - + if (idsToDelete.size() > 0) { + Log.i(Constants.TAG, + "Deleting downloads with ids " + idsToDelete + " as owner package is missing"); + deleteDownloadsWithIds(idsToDelete); + } return true; } + private void deleteDownloadsWithIds(ArrayList<Long> downloadIds) { + final int N = downloadIds.size(); + if (N == 0) { + return; + } + final StringBuilder queryBuilder = new StringBuilder(Downloads.Impl._ID + " in ("); + for (int i = 0; i < N; i++) { + queryBuilder.append(downloadIds.get(i)); + queryBuilder.append((i == N - 1) ? ")" : ","); + } + delete(Downloads.Impl.ALL_DOWNLOADS_CONTENT_URI, queryBuilder.toString(), null); + } + /** * Returns the content-provider-style MIME types of the various * types accessible through this content provider. @@ -704,7 +729,13 @@ public final class DownloadProvider extends ContentProvider { } insertRequestHeaders(db, rowID, values); - grantAllDownloadsPermission(rowID, Binder.getCallingUid()); + + final String callingPackage = getPackageForUid(Binder.getCallingUid()); + if (callingPackage == null) { + Log.e(Constants.TAG, "Package does not exist for calling uid"); + return null; + } + grantAllDownloadsPermission(callingPackage, rowID); notifyContentChanged(uri, match); final long token = Binder.clearCallingIdentity(); @@ -723,6 +754,15 @@ public final class DownloadProvider extends ContentProvider { return ContentUris.withAppendedId(Downloads.Impl.CONTENT_URI, rowID); } + private String getPackageForUid(int uid) { + String[] packages = getContext().getPackageManager().getPackagesForUid(uid); + if (packages == null || packages.length == 0) { + return null; + } + // For permission related purposes, any package belonging to the given uid should work. + return packages[0]; + } + /** * Check that the file URI provided for DESTINATION_FILE_URI is valid. */ @@ -1501,14 +1541,9 @@ public final class DownloadProvider extends ContentProvider { } } - 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 + private void grantAllDownloadsPermission(String toPackage, long id) { final Uri uri = ContentUris.withAppendedId(Downloads.Impl.ALL_DOWNLOADS_CONTENT_URI, id); - getContext().grantUriPermission(packageNames[0], uri, + getContext().grantUriPermission(toPackage, uri, Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); } |