mahdize / CrossQFile

MIT License
6 stars 1 forks source link

SecurityException causes crash #2

Open srcejon opened 1 year ago

srcejon commented 1 year ago

Hi,

I was trying to use CrossQFile to access a Uri I had created such as:

"content://com.android.externalstorage.documents/document/primary%3AIQ%2Ftest.wav"

This results in an SecurityException, then a crash:

: java_vm_ext.cc:594] JNI DETECTED ERROR IN APPLICATION: JNI GetMethodID called with pending exception java.lang.SecurityException: Permission Denial: writing com.android.externalstorage.ExternalStorageProvider uri content://com.android.externalstorage.documents/document/primary%3AIQ%2Ftest.wav from pid=20200, uid=10651 requires android.permission.MANAGE_DOCUMENTS, or grantUriPermission()
...
at android.os.ParcelFileDescriptor android.content.ContentResolver.openFileDescriptor(android.net.Uri, java.lang.String) (ContentResolver.java:1629)

The crash seems to be because checkJenvExceptions() isn't called between contentResolverObj.callObjectMethod("openFileDescriptor" and pfdObj.callMethod("detachFd"), only afterwards. It needs something like:

    QAndroidJniObject pfdObj{contentResolverObj.callObjectMethod
                ("openFileDescriptor", "(Landroid/net/Uri;Ljava/lang/String;)Landroid/os/ParcelFileDescriptor;",
                 parseUriString(fileName()).object(), jopenMode.object())};
    if(checkJenvExceptions()){
        return false;
    }
    int fd{pfdObj.callMethod<jint>("detachFd")};

Any idea about why I'm getting the SecurityException in the first place? What Uri should I be using to open an arbitrary file in external storage? I have android.permission.MANAGE_DOCUMENTS in the manifest.

mahdize commented 1 year ago

Hi,

Can you tell me which version of Android and which kind of device are you running the code? Also, the targeted Android SDK may cause different behavior due to different security policies. I think this problem is caused by missing the needed scoped storage permissions in the application manifest. if so, adding the following line to your manifest may solve the problem

<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />

For the last question, you can you the Uri provided by the Android File picker to open a file in the external storage.

srcejon commented 1 year ago

This was with Android 13 on a Samsung S22. SDK was 28. The JNI exception problem is pretty generic though, as I've seen that in other non-Android JNI code.

I can access files where the Uri is returned by the Android File picker, but am having the security exception when trying to access files without using the File Picker on a manually created Uri (perhaps that isn't allowed?) I will give MANAGE_EXTERNAL_STORAGE a try, thanks.

mahdize commented 1 year ago

For using manually created Uri, you should follow Android Documentation.

You should develop a custom "DocumentProvider", that provides the correct Uri with granted permissions.