Loading core/java/android/content/ContentProvider.java +34 −19 Original line number Diff line number Diff line Loading @@ -54,6 +54,7 @@ import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Arrays; import java.util.Objects; /** * Content providers are one of the primary building blocks of Android applications, providing Loading Loading @@ -208,7 +209,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 { @Override public Cursor query(String callingPkg, Uri uri, @Nullable String[] projection, @Nullable Bundle queryArgs, @Nullable ICancellationSignal cancellationSignal) { validateIncomingUri(uri); uri = validateIncomingUri(uri); uri = maybeGetUriWithoutUserId(uri); if (enforceReadPermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) { // The caller has no access to the data, so return an empty cursor with Loading Loading @@ -247,14 +248,14 @@ public abstract class ContentProvider implements ComponentCallbacks2 { @Override public String getType(Uri uri) { validateIncomingUri(uri); uri = validateIncomingUri(uri); uri = maybeGetUriWithoutUserId(uri); return ContentProvider.this.getType(uri); } @Override public Uri insert(String callingPkg, Uri uri, ContentValues initialValues) { validateIncomingUri(uri); uri = validateIncomingUri(uri); int userId = getUserIdFromUri(uri); uri = maybeGetUriWithoutUserId(uri); if (enforceWritePermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) { Loading @@ -270,7 +271,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 { @Override public int bulkInsert(String callingPkg, Uri uri, ContentValues[] initialValues) { validateIncomingUri(uri); uri = validateIncomingUri(uri); uri = maybeGetUriWithoutUserId(uri); if (enforceWritePermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) { return 0; Loading @@ -292,11 +293,12 @@ public abstract class ContentProvider implements ComponentCallbacks2 { for (int i = 0; i < numOperations; i++) { ContentProviderOperation operation = operations.get(i); Uri uri = operation.getUri(); validateIncomingUri(uri); userIds[i] = getUserIdFromUri(uri); if (userIds[i] != UserHandle.USER_CURRENT) { // Removing the user id from the uri. operation = new ContentProviderOperation(operation, true); uri = validateIncomingUri(uri); uri = maybeGetUriWithoutUserId(uri); // Rebuild operation if we changed the Uri above if (!Objects.equals(operation.getUri(), uri)) { operation = new ContentProviderOperation(operation, uri); operations.set(i, operation); } if (operation.isReadOperation()) { Loading Loading @@ -331,7 +333,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 { @Override public int delete(String callingPkg, Uri uri, String selection, String[] selectionArgs) { validateIncomingUri(uri); uri = validateIncomingUri(uri); uri = maybeGetUriWithoutUserId(uri); if (enforceWritePermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) { return 0; Loading @@ -347,7 +349,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 { @Override public int update(String callingPkg, Uri uri, ContentValues values, String selection, String[] selectionArgs) { validateIncomingUri(uri); uri = validateIncomingUri(uri); uri = maybeGetUriWithoutUserId(uri); if (enforceWritePermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) { return 0; Loading @@ -364,7 +366,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 { public ParcelFileDescriptor openFile( String callingPkg, Uri uri, String mode, ICancellationSignal cancellationSignal, IBinder callerToken) throws FileNotFoundException { validateIncomingUri(uri); uri = validateIncomingUri(uri); uri = maybeGetUriWithoutUserId(uri); enforceFilePermission(callingPkg, uri, mode, callerToken); final String original = setCallingPackage(callingPkg); Loading @@ -380,7 +382,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 { public AssetFileDescriptor openAssetFile( String callingPkg, Uri uri, String mode, ICancellationSignal cancellationSignal) throws FileNotFoundException { validateIncomingUri(uri); uri = validateIncomingUri(uri); uri = maybeGetUriWithoutUserId(uri); enforceFilePermission(callingPkg, uri, mode, null); final String original = setCallingPackage(callingPkg); Loading @@ -406,7 +408,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 { @Override public String[] getStreamTypes(Uri uri, String mimeTypeFilter) { validateIncomingUri(uri); uri = validateIncomingUri(uri); uri = maybeGetUriWithoutUserId(uri); return ContentProvider.this.getStreamTypes(uri, mimeTypeFilter); } Loading @@ -415,7 +417,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 { public AssetFileDescriptor openTypedAssetFile(String callingPkg, Uri uri, String mimeType, Bundle opts, ICancellationSignal cancellationSignal) throws FileNotFoundException { Bundle.setDefusable(opts, true); validateIncomingUri(uri); uri = validateIncomingUri(uri); uri = maybeGetUriWithoutUserId(uri); enforceFilePermission(callingPkg, uri, "r", null); final String original = setCallingPackage(callingPkg); Loading @@ -434,7 +436,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 { @Override public Uri canonicalize(String callingPkg, Uri uri) { validateIncomingUri(uri); uri = validateIncomingUri(uri); int userId = getUserIdFromUri(uri); uri = getUriWithoutUserId(uri); if (enforceReadPermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) { Loading @@ -450,7 +452,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 { @Override public Uri uncanonicalize(String callingPkg, Uri uri) { validateIncomingUri(uri); uri = validateIncomingUri(uri); int userId = getUserIdFromUri(uri); uri = getUriWithoutUserId(uri); if (enforceReadPermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) { Loading @@ -467,7 +469,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 { @Override public boolean refresh(String callingPkg, Uri uri, Bundle args, ICancellationSignal cancellationSignal) throws RemoteException { validateIncomingUri(uri); uri = validateIncomingUri(uri); uri = getUriWithoutUserId(uri); if (enforceReadPermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) { return false; Loading Loading @@ -1901,7 +1903,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 { */ if (mContext == null) { mContext = context; if (context != null) { if (context != null && mTransport != null) { mTransport.mAppOpsManager = (AppOpsManager) context.getSystemService( Context.APP_OPS_SERVICE); } Loading Loading @@ -2010,7 +2012,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 { } /** @hide */ private void validateIncomingUri(Uri uri) throws SecurityException { public Uri validateIncomingUri(Uri uri) throws SecurityException { String auth = uri.getAuthority(); if (!mSingleUser) { int userId = getUserIdFromAuthority(auth, UserHandle.USER_CURRENT); Loading @@ -2029,6 +2031,19 @@ public abstract class ContentProvider implements ComponentCallbacks2 { } throw new SecurityException(message); } // Normalize the path by removing any empty path segments, which can be // a source of security issues. final String encodedPath = uri.getEncodedPath(); if (encodedPath != null && encodedPath.indexOf("//") != -1) { final Uri normalized = uri.buildUpon() .encodedPath(encodedPath.replaceAll("//+", "/")).build(); Log.w(TAG, "Normalized " + uri + " to " + normalized + " to avoid possible security issues"); return normalized; } else { return uri; } } /** @hide */ Loading core/java/android/content/ContentProviderOperation.java +2 −14 Original line number Diff line number Diff line Loading @@ -94,13 +94,9 @@ public class ContentProviderOperation implements Parcelable { } /** @hide */ public ContentProviderOperation(ContentProviderOperation cpo, boolean removeUserIdFromUri) { public ContentProviderOperation(ContentProviderOperation cpo, Uri withUri) { mType = cpo.mType; if (removeUserIdFromUri) { mUri = ContentProvider.getUriWithoutUserId(cpo.mUri); } else { mUri = cpo.mUri; } mUri = withUri; mValues = cpo.mValues; mSelection = cpo.mSelection; mSelectionArgs = cpo.mSelectionArgs; Loading @@ -110,14 +106,6 @@ public class ContentProviderOperation implements Parcelable { mYieldAllowed = cpo.mYieldAllowed; } /** @hide */ public ContentProviderOperation getWithoutUserIdInUri() { if (ContentProvider.uriHasUserId(mUri)) { return new ContentProviderOperation(this, true); } return this; } public void writeToParcel(Parcel dest, int flags) { dest.writeInt(mType); Uri.writeToParcel(dest, mUri); Loading Loading
core/java/android/content/ContentProvider.java +34 −19 Original line number Diff line number Diff line Loading @@ -54,6 +54,7 @@ import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Arrays; import java.util.Objects; /** * Content providers are one of the primary building blocks of Android applications, providing Loading Loading @@ -208,7 +209,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 { @Override public Cursor query(String callingPkg, Uri uri, @Nullable String[] projection, @Nullable Bundle queryArgs, @Nullable ICancellationSignal cancellationSignal) { validateIncomingUri(uri); uri = validateIncomingUri(uri); uri = maybeGetUriWithoutUserId(uri); if (enforceReadPermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) { // The caller has no access to the data, so return an empty cursor with Loading Loading @@ -247,14 +248,14 @@ public abstract class ContentProvider implements ComponentCallbacks2 { @Override public String getType(Uri uri) { validateIncomingUri(uri); uri = validateIncomingUri(uri); uri = maybeGetUriWithoutUserId(uri); return ContentProvider.this.getType(uri); } @Override public Uri insert(String callingPkg, Uri uri, ContentValues initialValues) { validateIncomingUri(uri); uri = validateIncomingUri(uri); int userId = getUserIdFromUri(uri); uri = maybeGetUriWithoutUserId(uri); if (enforceWritePermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) { Loading @@ -270,7 +271,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 { @Override public int bulkInsert(String callingPkg, Uri uri, ContentValues[] initialValues) { validateIncomingUri(uri); uri = validateIncomingUri(uri); uri = maybeGetUriWithoutUserId(uri); if (enforceWritePermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) { return 0; Loading @@ -292,11 +293,12 @@ public abstract class ContentProvider implements ComponentCallbacks2 { for (int i = 0; i < numOperations; i++) { ContentProviderOperation operation = operations.get(i); Uri uri = operation.getUri(); validateIncomingUri(uri); userIds[i] = getUserIdFromUri(uri); if (userIds[i] != UserHandle.USER_CURRENT) { // Removing the user id from the uri. operation = new ContentProviderOperation(operation, true); uri = validateIncomingUri(uri); uri = maybeGetUriWithoutUserId(uri); // Rebuild operation if we changed the Uri above if (!Objects.equals(operation.getUri(), uri)) { operation = new ContentProviderOperation(operation, uri); operations.set(i, operation); } if (operation.isReadOperation()) { Loading Loading @@ -331,7 +333,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 { @Override public int delete(String callingPkg, Uri uri, String selection, String[] selectionArgs) { validateIncomingUri(uri); uri = validateIncomingUri(uri); uri = maybeGetUriWithoutUserId(uri); if (enforceWritePermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) { return 0; Loading @@ -347,7 +349,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 { @Override public int update(String callingPkg, Uri uri, ContentValues values, String selection, String[] selectionArgs) { validateIncomingUri(uri); uri = validateIncomingUri(uri); uri = maybeGetUriWithoutUserId(uri); if (enforceWritePermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) { return 0; Loading @@ -364,7 +366,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 { public ParcelFileDescriptor openFile( String callingPkg, Uri uri, String mode, ICancellationSignal cancellationSignal, IBinder callerToken) throws FileNotFoundException { validateIncomingUri(uri); uri = validateIncomingUri(uri); uri = maybeGetUriWithoutUserId(uri); enforceFilePermission(callingPkg, uri, mode, callerToken); final String original = setCallingPackage(callingPkg); Loading @@ -380,7 +382,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 { public AssetFileDescriptor openAssetFile( String callingPkg, Uri uri, String mode, ICancellationSignal cancellationSignal) throws FileNotFoundException { validateIncomingUri(uri); uri = validateIncomingUri(uri); uri = maybeGetUriWithoutUserId(uri); enforceFilePermission(callingPkg, uri, mode, null); final String original = setCallingPackage(callingPkg); Loading @@ -406,7 +408,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 { @Override public String[] getStreamTypes(Uri uri, String mimeTypeFilter) { validateIncomingUri(uri); uri = validateIncomingUri(uri); uri = maybeGetUriWithoutUserId(uri); return ContentProvider.this.getStreamTypes(uri, mimeTypeFilter); } Loading @@ -415,7 +417,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 { public AssetFileDescriptor openTypedAssetFile(String callingPkg, Uri uri, String mimeType, Bundle opts, ICancellationSignal cancellationSignal) throws FileNotFoundException { Bundle.setDefusable(opts, true); validateIncomingUri(uri); uri = validateIncomingUri(uri); uri = maybeGetUriWithoutUserId(uri); enforceFilePermission(callingPkg, uri, "r", null); final String original = setCallingPackage(callingPkg); Loading @@ -434,7 +436,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 { @Override public Uri canonicalize(String callingPkg, Uri uri) { validateIncomingUri(uri); uri = validateIncomingUri(uri); int userId = getUserIdFromUri(uri); uri = getUriWithoutUserId(uri); if (enforceReadPermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) { Loading @@ -450,7 +452,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 { @Override public Uri uncanonicalize(String callingPkg, Uri uri) { validateIncomingUri(uri); uri = validateIncomingUri(uri); int userId = getUserIdFromUri(uri); uri = getUriWithoutUserId(uri); if (enforceReadPermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) { Loading @@ -467,7 +469,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 { @Override public boolean refresh(String callingPkg, Uri uri, Bundle args, ICancellationSignal cancellationSignal) throws RemoteException { validateIncomingUri(uri); uri = validateIncomingUri(uri); uri = getUriWithoutUserId(uri); if (enforceReadPermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) { return false; Loading Loading @@ -1901,7 +1903,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 { */ if (mContext == null) { mContext = context; if (context != null) { if (context != null && mTransport != null) { mTransport.mAppOpsManager = (AppOpsManager) context.getSystemService( Context.APP_OPS_SERVICE); } Loading Loading @@ -2010,7 +2012,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 { } /** @hide */ private void validateIncomingUri(Uri uri) throws SecurityException { public Uri validateIncomingUri(Uri uri) throws SecurityException { String auth = uri.getAuthority(); if (!mSingleUser) { int userId = getUserIdFromAuthority(auth, UserHandle.USER_CURRENT); Loading @@ -2029,6 +2031,19 @@ public abstract class ContentProvider implements ComponentCallbacks2 { } throw new SecurityException(message); } // Normalize the path by removing any empty path segments, which can be // a source of security issues. final String encodedPath = uri.getEncodedPath(); if (encodedPath != null && encodedPath.indexOf("//") != -1) { final Uri normalized = uri.buildUpon() .encodedPath(encodedPath.replaceAll("//+", "/")).build(); Log.w(TAG, "Normalized " + uri + " to " + normalized + " to avoid possible security issues"); return normalized; } else { return uri; } } /** @hide */ Loading
core/java/android/content/ContentProviderOperation.java +2 −14 Original line number Diff line number Diff line Loading @@ -94,13 +94,9 @@ public class ContentProviderOperation implements Parcelable { } /** @hide */ public ContentProviderOperation(ContentProviderOperation cpo, boolean removeUserIdFromUri) { public ContentProviderOperation(ContentProviderOperation cpo, Uri withUri) { mType = cpo.mType; if (removeUserIdFromUri) { mUri = ContentProvider.getUriWithoutUserId(cpo.mUri); } else { mUri = cpo.mUri; } mUri = withUri; mValues = cpo.mValues; mSelection = cpo.mSelection; mSelectionArgs = cpo.mSelectionArgs; Loading @@ -110,14 +106,6 @@ public class ContentProviderOperation implements Parcelable { mYieldAllowed = cpo.mYieldAllowed; } /** @hide */ public ContentProviderOperation getWithoutUserIdInUri() { if (ContentProvider.uriHasUserId(mUri)) { return new ContentProviderOperation(this, true); } return this; } public void writeToParcel(Parcel dest, int flags) { dest.writeInt(mType); Uri.writeToParcel(dest, mUri); Loading