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

Commit b7e34d55 authored by Chad Brubaker's avatar Chad Brubaker
Browse files

Only send exposed broadcasts to Instant Apps

In order to prevent Instant Apps from receiving potentially sensitive
broadcasts they will only receive those that the sender explicitly
exposes to Instant Apps by setting
Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS.

Bug:33350280
Test: `adb shell am broadcast` does not get delivered to Instant App
Test: `adb shell am broadcast -f 0x0x200000` gets delivered to Instant
App
Test: Verified that an Instant App can send a broadcast to itself
without FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS
Change-Id: Ie363448bf224abba530dd4caf69258939fff00af
parent 748bf772
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -9313,6 +9313,7 @@ package android.content {
    field public static final int FLAG_RECEIVER_NO_ABORT = 134217728; // 0x8000000
    field public static final int FLAG_RECEIVER_NO_ABORT = 134217728; // 0x8000000
    field public static final int FLAG_RECEIVER_REGISTERED_ONLY = 1073741824; // 0x40000000
    field public static final int FLAG_RECEIVER_REGISTERED_ONLY = 1073741824; // 0x40000000
    field public static final int FLAG_RECEIVER_REPLACE_PENDING = 536870912; // 0x20000000
    field public static final int FLAG_RECEIVER_REPLACE_PENDING = 536870912; // 0x20000000
    field public static final int FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS = 2097152; // 0x200000
    field public static final java.lang.String METADATA_DOCK_HOME = "android.dock_home";
    field public static final java.lang.String METADATA_DOCK_HOME = "android.dock_home";
    field public static final int URI_ALLOW_UNSAFE = 4; // 0x4
    field public static final int URI_ALLOW_UNSAFE = 4; // 0x4
    field public static final int URI_ANDROID_APP_SCHEME = 2; // 0x2
    field public static final int URI_ANDROID_APP_SCHEME = 2; // 0x2
+1 −0
Original line number Original line Diff line number Diff line
@@ -9843,6 +9843,7 @@ package android.content {
    field public static final int FLAG_RECEIVER_NO_ABORT = 134217728; // 0x8000000
    field public static final int FLAG_RECEIVER_NO_ABORT = 134217728; // 0x8000000
    field public static final int FLAG_RECEIVER_REGISTERED_ONLY = 1073741824; // 0x40000000
    field public static final int FLAG_RECEIVER_REGISTERED_ONLY = 1073741824; // 0x40000000
    field public static final int FLAG_RECEIVER_REPLACE_PENDING = 536870912; // 0x20000000
    field public static final int FLAG_RECEIVER_REPLACE_PENDING = 536870912; // 0x20000000
    field public static final int FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS = 2097152; // 0x200000
    field public static final java.lang.String METADATA_DOCK_HOME = "android.dock_home";
    field public static final java.lang.String METADATA_DOCK_HOME = "android.dock_home";
    field public static final int URI_ALLOW_UNSAFE = 4; // 0x4
    field public static final int URI_ALLOW_UNSAFE = 4; // 0x4
    field public static final int URI_ANDROID_APP_SCHEME = 2; // 0x2
    field public static final int URI_ANDROID_APP_SCHEME = 2; // 0x2
+1 −0
Original line number Original line Diff line number Diff line
@@ -9343,6 +9343,7 @@ package android.content {
    field public static final int FLAG_RECEIVER_NO_ABORT = 134217728; // 0x8000000
    field public static final int FLAG_RECEIVER_NO_ABORT = 134217728; // 0x8000000
    field public static final int FLAG_RECEIVER_REGISTERED_ONLY = 1073741824; // 0x40000000
    field public static final int FLAG_RECEIVER_REGISTERED_ONLY = 1073741824; // 0x40000000
    field public static final int FLAG_RECEIVER_REPLACE_PENDING = 536870912; // 0x20000000
    field public static final int FLAG_RECEIVER_REPLACE_PENDING = 536870912; // 0x20000000
    field public static final int FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS = 2097152; // 0x200000
    field public static final java.lang.String METADATA_DOCK_HOME = "android.dock_home";
    field public static final java.lang.String METADATA_DOCK_HOME = "android.dock_home";
    field public static final int URI_ALLOW_UNSAFE = 4; // 0x4
    field public static final int URI_ALLOW_UNSAFE = 4; // 0x4
    field public static final int URI_ANDROID_APP_SCHEME = 2; // 0x2
    field public static final int URI_ANDROID_APP_SCHEME = 2; // 0x2
+8 −0
Original line number Original line Diff line number Diff line
@@ -4976,6 +4976,14 @@ public class Intent implements Parcelable, Cloneable {
     */
     */
    public static final int FLAG_RECEIVER_FROM_SHELL = 0x00400000;
    public static final int FLAG_RECEIVER_FROM_SHELL = 0x00400000;


    /**
     * If set, the broadcast will be visible to receivers in Instant Apps. By default Instant Apps
     * will not receive broadcasts.
     *
     * <em>This flag has no effect when used by an Instant App.</em>
     */
    public static final int FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS = 0x00200000;

    /**
    /**
     * @hide Flags that can't be changed with PendingIntent.
     * @hide Flags that can't be changed with PendingIntent.
     */
     */
+33 −1
Original line number Original line Diff line number Diff line
@@ -17987,6 +17987,25 @@ public class ActivityManagerService extends IActivityManager.Stub
    // BROADCASTS
    // BROADCASTS
    // =========================================================
    // =========================================================
    private boolean isInstantApp(ProcessRecord record, String callerPackage, int uid) {
        if (UserHandle.getAppId(uid) < Process.FIRST_APPLICATION_UID) {
            return false;
        }
        // Easy case -- we have the app's ProcessRecord.
        if (record != null) {
            return record.info.isInstantApp();
        }
        // Otherwise check with PackageManager.
        mAppOpsService.checkPackage(uid, callerPackage);
        try {
            IPackageManager pm = AppGlobals.getPackageManager();
            return pm.isInstantApp(callerPackage, UserHandle.getUserId(uid));
        } catch (RemoteException e) {
            Slog.e(TAG, "Error looking up if " + callerPackage + " is an instant app.", e);
            return true;
        }
    }
    boolean isPendingBroadcastProcessLocked(int pid) {
    boolean isPendingBroadcastProcessLocked(int pid) {
        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
@@ -18015,6 +18034,7 @@ public class ActivityManagerService extends IActivityManager.Stub
        ProcessRecord callerApp = null;
        ProcessRecord callerApp = null;
        int callingUid;
        int callingUid;
        int callingPid;
        int callingPid;
        boolean instantApp;
        synchronized(this) {
        synchronized(this) {
            if (caller != null) {
            if (caller != null) {
                callerApp = getRecordForAppLocked(caller);
                callerApp = getRecordForAppLocked(caller);
@@ -18038,6 +18058,7 @@ public class ActivityManagerService extends IActivityManager.Stub
                callingPid = Binder.getCallingPid();
                callingPid = Binder.getCallingPid();
            }
            }
            instantApp = isInstantApp(callerApp, callerPackage, callingUid);
            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
@@ -18073,6 +18094,11 @@ public class ActivityManagerService extends IActivityManager.Stub
            // Look for any matching sticky broadcasts...
            // Look for any matching sticky broadcasts...
            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
                Intent intent = stickyIntents.get(i);
                Intent intent = stickyIntents.get(i);
                // Don't provided intents that aren't available to instant apps.
                if (instantApp &&
                        (intent.getFlags() & Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS) == 0) {
                    continue;
                }
                // If intent has scheme "content", it will need to acccess
                // If intent has scheme "content", it will need to acccess
                // provider that needs to lock mProviderMap in ActivityThread
                // provider that needs to lock mProviderMap in ActivityThread
                // and also it may need to wait application response, so we
                // and also it may need to wait application response, so we
@@ -18131,7 +18157,7 @@ public class ActivityManagerService extends IActivityManager.Stub
                        + " callerPackage is " + callerPackage);
                        + " callerPackage is " + callerPackage);
            }
            }
            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
                    permission, callingUid, userId);
                    permission, callingUid, userId, instantApp);
            rl.add(bf);
            rl.add(bf);
            if (!bf.debugCheck()) {
            if (!bf.debugCheck()) {
                Slog.w(TAG, "==> For Dynamic broadcast");
                Slog.w(TAG, "==> For Dynamic broadcast");
@@ -18390,6 +18416,12 @@ public class ActivityManagerService extends IActivityManager.Stub
            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
        intent = new Intent(intent);
        intent = new Intent(intent);
        final boolean callerInstantApp = isInstantApp(callerApp, callerPackage, callingUid);
        // Instant Apps cannot use FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS
        if (callerInstantApp) {
            intent.setFlags(intent.getFlags() & ~Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
        }
        // By default broadcasts do not go to stopped apps.
        // By default broadcasts do not go to stopped apps.
        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
Loading