Enforce visibleToInstantApps for receivers
Instant apps can only send broadcasts to receivers that are declared in
the manifest with android:visibleToInstantApps=true or if the app
registers a receiver at runtime using the new methods that take
visibleToInstantApps.
Bug:33350280
Test: Manually sending broadcasts from Instant Apps only goes to
receivers with visibleToInstantApps set to true.
Test: Receiving a broadcast from within the same app does not require
visibleToInstantApps to be set.
Change-Id: I54d79a502ba9c5fd03ede3c09e08afc88fe2775f
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index a957c70..20ee30d 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -18028,7 +18028,8 @@
}
public Intent registerReceiver(IApplicationThread caller, String callerPackage,
- IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
+ IIntentReceiver receiver, IntentFilter filter, String permission, int userId,
+ boolean visibleToInstantApps) {
enforceNotIsolatedCaller("registerReceiver");
ArrayList<Intent> stickyIntents = null;
ProcessRecord callerApp = null;
@@ -18157,7 +18158,7 @@
+ " callerPackage is " + callerPackage);
}
BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
- permission, callingUid, userId, instantApp);
+ permission, callingUid, userId, instantApp, visibleToInstantApps);
rl.add(bf);
if (!bf.debugCheck()) {
Slog.w(TAG, "==> For Dynamic broadcast");
@@ -18175,7 +18176,7 @@
Intent intent = allSticky.get(i);
BroadcastQueue queue = broadcastQueueForIntent(intent);
BroadcastRecord r = new BroadcastRecord(queue, intent, null,
- null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
+ null, -1, -1, false, null, null, AppOpsManager.OP_NONE, null, receivers,
null, 0, null, null, false, true, true, -1);
queue.enqueueParallelBroadcastLocked(r);
queue.scheduleBroadcastsLocked();
@@ -18911,9 +18912,9 @@
}
final BroadcastQueue queue = broadcastQueueForIntent(intent);
BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
- callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
- appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
- resultExtras, ordered, sticky, false, userId);
+ callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
+ requiredPermissions, appOp, brOptions, registeredReceivers, resultTo,
+ resultCode, resultData, resultExtras, ordered, sticky, false, userId);
if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
final boolean replaced = replacePending
&& (queue.replaceParallelBroadcastLocked(r) != null);
@@ -19007,7 +19008,7 @@
|| resultTo != null) {
BroadcastQueue queue = broadcastQueueForIntent(intent);
BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
- callerPackage, callingPid, callingUid, resolvedType,
+ callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
resultData, resultExtras, ordered, sticky, false, userId);
diff --git a/services/core/java/com/android/server/am/BroadcastFilter.java b/services/core/java/com/android/server/am/BroadcastFilter.java
index a06a21f..f96b06f 100644
--- a/services/core/java/com/android/server/am/BroadcastFilter.java
+++ b/services/core/java/com/android/server/am/BroadcastFilter.java
@@ -30,10 +30,11 @@
final int owningUid;
final int owningUserId;
final boolean instantApp;
+ final boolean visibleToInstantApp;
BroadcastFilter(IntentFilter _filter, ReceiverList _receiverList,
String _packageName, String _requiredPermission, int _owningUid, int _userId,
- boolean _instantApp) {
+ boolean _instantApp, boolean _visibleToInstantApp) {
super(_filter);
receiverList = _receiverList;
packageName = _packageName;
@@ -41,6 +42,7 @@
owningUid = _owningUid;
owningUserId = _userId;
instantApp = _instantApp;
+ visibleToInstantApp = _visibleToInstantApp;
}
public void dump(PrintWriter pw, String prefix) {
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index 629f80d..2787895 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -641,6 +641,19 @@
skip = true;
}
+ if (!skip && !filter.visibleToInstantApp && r.callerInstantApp
+ && filter.receiverList.uid != r.callingUid) {
+ Slog.w(TAG, "Instant App Denial: receiving "
+ + r.intent.toString()
+ + " to " + filter.receiverList.app
+ + " (pid=" + filter.receiverList.pid
+ + ", uid=" + filter.receiverList.uid + ")"
+ + " requires receiver be visible to instant apps"
+ + " due to sender " + r.callerPackage
+ + " (uid " + r.callingUid + ")");
+ skip = true;
+ }
+
if (skip) {
r.delivery[index] = BroadcastRecord.DELIVERY_SKIPPED;
return;
@@ -1152,6 +1165,17 @@
+ " not specifying FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS");
skip = true;
}
+ if (!skip && r.callerInstantApp
+ && (info.activityInfo.flags & ActivityInfo.FLAG_VISIBLE_TO_EPHEMERAL) == 0
+ && r.callingUid != info.activityInfo.applicationInfo.uid) {
+ Slog.w(TAG, "Instant App Denial: receiving "
+ + r.intent
+ + " to " + component.flattenToShortString()
+ + " requires receiver have visibleToInstantApps set"
+ + " due to sender " + r.callerPackage
+ + " (uid " + r.callingUid + ")");
+ skip = true;
+ }
if (!skip) {
r.manifestCount++;
} else {
diff --git a/services/core/java/com/android/server/am/BroadcastRecord.java b/services/core/java/com/android/server/am/BroadcastRecord.java
index 1e7911a..7764be7 100644
--- a/services/core/java/com/android/server/am/BroadcastRecord.java
+++ b/services/core/java/com/android/server/am/BroadcastRecord.java
@@ -48,6 +48,7 @@
final String callerPackage; // who sent this
final int callingPid; // the pid of who sent this
final int callingUid; // the uid of who sent this
+ final boolean callerInstantApp; // caller is an Instant App?
final boolean ordered; // serialize the send to receivers?
final boolean sticky; // originated from existing sticky data?
final boolean initialSticky; // initial broadcast from register to sticky?
@@ -214,11 +215,10 @@
BroadcastRecord(BroadcastQueue _queue,
Intent _intent, ProcessRecord _callerApp, String _callerPackage,
- int _callingPid, int _callingUid, String _resolvedType, String[] _requiredPermissions,
- int _appOp, BroadcastOptions _options, List _receivers, IIntentReceiver _resultTo,
- int _resultCode, String _resultData, Bundle _resultExtras, boolean _serialized,
- boolean _sticky, boolean _initialSticky,
- int _userId) {
+ int _callingPid, int _callingUid, boolean _callerInstantApp, String _resolvedType,
+ String[] _requiredPermissions, int _appOp, BroadcastOptions _options, List _receivers,
+ IIntentReceiver _resultTo, int _resultCode, String _resultData, Bundle _resultExtras,
+ boolean _serialized, boolean _sticky, boolean _initialSticky, int _userId) {
if (_intent == null) {
throw new NullPointerException("Can't construct with a null intent");
}
@@ -229,6 +229,7 @@
callerPackage = _callerPackage;
callingPid = _callingPid;
callingUid = _callingUid;
+ callerInstantApp = _callerInstantApp;
resolvedType = _resolvedType;
requiredPermissions = _requiredPermissions;
appOp = _appOp;