Repository: thundernest/k-9
Issue: SecurityException on image shared to K-9 not caught

### Checklist

- [X] I have used the search function to see if someone else has already submitted the same bug report.
- [X] I will describe the problem with as much detail as possible.

### App version

6.301

### Where did you get the app from?

F-Droid

### Android version

12

### Device model

Pixel 4a

### Steps to reproduce

1. Share an image from Firefox to a K-9 Direct Share contact (before [this](https://github.com/mozilla-mobile/android-components/pull/12649) change is rolled out) or an older version of chome (like 3 months old? not sure) or any app that forgets to call `intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)`
2. K-9 mail crashes.

### Expected behavior

K-9 communicates to the user that the attachement can't be opened.

### Actual behavior

K-9 mail crashes.

### Logs

```
08-12 22:06:59.152 31785  7754 E AndroidRuntime: FATAL EXCEPTION: ModernAsyncTask #2
08-12 22:06:59.152 31785  7754 E AndroidRuntime: Process: com.fsck.k9, PID: 31785
08-12 22:06:59.152 31785  7754 E AndroidRuntime: java.lang.RuntimeException: An error occurred while executing doInBackground()
08-12 22:06:59.152 31785  7754 E AndroidRuntime: 	at androidx.loader.content.ModernAsyncTask$3.done(ModernAsyncTask.java:164)
08-12 22:06:59.152 31785  7754 E AndroidRuntime: 	at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:383)
08-12 22:06:59.152 31785  7754 E AndroidRuntime: 	at java.util.concurrent.FutureTask.setException(FutureTask.java:252)
08-12 22:06:59.152 31785  7754 E AndroidRuntime: 	at java.util.concurrent.FutureTask.run(FutureTask.java:271)
08-12 22:06:59.152 31785  7754 E AndroidRuntime: 	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
08-12 22:06:59.152 31785  7754 E AndroidRuntime: 	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
08-12 22:06:59.152 31785  7754 E AndroidRuntime: 	at java.lang.Thread.run(Thread.java:919)
08-12 22:06:59.152 31785  7754 E AndroidRuntime: Caused by: java.lang.SecurityException: Permission Denial: opening provider mozilla.components.feature.downloads.provider.FileProvider from ProcessRecord{1846f0d 31785:com.fsck.k9/u0a153} (pid=31785, uid=10153) that is not exported from UID 10140
08-12 22:06:59.152 31785  7754 E AndroidRuntime: 	at android.os.Parcel.createException(Parcel.java:2071)
08-12 22:06:59.152 31785  7754 E AndroidRuntime: 	at android.os.Parcel.readException(Parcel.java:2039)
08-12 22:06:59.152 31785  7754 E AndroidRuntime: 	at android.os.Parcel.readException(Parcel.java:1987)
08-12 22:06:59.152 31785  7754 E AndroidRuntime: 	at android.app.IActivityManager$Stub$Proxy.getContentProvider(IActivityManager.java:5056)
08-12 22:06:59.152 31785  7754 E AndroidRuntime: 	at android.app.ActivityThread.acquireProvider(ActivityThread.java:6561)
08-12 22:06:59.152 31785  7754 E AndroidRuntime: 	at android.app.ContextImpl$ApplicationContentResolver.acquireUnstableProvider(ContextImpl.java:2725)
08-12 22:06:59.152 31785  7754 E AndroidRuntime: 	at android.content.ContentResolver.acquireUnstableProvider(ContentResolver.java:2117)
08-12 22:06:59.152 31785  7754 E AndroidRuntime: 	at android.content.ContentResolver.query(ContentResolver.java:928)
08-12 22:06:59.152 31785  7754 E AndroidRuntime: 	at android.content.ContentResolver.query(ContentResolver.java:880)
08-12 22:06:59.152 31785  7754 E AndroidRuntime: 	at android.content.ContentResolver.query(ContentResolver.java:836)
08-12 22:06:59.152 31785  7754 E AndroidRuntime: 	at com.fsck.k9.activity.loader.AttachmentInfoLoader.loadInBackground(AttachmentInfoLoader.java:57)
08-12 22:06:59.152 31785  7754 E AndroidRuntime: 	at com.fsck.k9.activity.loader.AttachmentInfoLoader.loadInBackground(AttachmentInfoLoader.java:22)
08-12 22:06:59.152 31785  7754 E AndroidRuntime: 	at androidx.loader.content.AsyncTaskLoader.onLoadInBackground(AsyncTaskLoader.java:307)
08-12 22:06:59.152 31785  7754 E AndroidRuntime: 	at androidx.loader.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:60)
08-12 22:06:59.152 31785  7754 E AndroidRuntime: 	at androidx.loader.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:48)
08-12 22:06:59.152 31785  7754 E AndroidRuntime: 	at androidx.loader.content.ModernAsyncTask$2.call(ModernAsyncTask.java:141)
08-12 22:06:59.152 31785  7754 E AndroidRuntime: 	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
08-12 22:06:59.152 31785  7754 E AndroidRuntime: 	... 3 more
08-12 22:06:59.152 31785  7754 E AndroidRuntime: Caused by: android.os.RemoteException: Remote stack trace:
08-12 22:06:59.152 31785  7754 E AndroidRuntime: 	at com.android.server.am.ActivityManagerService.getContentProviderImpl(ActivityManagerService.java:6816)
08-12 22:06:59.152 31785  7754 E AndroidRuntime: 	at com.android.server.am.ActivityManagerService.getContentProvider(ActivityManagerService.java:7238)
08-12 22:06:59.152 31785  7754 E AndroidRuntime: 	at android.app.IActivityManager$Stub.onTransact(IActivityManager.java:2078)
08-12 22:06:59.152 31785  7754 E AndroidRuntime: 	at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:2742)
08-12 22:06:59.152 31785  7754 E AndroidRuntime: 	at android.os.Binder.execTransactInternal(Binder.java:1021)
08-12 22:06:59.152 31785  7754 E AndroidRuntime: 
```

Changed files:
app/ui/legacy/src/main/java/com/fsck/k9/activity/loader/AttachmentInfoLoader.java
app/ui/legacy/src/main/java/com/fsck/k9/activity/loader/AttachmentContentLoader.java

diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/activity/loader/AttachmentContentLoader.java b/app/ui/legacy/src/main/java/com/fsck/k9/activity/loader/AttachmentContentLoader.java
index 6a420c812..19ceff5b6 100644
--- a/app/ui/legacy/src/main/java/com/fsck/k9/activity/loader/AttachmentContentLoader.java
+++ b/app/ui/legacy/src/main/java/com/fsck/k9/activity/loader/AttachmentContentLoader.java
@@ -3,7 +3,6 @@ package com.fsck.k9.activity.loader;
 
 import java.io.File;
 import java.io.FileOutputStream;
-import java.io.IOException;
 import java.io.InputStream;
 
 import android.content.ContentResolver;
@@ -88,7 +87,7 @@ public class AttachmentContentLoader extends AsyncTaskLoader<Attachment> {
 
             cachedResultAttachment = sourceAttachment.deriveWithLoadComplete(file.getAbsolutePath());
             return cachedResultAttachment;
-        } catch (IOException e) {
+        } catch (Exception e) {
             Timber.e(e, "Error saving attachment!");
         }
 
diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/activity/loader/AttachmentInfoLoader.java b/app/ui/legacy/src/main/java/com/fsck/k9/activity/loader/AttachmentInfoLoader.java
index 6750dd52b..9bbf2e61d 100644
--- a/app/ui/legacy/src/main/java/com/fsck/k9/activity/loader/AttachmentInfoLoader.java
+++ b/app/ui/legacy/src/main/java/com/fsck/k9/activity/loader/AttachmentInfoLoader.java
@@ -46,63 +46,70 @@ public class AttachmentInfoLoader  extends AsyncTaskLoader<Attachment> {
 
     @Override
     public Attachment loadInBackground() {
-        Uri uri = sourceAttachment.uri;
-        String contentType = sourceAttachment.contentType;
-
-        long size = -1;
-        String name = null;
-
-        ContentResolver contentResolver = getContext().getContentResolver();
-
-        Cursor metadataCursor = contentResolver.query(
-                uri,
-                new String[] { OpenableColumns.DISPLAY_NAME, OpenableColumns.SIZE },
-                null,
-                null,
-                null);
-
-        if (metadataCursor != null) {
-            try {
-                if (metadataCursor.moveToFirst()) {
-                    name = metadataCursor.getString(0);
-                    size = metadataCursor.getInt(1);
+        try {
+            Uri uri = sourceAttachment.uri;
+            String contentType = sourceAttachment.contentType;
+
+            long size = -1;
+            String name = null;
+
+            ContentResolver contentResolver = getContext().getContentResolver();
+
+            Cursor metadataCursor = contentResolver.query(
+                    uri,
+                    new String[] { OpenableColumns.DISPLAY_NAME, OpenableColumns.SIZE },
+                    null,
+                    null,
+                    null);
+
+            if (metadataCursor != null) {
+                try {
+                    if (metadataCursor.moveToFirst()) {
+                        name = metadataCursor.getString(0);
+                        size = metadataCursor.getInt(1);
+                    }
+                } finally {
+                    metadataCursor.close();
                 }
-            } finally {
-                metadataCursor.close();
             }
-        }
 
-        if (name == null) {
-            name = uri.getLastPathSegment();
-        }
+            if (name == null) {
+                name = uri.getLastPathSegment();
+            }
 
-        String usableContentType = contentResolver.getType(uri);
-        if (usableContentType == null && contentType != null && contentType.indexOf('*') != -1) {
-            usableContentType = contentType;
-        }
+            String usableContentType = contentResolver.getType(uri);
+            if (usableContentType == null && contentType != null && contentType.indexOf('*') != -1) {
+                usableContentType = contentType;
+            }
 
-        if (usableContentType == null) {
-            usableContentType = MimeTypeUtil.getMimeTypeByExtension(name);
-        }
+            if (usableContentType == null) {
+                usableContentType = MimeTypeUtil.getMimeTypeByExtension(name);
+            }
 
-        if (!sourceAttachment.allowMessageType && MimeUtility.isMessageType(usableContentType)) {
-            usableContentType = MimeTypeUtil.DEFAULT_ATTACHMENT_MIME_TYPE;
-        }
+            if (!sourceAttachment.allowMessageType && MimeUtility.isMessageType(usableContentType)) {
+                usableContentType = MimeTypeUtil.DEFAULT_ATTACHMENT_MIME_TYPE;
+            }
 
-        if (size <= 0) {
-            String uriString = uri.toString();
-            if (uriString.startsWith("file://")) {
-                File f = new File(uriString.substring("file://".length()));
-                size = f.length();
+            if (size <= 0) {
+                String uriString = uri.toString();
+                if (uriString.startsWith("file://")) {
+                    File f = new File(uriString.substring("file://".length()));
+                    size = f.length();
+                } else {
+                    Timber.v("Not a file: %s", uriString);
+                }
             } else {
-                Timber.v("Not a file: %s", uriString);
+                Timber.v("old attachment.size: %d", size);
             }
-        } else {
-            Timber.v("old attachment.size: %d", size);
-        }
-        Timber.v("new attachment.size: %d", size);
+            Timber.v("new attachment.size: %d", size);
+
+            cachedResultAttachment = sourceAttachment.deriveWithMetadataLoaded(usableContentType, name, size);
+            return cachedResultAttachment;
+        } catch (Exception e) {
+            Timber.e(e, "Error getting attachment meta data");
 
-        cachedResultAttachment = sourceAttachment.deriveWithMetadataLoaded(usableContentType, name, size);
-        return cachedResultAttachment;
+            cachedResultAttachment = sourceAttachment.deriveWithLoadCancelled();
+            return cachedResultAttachment;
+        }
     }
 }