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.

Change-Id: Ifce883caf1631d352ae264266614d58d125964bf
diff --git a/src/com/android/providers/telephony/MmsProvider.java b/src/com/android/providers/telephony/MmsProvider.java
index 9b6cf48..a7e4ed4 100644
--- a/src/com/android/providers/telephony/MmsProvider.java
+++ b/src/com/android/providers/telephony/MmsProvider.java
@@ -18,6 +18,7 @@
 
 import android.app.AppOpsManager;
 import android.content.ContentProvider;
+import android.content.ContentResolver;
 import android.content.ContentValues;
 import android.content.Context;
 import android.content.Intent;
@@ -766,20 +767,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) {