Merge "Make sure stickies get resent from the same UID." into udc-dev
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 658e664..544828a 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -1175,17 +1175,21 @@
static final class StickyBroadcast {
public Intent intent;
public boolean deferUntilActive;
+ public int originalCallingUid;
- public static StickyBroadcast create(Intent intent, boolean deferUntilActive) {
+ public static StickyBroadcast create(Intent intent, boolean deferUntilActive,
+ int originalCallingUid) {
final StickyBroadcast b = new StickyBroadcast();
b.intent = intent;
b.deferUntilActive = deferUntilActive;
+ b.originalCallingUid = originalCallingUid;
return b;
}
@Override
public String toString() {
- return "{intent=" + intent + ", defer=" + deferUntilActive + "}";
+ return "{intent=" + intent + ", defer=" + deferUntilActive + ", originalCallingUid="
+ + originalCallingUid + "}";
}
}
@@ -11119,6 +11123,9 @@
pw.print(" [D]");
}
pw.println();
+ pw.print(" originalCallingUid: ");
+ pw.println(broadcasts.get(i).originalCallingUid);
+ pw.println();
Bundle bundle = intent.getExtras();
if (bundle != null) {
pw.print(" extras: ");
@@ -14008,16 +14015,25 @@
if (allSticky != null) {
ArrayList receivers = new ArrayList();
receivers.add(bf);
+ sticky = null;
final int stickyCount = allSticky.size();
for (int i = 0; i < stickyCount; i++) {
final StickyBroadcast broadcast = allSticky.get(i);
+ final int originalStickyCallingUid = allSticky.get(i).originalCallingUid;
+ // TODO(b/281889567): consider using checkComponentPermission instead of
+ // canAccessUnexportedComponents
+ if (sticky == null && (exported || originalStickyCallingUid == callingUid
+ || ActivityManager.canAccessUnexportedComponents(
+ originalStickyCallingUid))) {
+ sticky = broadcast.intent;
+ }
BroadcastQueue queue = broadcastQueueForIntent(broadcast.intent);
BroadcastRecord r = new BroadcastRecord(queue, broadcast.intent, null,
null, null, -1, -1, false, null, null, null, null, OP_NONE,
BroadcastOptions.makeWithDeferUntilActive(broadcast.deferUntilActive),
receivers, null, null, 0, null, null, false, true, true, -1,
- BackgroundStartPrivileges.NONE,
+ originalStickyCallingUid, BackgroundStartPrivileges.NONE,
false /* only PRE_BOOT_COMPLETED should be exempt, no stickies */,
null /* filterExtrasForReceiver */);
queue.enqueueBroadcastLocked(r);
@@ -14895,12 +14911,13 @@
for (i = 0; i < stickiesCount; i++) {
if (intent.filterEquals(list.get(i).intent)) {
// This sticky already exists, replace it.
- list.set(i, StickyBroadcast.create(new Intent(intent), deferUntilActive));
+ list.set(i, StickyBroadcast.create(new Intent(intent), deferUntilActive,
+ callingUid));
break;
}
}
if (i >= stickiesCount) {
- list.add(StickyBroadcast.create(new Intent(intent), deferUntilActive));
+ list.add(StickyBroadcast.create(new Intent(intent), deferUntilActive, callingUid));
}
}
diff --git a/services/core/java/com/android/server/am/BroadcastRecord.java b/services/core/java/com/android/server/am/BroadcastRecord.java
index a9274408..a402db9 100644
--- a/services/core/java/com/android/server/am/BroadcastRecord.java
+++ b/services/core/java/com/android/server/am/BroadcastRecord.java
@@ -79,6 +79,9 @@
final @Nullable String callerFeatureId; // which feature in the package sent this
final int callingPid; // the pid of who sent this
final int callingUid; // the uid of who sent this
+
+ final int originalStickyCallingUid;
+ // if this is a sticky broadcast, the Uid of the original sender
final boolean callerInstantApp; // caller is an Instant App?
final boolean callerInstrumented; // caller is being instrumented?
final boolean ordered; // serialize the send to receivers?
@@ -330,7 +333,8 @@
pw.print(prefix); pw.print("resultAbort="); pw.print(resultAbort);
pw.print(" ordered="); pw.print(ordered);
pw.print(" sticky="); pw.print(sticky);
- pw.print(" initialSticky="); pw.println(initialSticky);
+ pw.print(" initialSticky="); pw.print(initialSticky);
+ pw.print(" originalStickyCallingUid="); pw.println(originalStickyCallingUid);
}
if (nextReceiver != 0) {
pw.print(prefix); pw.print("nextReceiver="); pw.println(nextReceiver);
@@ -399,6 +403,27 @@
}
}
+ BroadcastRecord(BroadcastQueue queue,
+ Intent intent, ProcessRecord callerApp, String callerPackage,
+ @Nullable String callerFeatureId, int callingPid, int callingUid,
+ boolean callerInstantApp, String resolvedType,
+ String[] requiredPermissions, String[] excludedPermissions,
+ String[] excludedPackages, int appOp,
+ BroadcastOptions options, List receivers,
+ ProcessRecord resultToApp, IIntentReceiver resultTo, int resultCode,
+ String resultData, Bundle resultExtras, boolean serialized, boolean sticky,
+ boolean initialSticky, int userId,
+ @NonNull BackgroundStartPrivileges backgroundStartPrivileges,
+ boolean timeoutExempt,
+ @Nullable BiFunction<Integer, Bundle, Bundle> filterExtrasForReceiver) {
+ this(queue, intent, callerApp, callerPackage, callerFeatureId, callingPid,
+ callingUid, callerInstantApp, resolvedType, requiredPermissions,
+ excludedPermissions, excludedPackages, appOp, options, receivers, resultToApp,
+ resultTo, resultCode, resultData, resultExtras, serialized, sticky,
+ initialSticky, userId, -1, backgroundStartPrivileges, timeoutExempt,
+ filterExtrasForReceiver);
+ }
+
BroadcastRecord(BroadcastQueue _queue,
Intent _intent, ProcessRecord _callerApp, String _callerPackage,
@Nullable String _callerFeatureId, int _callingPid, int _callingUid,
@@ -408,7 +433,7 @@
BroadcastOptions _options, List _receivers,
ProcessRecord _resultToApp, IIntentReceiver _resultTo, int _resultCode,
String _resultData, Bundle _resultExtras, boolean _serialized, boolean _sticky,
- boolean _initialSticky, int _userId,
+ boolean _initialSticky, int _userId, int originalStickyCallingUid,
@NonNull BackgroundStartPrivileges backgroundStartPrivileges,
boolean timeoutExempt,
@Nullable BiFunction<Integer, Bundle, Bundle> filterExtrasForReceiver) {
@@ -460,6 +485,7 @@
interactive = options != null && options.isInteractive();
shareIdentity = options != null && options.isShareIdentityEnabled();
this.filterExtrasForReceiver = filterExtrasForReceiver;
+ this.originalStickyCallingUid = originalStickyCallingUid;
}
/**
@@ -524,6 +550,7 @@
shareIdentity = from.shareIdentity;
urgent = from.urgent;
filterExtrasForReceiver = from.filterExtrasForReceiver;
+ originalStickyCallingUid = from.originalStickyCallingUid;
}
/**
diff --git a/services/core/java/com/android/server/am/BroadcastSkipPolicy.java b/services/core/java/com/android/server/am/BroadcastSkipPolicy.java
index 6718319..5f918cf 100644
--- a/services/core/java/com/android/server/am/BroadcastSkipPolicy.java
+++ b/services/core/java/com/android/server/am/BroadcastSkipPolicy.java
@@ -563,14 +563,15 @@
// Ensure that broadcasts are only sent to other apps if they are explicitly marked as
// exported, or are System level broadcasts
+ final int originalCallingUid = r.sticky ? r.originalStickyCallingUid : r.callingUid;
if (!filter.exported && checkComponentPermission(null, r.callingPid,
- r.callingUid, filter.receiverList.uid, filter.exported)
+ originalCallingUid, filter.receiverList.uid, filter.exported)
!= PackageManager.PERMISSION_GRANTED) {
return "Exported Denial: sending "
+ r.intent.toString()
+ ", action: " + r.intent.getAction()
+ " from " + r.callerPackage
- + " (uid=" + r.callingUid + ")"
+ + " (uid=" + originalCallingUid + ")"
+ " due to receiver " + filter.receiverList.app
+ " (uid " + filter.receiverList.uid + ")"
+ " not specifying RECEIVER_EXPORTED";
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/ActivityManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/am/ActivityManagerServiceTest.java
index f82d246..bfe7d7f 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/ActivityManagerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/ActivityManagerServiceTest.java
@@ -648,24 +648,24 @@
broadcastIntent(intent1, null, true);
assertStickyBroadcasts(mAms.getStickyBroadcasts(TEST_ACTION1, TEST_USER),
- StickyBroadcast.create(intent1, false));
+ StickyBroadcast.create(intent1, false, Process.myUid()));
assertNull(mAms.getStickyBroadcasts(TEST_ACTION2, TEST_USER));
assertNull(mAms.getStickyBroadcasts(TEST_ACTION3, TEST_USER));
broadcastIntent(intent2, options.toBundle(), true);
assertStickyBroadcasts(mAms.getStickyBroadcasts(TEST_ACTION1, TEST_USER),
- StickyBroadcast.create(intent1, false));
+ StickyBroadcast.create(intent1, false, Process.myUid()));
assertStickyBroadcasts(mAms.getStickyBroadcasts(TEST_ACTION2, TEST_USER),
- StickyBroadcast.create(intent2, true));
+ StickyBroadcast.create(intent2, true, Process.myUid()));
assertNull(mAms.getStickyBroadcasts(TEST_ACTION3, TEST_USER));
broadcastIntent(intent3, null, true);
assertStickyBroadcasts(mAms.getStickyBroadcasts(TEST_ACTION1, TEST_USER),
- StickyBroadcast.create(intent1, false));
+ StickyBroadcast.create(intent1, false, Process.myUid()));
assertStickyBroadcasts(mAms.getStickyBroadcasts(TEST_ACTION2, TEST_USER),
- StickyBroadcast.create(intent2, true));
+ StickyBroadcast.create(intent2, true, Process.myUid()));
assertStickyBroadcasts(mAms.getStickyBroadcasts(TEST_ACTION3, TEST_USER),
- StickyBroadcast.create(intent3, false));
+ StickyBroadcast.create(intent3, false, Process.myUid()));
}
@SuppressWarnings("GuardedBy")
@@ -698,6 +698,9 @@
if (a.deferUntilActive != b.deferUntilActive) {
return false;
}
+ if (a.originalCallingUid != b.originalCallingUid) {
+ return false;
+ }
return true;
}