Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e44f60ec authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Require valid authorities for Uri notifications."

parents 80999f79 912e80d3
Loading
Loading
Loading
Loading
+65 −36
Original line number Diff line number Diff line
@@ -500,6 +500,7 @@ public abstract class ContentResolver {
    public ContentResolver(Context context) {
        mContext = context != null ? context : ActivityThread.currentApplication();
        mPackageName = mContext.getOpPackageName();
        mTargetSdkVersion = mContext.getApplicationInfo().targetSdkVersion;
    }

    /** @hide */
@@ -1868,13 +1869,18 @@ public abstract class ContentResolver {
    /**
     * Register an observer class that gets callbacks when data identified by a
     * given content URI changes.
     *
     * @param uri The URI to watch for changes. This can be a specific row URI, or a base URI
     * for a whole class of content.
     * @param notifyForDescendants When false, the observer will be notified whenever a
     * change occurs to the exact URI specified by <code>uri</code> or to one of the
     * URI's ancestors in the path hierarchy.  When true, the observer will also be notified
     * whenever a change occurs to the URI's descendants in the path hierarchy.
     * <p>
     * Starting in {@link android.os.Build.VERSION_CODES#O}, all content
     * notifications must be backed by a valid {@link ContentProvider}.
     *
     * @param uri The URI to watch for changes. This can be a specific row URI,
     *            or a base URI for a whole class of content.
     * @param notifyForDescendants When false, the observer will be notified
     *            whenever a change occurs to the exact URI specified by
     *            <code>uri</code> or to one of the URI's ancestors in the path
     *            hierarchy. When true, the observer will also be notified
     *            whenever a change occurs to the URI's descendants in the path
     *            hierarchy.
     * @param observer The object that receives callbacks when changes occur.
     * @see #unregisterContentObserver
     */
@@ -1894,7 +1900,7 @@ public abstract class ContentResolver {
            ContentObserver observer, @UserIdInt int userHandle) {
        try {
            getContentService().registerContentObserver(uri, notifyForDescendents,
                    observer.getContentObserver(), userHandle);
                    observer.getContentObserver(), userHandle, mTargetSdkVersion);
        } catch (RemoteException e) {
        }
    }
@@ -1918,16 +1924,22 @@ public abstract class ContentResolver {
    }

    /**
     * Notify registered observers that a row was updated and attempt to sync changes
     * to the network.
     * To register, call {@link #registerContentObserver(android.net.Uri , boolean, android.database.ContentObserver) registerContentObserver()}.
     * By default, CursorAdapter objects will get this notification.
     * Notify registered observers that a row was updated and attempt to sync
     * changes to the network.
     * <p>
     * To observe events sent through this call, use
     * {@link #registerContentObserver(Uri, boolean, ContentObserver)}.
     * <p>
     * Starting in {@link android.os.Build.VERSION_CODES#O}, all content
     * notifications must be backed by a valid {@link ContentProvider}.
     *
     * @param uri The uri of the content that was changed.
     * @param observer The observer that originated the change, may be <code>null</null>.
     * The observer that originated the change will only receive the notification if it
     * has requested to receive self-change notifications by implementing
     * {@link ContentObserver#deliverSelfNotifications()} to return true.
     * @param observer The observer that originated the change, may be
     *            <code>null</null>. The observer that originated the change
     *            will only receive the notification if it has requested to
     *            receive self-change notifications by implementing
     *            {@link ContentObserver#deliverSelfNotifications()} to return
     *            true.
     */
    public void notifyChange(@NonNull Uri uri, @Nullable ContentObserver observer) {
        notifyChange(uri, observer, true /* sync to network */);
@@ -1935,17 +1947,25 @@ public abstract class ContentResolver {

    /**
     * Notify registered observers that a row was updated.
     * To register, call {@link #registerContentObserver(android.net.Uri , boolean, android.database.ContentObserver) registerContentObserver()}.
     * By default, CursorAdapter objects will get this notification.
     * If syncToNetwork is true, this will attempt to schedule a local sync using the sync
     * adapter that's registered for the authority of the provided uri. No account will be
     * passed to the sync adapter, so all matching accounts will be synchronized.
     * <p>
     * To observe events sent through this call, use
     * {@link #registerContentObserver(Uri, boolean, ContentObserver)}.
     * <p>
     * If syncToNetwork is true, this will attempt to schedule a local sync
     * using the sync adapter that's registered for the authority of the
     * provided uri. No account will be passed to the sync adapter, so all
     * matching accounts will be synchronized.
     * <p>
     * Starting in {@link android.os.Build.VERSION_CODES#O}, all content
     * notifications must be backed by a valid {@link ContentProvider}.
     *
     * @param uri The uri of the content that was changed.
     * @param observer The observer that originated the change, may be <code>null</null>.
     * The observer that originated the change will only receive the notification if it
     * has requested to receive self-change notifications by implementing
     * {@link ContentObserver#deliverSelfNotifications()} to return true.
     * @param observer The observer that originated the change, may be
     *            <code>null</null>. The observer that originated the change
     *            will only receive the notification if it has requested to
     *            receive self-change notifications by implementing
     *            {@link ContentObserver#deliverSelfNotifications()} to return
     *            true.
     * @param syncToNetwork If true, same as {@link #NOTIFY_SYNC_TO_NETWORK}.
     * @see #requestSync(android.accounts.Account, String, android.os.Bundle)
     */
@@ -1961,17 +1981,25 @@ public abstract class ContentResolver {

    /**
     * Notify registered observers that a row was updated.
     * To register, call {@link #registerContentObserver(android.net.Uri, boolean, android.database.ContentObserver) registerContentObserver()}.
     * By default, CursorAdapter objects will get this notification.
     * If syncToNetwork is true, this will attempt to schedule a local sync using the sync
     * adapter that's registered for the authority of the provided uri. No account will be
     * passed to the sync adapter, so all matching accounts will be synchronized.
     * <p>
     * To observe events sent through this call, use
     * {@link #registerContentObserver(Uri, boolean, ContentObserver)}.
     * <p>
     * If syncToNetwork is true, this will attempt to schedule a local sync
     * using the sync adapter that's registered for the authority of the
     * provided uri. No account will be passed to the sync adapter, so all
     * matching accounts will be synchronized.
     * <p>
     * Starting in {@link android.os.Build.VERSION_CODES#O}, all content
     * notifications must be backed by a valid {@link ContentProvider}.
     *
     * @param uri The uri of the content that was changed.
     * @param observer The observer that originated the change, may be <code>null</null>.
     * The observer that originated the change will only receive the notification if it
     * has requested to receive self-change notifications by implementing
     * {@link ContentObserver#deliverSelfNotifications()} to return true.
     * @param observer The observer that originated the change, may be
     *            <code>null</null>. The observer that originated the change
     *            will only receive the notification if it has requested to
     *            receive self-change notifications by implementing
     *            {@link ContentObserver#deliverSelfNotifications()} to return
     *            true.
     * @param flags Additional flags: {@link #NOTIFY_SYNC_TO_NETWORK}.
     * @see #requestSync(android.accounts.Account, String, android.os.Bundle)
     */
@@ -1997,7 +2025,7 @@ public abstract class ContentResolver {
                    uri, observer == null ? null : observer.getContentObserver(),
                    observer != null && observer.deliverSelfNotifications(),
                    syncToNetwork ? NOTIFY_SYNC_TO_NETWORK : 0,
                    userHandle);
                    userHandle, mTargetSdkVersion);
        } catch (RemoteException e) {
        }
    }
@@ -2013,7 +2041,7 @@ public abstract class ContentResolver {
            getContentService().notifyChange(
                    uri, observer == null ? null : observer.getContentObserver(),
                    observer != null && observer.deliverSelfNotifications(), flags,
                    userHandle);
                    userHandle, mTargetSdkVersion);
        } catch (RemoteException e) {
        }
    }
@@ -2932,6 +2960,7 @@ public abstract class ContentResolver {
    private final Context mContext;

    final String mPackageName;
    final int mTargetSdkVersion;

    private static final String TAG = "ContentResolver";

+2 −2
Original line number Diff line number Diff line
@@ -42,7 +42,7 @@ interface IContentService {
     *     USER_CURRENT are properly handled.
     */
    void registerContentObserver(in Uri uri, boolean notifyForDescendants,
            IContentObserver observer, int userHandle);
            IContentObserver observer, int userHandle, int targetSdkVersion);

    /**
     * Notify observers of a particular user's view of the provider.
@@ -53,7 +53,7 @@ interface IContentService {
     */
    void notifyChange(in Uri uri, IContentObserver observer,
            boolean observerWantsSelfNotifications, int flags,
            int userHandle);
            int userHandle, int targetSdkVersion);

    void requestSync(in Account account, String authority, in Bundle extras);
    /**
+1 −4
Original line number Diff line number Diff line
@@ -10708,10 +10708,7 @@ public class ActivityManagerService extends IActivityManager.Stub
        } catch (RemoteException ignored) {
        }
        if (cpi == null) {
            // TODO: make this an outright failure in a future platform release;
            // until then anonymous content notifications are unprotected
            //return "Failed to find provider " + authority + " for user " + userId;
            return null;
            return "Failed to find provider " + authority + " for user " + userId;
        }
        ProcessRecord r = null;
+28 −9
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@ import android.database.IContentObserver;
import android.database.sqlite.SQLiteException;
import android.net.Uri;
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
import android.os.FactoryTest;
import android.os.IBinder;
@@ -287,7 +288,7 @@ public final class ContentService extends IContentService.Stub {
     */
    @Override
    public void registerContentObserver(Uri uri, boolean notifyForDescendants,
                                        IContentObserver observer, int userHandle) {
            IContentObserver observer, int userHandle, int targetSdkVersion) {
        if (observer == null || uri == null) {
            throw new IllegalArgumentException("You must pass a valid uri and observer");
        }
@@ -301,9 +302,18 @@ public final class ContentService extends IContentService.Stub {
        final String msg = LocalServices.getService(ActivityManagerInternal.class)
                .checkContentProviderAccess(uri.getAuthority(), userHandle);
        if (msg != null) {
            if (targetSdkVersion >= Build.VERSION_CODES.O) {
                throw new SecurityException(msg);
            } else {
                if (msg.startsWith("Failed to find provider")) {
                    // Sigh, we need to quietly let apps targeting older API
                    // levels notify on non-existent providers.
                } else {
                    Log.w(TAG, "Ignoring content changes for " + uri + " from " + uid + ": " + msg);
                    return;
                }
            }
        }

        synchronized (mRootNode) {
            mRootNode.addObserverLocked(uri, observer, notifyForDescendants, mRootNode,
@@ -316,7 +326,7 @@ public final class ContentService extends IContentService.Stub {
    public void registerContentObserver(Uri uri, boolean notifyForDescendants,
                                        IContentObserver observer) {
        registerContentObserver(uri, notifyForDescendants, observer,
                UserHandle.getCallingUserId());
                UserHandle.getCallingUserId(), Build.VERSION_CODES.CUR_DEVELOPMENT);
    }

    @Override
@@ -340,8 +350,8 @@ public final class ContentService extends IContentService.Stub {
     */
    @Override
    public void notifyChange(Uri uri, IContentObserver observer,
                             boolean observerWantsSelfNotifications, int flags,
                             int userHandle) {
            boolean observerWantsSelfNotifications, int flags, int userHandle,
            int targetSdkVersion) {
        if (DEBUG) Slog.d(TAG, "Notifying update of " + uri + " for user " + userHandle
                + " from observer " + observer + ", flags " + Integer.toHexString(flags));

@@ -359,9 +369,18 @@ public final class ContentService extends IContentService.Stub {
        final String msg = LocalServices.getService(ActivityManagerInternal.class)
                .checkContentProviderAccess(uri.getAuthority(), userHandle);
        if (msg != null) {
            if (targetSdkVersion >= Build.VERSION_CODES.O) {
                throw new SecurityException(msg);
            } else {
                if (msg.startsWith("Failed to find provider")) {
                    // Sigh, we need to quietly let apps targeting older API
                    // levels notify on non-existent providers.
                } else {
                    Log.w(TAG, "Ignoring notify for " + uri + " from " + uid + ": " + msg);
                    return;
                }
            }
        }

        // This makes it so that future permission checks will be in the context of this
        // process rather than the caller's process. We will restore this before returning.
@@ -427,7 +446,7 @@ public final class ContentService extends IContentService.Stub {
                             boolean observerWantsSelfNotifications, boolean syncToNetwork) {
        notifyChange(uri, observer, observerWantsSelfNotifications,
                syncToNetwork ? ContentResolver.NOTIFY_SYNC_TO_NETWORK : 0,
                UserHandle.getCallingUserId());
                UserHandle.getCallingUserId(), Build.VERSION_CODES.CUR_DEVELOPMENT);
    }

    /**