Detailed ContentProvider permissions checks.

The new MediaProvider design has an internal dynamic security model
based on the value stored in OWNER_PACKAGE_NAME, so the OS always
needs to consult the provider when resolving Uri permission grants.

Blocking calls from the system process like this are typically
discouraged, but this is the best we can do with the limited time
left, and there is existing precident with getType().

For now, use "forceUriPermissions" as a proxy for determining when
we need to consult the provider directly.

Bug: 115619667
Test: atest --test-mapping packages/providers/MediaProvider
Test: atest android.appsecurity.cts.ExternalStorageHostTest
Change-Id: I1d54feeec93fbb4cf5ff55240ef4eae3a35ed068
This commit is contained in:
Jeff Sharkey
2019-05-20 14:00:17 -06:00
parent 26f2c379d0
commit 9edef25ede
12 changed files with 224 additions and 1 deletions

View File

@@ -16,6 +16,7 @@
package android.test.mock;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.ContentProvider;
import android.content.ContentProviderOperation;
@@ -23,6 +24,7 @@ import android.content.ContentProviderResult;
import android.content.ContentValues;
import android.content.Context;
import android.content.IContentProvider;
import android.content.Intent;
import android.content.OperationApplicationException;
import android.content.pm.PathPermission;
import android.content.pm.ProviderInfo;
@@ -154,6 +156,11 @@ public class MockContentProvider extends ContentProvider {
ICancellationSignal cancellationSignal) throws RemoteException {
return MockContentProvider.this.refresh(url, args);
}
@Override
public int checkUriPermission(String callingPkg, Uri uri, int uid, int modeFlags) {
return MockContentProvider.this.checkUriPermission(uri, uid, modeFlags);
}
}
private final InversionIContentProvider mIContentProvider = new InversionIContentProvider();
@@ -266,6 +273,12 @@ public class MockContentProvider extends ContentProvider {
throw new UnsupportedOperationException("unimplemented mock method call");
}
/** {@hide} */
@Override
public int checkUriPermission(@NonNull Uri uri, int uid, @Intent.AccessUriMode int modeFlags) {
throw new UnsupportedOperationException("unimplemented mock method call");
}
/**
* Returns IContentProvider which calls back same methods in this class.
* By overriding this class, we avoid the mechanism hidden behind ContentProvider

View File

@@ -16,12 +16,14 @@
package android.test.mock;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.ContentProviderOperation;
import android.content.ContentProviderResult;
import android.content.ContentValues;
import android.content.EntityIterator;
import android.content.IContentProvider;
import android.content.Intent;
import android.content.res.AssetFileDescriptor;
import android.database.Cursor;
import android.net.Uri;
@@ -144,4 +146,10 @@ public class MockIContentProvider implements IContentProvider {
ICancellationSignal cancellationSignal) throws RemoteException {
throw new UnsupportedOperationException("unimplemented mock method");
}
/** {@hide} */
@Override
public int checkUriPermission(String callingPkg, Uri uri, int uid, int modeFlags) {
throw new UnsupportedOperationException("unimplemented mock method call");
}
}