Android MMS api allows arbitrary file access as the radio user
Bug 8214355
Only allow files in mms's app_parts directory to be opened.
Tested with the code found in the bug, before and after this
change.
(cherry picked from commit 8168ff8cebcd1b51ef9d97f2a50f9c91ee8aa562)
Change-Id: Ieab4cf20f6191aba5c2118d454dcf69f5e268308
diff --git a/src/com/android/providers/telephony/MmsProvider.java b/src/com/android/providers/telephony/MmsProvider.java
index 5e3e1f1..bddce1d 100644
--- a/src/com/android/providers/telephony/MmsProvider.java
+++ b/src/com/android/providers/telephony/MmsProvider.java
@@ -17,6 +17,7 @@
package com.android.providers.telephony;
import android.content.ContentProvider;
+import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
@@ -764,20 +765,50 @@
@Override
public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
- // TODO do we even need this anymore?
- ParcelFileDescriptor fd;
int match = sURLMatcher.match(uri);
if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.d(TAG, "openFile: uri=" + uri + ", mode=" + mode);
+ Log.d(TAG, "openFile: uri=" + uri + ", mode=" + mode + ", match=" + match);
}
- switch (match) {
- default:
- fd = openFileHelper(uri, mode);
+ if (match != MMS_PART_ID) {
+ return null;
}
- return fd;
+ // Verify that the _data path points to mms data
+ Cursor c = query(uri, new String[]{"_data"}, null, null, null);
+ int count = (c != null) ? c.getCount() : 0;
+ if (count != 1) {
+ // If there is not exactly one result, throw an appropriate
+ // exception.
+ if (c != null) {
+ c.close();
+ }
+ if (count == 0) {
+ throw new FileNotFoundException("No entry for " + uri);
+ }
+ throw new FileNotFoundException("Multiple items at " + uri);
+ }
+
+ c.moveToFirst();
+ int i = c.getColumnIndex("_data");
+ String path = (i >= 0 ? c.getString(i) : null);
+ c.close();
+
+ if (path == null) {
+ return null;
+ }
+ try {
+ File filePath = new File(path);
+ if (!filePath.getCanonicalPath()
+ .startsWith(getContext().getApplicationInfo().dataDir + "/app_parts/")) {
+ return null;
+ }
+ } catch (IOException e) {
+ return null;
+ }
+
+ return openFileHelper(uri, mode);
}
private void filterUnsupportedKeys(ContentValues values) {