Merge "Make sure stickies get resent from the same UID." into udc-dev am: f45c483022
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/22860109 Change-Id: Ic3c3f57d0588db1609503f15ac6cf164248d96fe Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -1175,17 +1175,21 @@ public class ActivityManagerService extends IActivityManager.Stub
|
|||||||
static final class StickyBroadcast {
|
static final class StickyBroadcast {
|
||||||
public Intent intent;
|
public Intent intent;
|
||||||
public boolean deferUntilActive;
|
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();
|
final StickyBroadcast b = new StickyBroadcast();
|
||||||
b.intent = intent;
|
b.intent = intent;
|
||||||
b.deferUntilActive = deferUntilActive;
|
b.deferUntilActive = deferUntilActive;
|
||||||
|
b.originalCallingUid = originalCallingUid;
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "{intent=" + intent + ", defer=" + deferUntilActive + "}";
|
return "{intent=" + intent + ", defer=" + deferUntilActive + ", originalCallingUid="
|
||||||
|
+ originalCallingUid + "}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -11119,6 +11123,9 @@ public class ActivityManagerService extends IActivityManager.Stub
|
|||||||
pw.print(" [D]");
|
pw.print(" [D]");
|
||||||
}
|
}
|
||||||
pw.println();
|
pw.println();
|
||||||
|
pw.print(" originalCallingUid: ");
|
||||||
|
pw.println(broadcasts.get(i).originalCallingUid);
|
||||||
|
pw.println();
|
||||||
Bundle bundle = intent.getExtras();
|
Bundle bundle = intent.getExtras();
|
||||||
if (bundle != null) {
|
if (bundle != null) {
|
||||||
pw.print(" extras: ");
|
pw.print(" extras: ");
|
||||||
@@ -14008,16 +14015,25 @@ public class ActivityManagerService extends IActivityManager.Stub
|
|||||||
if (allSticky != null) {
|
if (allSticky != null) {
|
||||||
ArrayList receivers = new ArrayList();
|
ArrayList receivers = new ArrayList();
|
||||||
receivers.add(bf);
|
receivers.add(bf);
|
||||||
|
sticky = null;
|
||||||
|
|
||||||
final int stickyCount = allSticky.size();
|
final int stickyCount = allSticky.size();
|
||||||
for (int i = 0; i < stickyCount; i++) {
|
for (int i = 0; i < stickyCount; i++) {
|
||||||
final StickyBroadcast broadcast = allSticky.get(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);
|
BroadcastQueue queue = broadcastQueueForIntent(broadcast.intent);
|
||||||
BroadcastRecord r = new BroadcastRecord(queue, broadcast.intent, null,
|
BroadcastRecord r = new BroadcastRecord(queue, broadcast.intent, null,
|
||||||
null, null, -1, -1, false, null, null, null, null, OP_NONE,
|
null, null, -1, -1, false, null, null, null, null, OP_NONE,
|
||||||
BroadcastOptions.makeWithDeferUntilActive(broadcast.deferUntilActive),
|
BroadcastOptions.makeWithDeferUntilActive(broadcast.deferUntilActive),
|
||||||
receivers, null, null, 0, null, null, false, true, true, -1,
|
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 */,
|
false /* only PRE_BOOT_COMPLETED should be exempt, no stickies */,
|
||||||
null /* filterExtrasForReceiver */);
|
null /* filterExtrasForReceiver */);
|
||||||
queue.enqueueBroadcastLocked(r);
|
queue.enqueueBroadcastLocked(r);
|
||||||
@@ -14895,12 +14911,13 @@ public class ActivityManagerService extends IActivityManager.Stub
|
|||||||
for (i = 0; i < stickiesCount; i++) {
|
for (i = 0; i < stickiesCount; i++) {
|
||||||
if (intent.filterEquals(list.get(i).intent)) {
|
if (intent.filterEquals(list.get(i).intent)) {
|
||||||
// This sticky already exists, replace it.
|
// 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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (i >= stickiesCount) {
|
if (i >= stickiesCount) {
|
||||||
list.add(StickyBroadcast.create(new Intent(intent), deferUntilActive));
|
list.add(StickyBroadcast.create(new Intent(intent), deferUntilActive, callingUid));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -79,6 +79,9 @@ final class BroadcastRecord extends Binder {
|
|||||||
final @Nullable String callerFeatureId; // which feature in the package sent this
|
final @Nullable String callerFeatureId; // which feature in the package sent this
|
||||||
final int callingPid; // the pid of who sent this
|
final int callingPid; // the pid of who sent this
|
||||||
final int callingUid; // the uid 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 callerInstantApp; // caller is an Instant App?
|
||||||
final boolean callerInstrumented; // caller is being instrumented?
|
final boolean callerInstrumented; // caller is being instrumented?
|
||||||
final boolean ordered; // serialize the send to receivers?
|
final boolean ordered; // serialize the send to receivers?
|
||||||
@@ -330,7 +333,8 @@ final class BroadcastRecord extends Binder {
|
|||||||
pw.print(prefix); pw.print("resultAbort="); pw.print(resultAbort);
|
pw.print(prefix); pw.print("resultAbort="); pw.print(resultAbort);
|
||||||
pw.print(" ordered="); pw.print(ordered);
|
pw.print(" ordered="); pw.print(ordered);
|
||||||
pw.print(" sticky="); pw.print(sticky);
|
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) {
|
if (nextReceiver != 0) {
|
||||||
pw.print(prefix); pw.print("nextReceiver="); pw.println(nextReceiver);
|
pw.print(prefix); pw.print("nextReceiver="); pw.println(nextReceiver);
|
||||||
@@ -399,6 +403,27 @@ final class BroadcastRecord extends Binder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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,
|
BroadcastRecord(BroadcastQueue _queue,
|
||||||
Intent _intent, ProcessRecord _callerApp, String _callerPackage,
|
Intent _intent, ProcessRecord _callerApp, String _callerPackage,
|
||||||
@Nullable String _callerFeatureId, int _callingPid, int _callingUid,
|
@Nullable String _callerFeatureId, int _callingPid, int _callingUid,
|
||||||
@@ -408,7 +433,7 @@ final class BroadcastRecord extends Binder {
|
|||||||
BroadcastOptions _options, List _receivers,
|
BroadcastOptions _options, List _receivers,
|
||||||
ProcessRecord _resultToApp, IIntentReceiver _resultTo, int _resultCode,
|
ProcessRecord _resultToApp, IIntentReceiver _resultTo, int _resultCode,
|
||||||
String _resultData, Bundle _resultExtras, boolean _serialized, boolean _sticky,
|
String _resultData, Bundle _resultExtras, boolean _serialized, boolean _sticky,
|
||||||
boolean _initialSticky, int _userId,
|
boolean _initialSticky, int _userId, int originalStickyCallingUid,
|
||||||
@NonNull BackgroundStartPrivileges backgroundStartPrivileges,
|
@NonNull BackgroundStartPrivileges backgroundStartPrivileges,
|
||||||
boolean timeoutExempt,
|
boolean timeoutExempt,
|
||||||
@Nullable BiFunction<Integer, Bundle, Bundle> filterExtrasForReceiver) {
|
@Nullable BiFunction<Integer, Bundle, Bundle> filterExtrasForReceiver) {
|
||||||
@@ -460,6 +485,7 @@ final class BroadcastRecord extends Binder {
|
|||||||
interactive = options != null && options.isInteractive();
|
interactive = options != null && options.isInteractive();
|
||||||
shareIdentity = options != null && options.isShareIdentityEnabled();
|
shareIdentity = options != null && options.isShareIdentityEnabled();
|
||||||
this.filterExtrasForReceiver = filterExtrasForReceiver;
|
this.filterExtrasForReceiver = filterExtrasForReceiver;
|
||||||
|
this.originalStickyCallingUid = originalStickyCallingUid;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -524,6 +550,7 @@ final class BroadcastRecord extends Binder {
|
|||||||
shareIdentity = from.shareIdentity;
|
shareIdentity = from.shareIdentity;
|
||||||
urgent = from.urgent;
|
urgent = from.urgent;
|
||||||
filterExtrasForReceiver = from.filterExtrasForReceiver;
|
filterExtrasForReceiver = from.filterExtrasForReceiver;
|
||||||
|
originalStickyCallingUid = from.originalStickyCallingUid;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -563,14 +563,15 @@ public class BroadcastSkipPolicy {
|
|||||||
|
|
||||||
// Ensure that broadcasts are only sent to other apps if they are explicitly marked as
|
// Ensure that broadcasts are only sent to other apps if they are explicitly marked as
|
||||||
// exported, or are System level broadcasts
|
// exported, or are System level broadcasts
|
||||||
|
final int originalCallingUid = r.sticky ? r.originalStickyCallingUid : r.callingUid;
|
||||||
if (!filter.exported && checkComponentPermission(null, r.callingPid,
|
if (!filter.exported && checkComponentPermission(null, r.callingPid,
|
||||||
r.callingUid, filter.receiverList.uid, filter.exported)
|
originalCallingUid, filter.receiverList.uid, filter.exported)
|
||||||
!= PackageManager.PERMISSION_GRANTED) {
|
!= PackageManager.PERMISSION_GRANTED) {
|
||||||
return "Exported Denial: sending "
|
return "Exported Denial: sending "
|
||||||
+ r.intent.toString()
|
+ r.intent.toString()
|
||||||
+ ", action: " + r.intent.getAction()
|
+ ", action: " + r.intent.getAction()
|
||||||
+ " from " + r.callerPackage
|
+ " from " + r.callerPackage
|
||||||
+ " (uid=" + r.callingUid + ")"
|
+ " (uid=" + originalCallingUid + ")"
|
||||||
+ " due to receiver " + filter.receiverList.app
|
+ " due to receiver " + filter.receiverList.app
|
||||||
+ " (uid " + filter.receiverList.uid + ")"
|
+ " (uid " + filter.receiverList.uid + ")"
|
||||||
+ " not specifying RECEIVER_EXPORTED";
|
+ " not specifying RECEIVER_EXPORTED";
|
||||||
|
|||||||
@@ -648,24 +648,24 @@ public class ActivityManagerServiceTest {
|
|||||||
|
|
||||||
broadcastIntent(intent1, null, true);
|
broadcastIntent(intent1, null, true);
|
||||||
assertStickyBroadcasts(mAms.getStickyBroadcasts(TEST_ACTION1, TEST_USER),
|
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_ACTION2, TEST_USER));
|
||||||
assertNull(mAms.getStickyBroadcasts(TEST_ACTION3, TEST_USER));
|
assertNull(mAms.getStickyBroadcasts(TEST_ACTION3, TEST_USER));
|
||||||
|
|
||||||
broadcastIntent(intent2, options.toBundle(), true);
|
broadcastIntent(intent2, options.toBundle(), true);
|
||||||
assertStickyBroadcasts(mAms.getStickyBroadcasts(TEST_ACTION1, TEST_USER),
|
assertStickyBroadcasts(mAms.getStickyBroadcasts(TEST_ACTION1, TEST_USER),
|
||||||
StickyBroadcast.create(intent1, false));
|
StickyBroadcast.create(intent1, false, Process.myUid()));
|
||||||
assertStickyBroadcasts(mAms.getStickyBroadcasts(TEST_ACTION2, TEST_USER),
|
assertStickyBroadcasts(mAms.getStickyBroadcasts(TEST_ACTION2, TEST_USER),
|
||||||
StickyBroadcast.create(intent2, true));
|
StickyBroadcast.create(intent2, true, Process.myUid()));
|
||||||
assertNull(mAms.getStickyBroadcasts(TEST_ACTION3, TEST_USER));
|
assertNull(mAms.getStickyBroadcasts(TEST_ACTION3, TEST_USER));
|
||||||
|
|
||||||
broadcastIntent(intent3, null, true);
|
broadcastIntent(intent3, null, true);
|
||||||
assertStickyBroadcasts(mAms.getStickyBroadcasts(TEST_ACTION1, TEST_USER),
|
assertStickyBroadcasts(mAms.getStickyBroadcasts(TEST_ACTION1, TEST_USER),
|
||||||
StickyBroadcast.create(intent1, false));
|
StickyBroadcast.create(intent1, false, Process.myUid()));
|
||||||
assertStickyBroadcasts(mAms.getStickyBroadcasts(TEST_ACTION2, TEST_USER),
|
assertStickyBroadcasts(mAms.getStickyBroadcasts(TEST_ACTION2, TEST_USER),
|
||||||
StickyBroadcast.create(intent2, true));
|
StickyBroadcast.create(intent2, true, Process.myUid()));
|
||||||
assertStickyBroadcasts(mAms.getStickyBroadcasts(TEST_ACTION3, TEST_USER),
|
assertStickyBroadcasts(mAms.getStickyBroadcasts(TEST_ACTION3, TEST_USER),
|
||||||
StickyBroadcast.create(intent3, false));
|
StickyBroadcast.create(intent3, false, Process.myUid()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("GuardedBy")
|
@SuppressWarnings("GuardedBy")
|
||||||
@@ -698,6 +698,9 @@ public class ActivityManagerServiceTest {
|
|||||||
if (a.deferUntilActive != b.deferUntilActive) {
|
if (a.deferUntilActive != b.deferUntilActive) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (a.originalCallingUid != b.originalCallingUid) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user