Skip to content

SecurityException reading own capabilities provider when an external app creates a file via SAF (DocumentsStorageProvider.createFile) → "Failed to save document" #17261

Description

@Barthelemy-Cabouat

⚠️ Before posting ⚠️

  • This is a bug, not a question or an enhancement.
  • I've searched for similar issues and didn't find a duplicate.
  • I've written a clear and descriptive title for this issue, not just "Bug" or "Crash".
  • I agree to follow Nextcloud's Code of Conduct.

Steps to reproduce

  1. Have the Nextcloud Android client signed in (here: 34.0.1).
  2. From any third-party app, invoke the system file picker with ACTION_CREATE_DOCUMENT and choose a folder inside Nextcloud as the destination (reproduced with Gadgetbridge's "Auto export" → export location, creating an application/x-sqlite3 file).
  3. Confirm the save in the picker.

Expected behaviour

Expected: the file is created in the selected Nextcloud folder.

Actual behaviour

Actual: the picker (Android DocumentsUI) shows "Failed to save document" and no file is created. The Nextcloud client throws a SecurityException while creating the document.

Android version

15

Device brand and model

Fairphone 5

Stock or custom OS?

Stock

Nextcloud android app version

34.0.1 versionCode 340000190

Nextcloud server version

34.0.0

Using a reverse proxy?

No

Android logs

06-29 14:15:42.379 D/DocumentsStorageProvider(28727): createDocument(), id=…/153

06-29 14:15:50.066 E/DatabaseUtils(28727): Writing exception to parcel
06-29 14:15:50.066 E/DatabaseUtils(28727): java.lang.SecurityException: Permission Denial: reading
        com.owncloud.android.providers.FileContentProvider uri content://org.nextcloud/capabilities
        from pid=29872, uid=10059 requires false, or grantUriPermission()
06-29 14:15:50.066 E/DatabaseUtils(28727):   at com.owncloud.android.lib.common.operations.RemoteOperation.execute(RemoteOperation.java:193)
06-29 14:15:50.066 E/DatabaseUtils(28727):   at com.owncloud.android.providers.DocumentsStorageProvider.createFile(DocumentsStorageProvider.java:641)
06-29 14:15:50.066 E/DatabaseUtils(28727):   at com.owncloud.android.providers.DocumentsStorageProvider.createDocument(DocumentsStorageProvider.java:539)
        [ … standard android.os.Binder / Parcel IPC frames elided … ]

// Surfaced on the DocumentsUI (picker, uid 10059 / pid 29872) side:
06-29 14:15:50.070 W/DocumentsContract(29872): java.lang.SecurityException: Permission Denial: reading
        com.owncloud.android.providers.FileContentProvider uri content://org.nextcloud/capabilities
        from pid=29872, uid=10059 requires false, or grantUriPermission()
06-29 14:15:50.070 W/DocumentsContract(29872):   at android.os.Parcel.createExceptionOrNull(Parcel.java:3241)
06-29 14:15:50.070 W/DocumentsContract(29872):   at android.os.Parcel.createException(Parcel.java:3225)
06-29 14:15:50.070 W/DocumentsContract(29872):   at android.os.Parcel.readException(Parcel.java:3208)
06-29 14:15:50.070 W/DocumentsContract(29872):   at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:203)
06-29 14:15:50.070 W/DocumentsContract(29872):   at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:155)
06-29 14:15:50.070 W/DocumentsContract(29872):   at android.provider.DocumentsContract.createDocument(DocumentsContract.java:1380)
06-29 14:15:50.070 W/DocumentsContract(29872):   at com.android.documentsui.DocumentsAccess$RuntimeDocumentAccess.createDocument(DocumentsAccess.java:170)
06-29 14:15:50.070 W/DocumentsContract(29872):   at java.util.concurrent.FutureTask.run(FutureTask.java:328)

Server error logs

n/a

Additional information

DocumentsStorageProvider.createFile() (line 641) runs a RemoteOperation whose execute() reads the client's own content://org.nextcloud/capabilities provider. During a SAF createDocument call the binder calling identity is still the caller's (DocumentsUI, uid 10059), not the Nextcloud client's, so the read of the non-exported FileContentProvider is denied. The SecurityException propagates out of createDocument, and Android's DocumentsUI reports "Failed to save document."

The capabilities lookup inside createFile likely needs to run under the provider's own identity (e.g. wrap the internal capabilities/RemoteOperation read in Binder.clearCallingIdentity() / restoreCallingIdentity()), rather than the SAF caller's identity.

Creating files into Nextcloud via other DocumentsProviders (local storage, Google Drive) works; only Nextcloud's provider fails, because only it performs this self-referential capabilities read under the foreign caller identity.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions