Loading services/core/java/com/android/server/am/ActivityManagerService.java +22 −5 Original line number Diff line number Diff line Loading @@ -1175,17 +1175,21 @@ public class ActivityManagerService extends IActivityManager.Stub 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 + "}"; } } Loading Loading @@ -11119,6 +11123,9 @@ public class ActivityManagerService extends IActivityManager.Stub 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: "); Loading Loading @@ -14008,16 +14015,25 @@ public class ActivityManagerService extends IActivityManager.Stub 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); Loading Loading @@ -14895,12 +14911,13 @@ public class ActivityManagerService extends IActivityManager.Stub 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)); } } services/core/java/com/android/server/am/BroadcastRecord.java +29 −2 Original line number Diff line number Diff line Loading @@ -79,6 +79,9 @@ final class BroadcastRecord extends Binder { 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? Loading Loading @@ -330,7 +333,8 @@ final class BroadcastRecord extends Binder { 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); Loading Loading @@ -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, Intent _intent, ProcessRecord _callerApp, String _callerPackage, @Nullable String _callerFeatureId, int _callingPid, int _callingUid, Loading @@ -408,7 +433,7 @@ final class BroadcastRecord extends Binder { 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) { Loading Loading @@ -460,6 +485,7 @@ final class BroadcastRecord extends Binder { interactive = options != null && options.isInteractive(); shareIdentity = options != null && options.isShareIdentityEnabled(); this.filterExtrasForReceiver = filterExtrasForReceiver; this.originalStickyCallingUid = originalStickyCallingUid; } /** Loading Loading @@ -524,6 +550,7 @@ final class BroadcastRecord extends Binder { shareIdentity = from.shareIdentity; urgent = from.urgent; filterExtrasForReceiver = from.filterExtrasForReceiver; originalStickyCallingUid = from.originalStickyCallingUid; } /** Loading services/core/java/com/android/server/am/BroadcastSkipPolicy.java +3 −2 Original line number Diff line number Diff line Loading @@ -563,14 +563,15 @@ public class BroadcastSkipPolicy { // 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"; Loading services/tests/mockingservicestests/src/com/android/server/am/ActivityManagerServiceTest.java +9 −6 Original line number Diff line number Diff line Loading @@ -648,24 +648,24 @@ public class ActivityManagerServiceTest { 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") Loading Loading @@ -698,6 +698,9 @@ public class ActivityManagerServiceTest { if (a.deferUntilActive != b.deferUntilActive) { return false; } if (a.originalCallingUid != b.originalCallingUid) { return false; } return true; } Loading Loading
services/core/java/com/android/server/am/ActivityManagerService.java +22 −5 Original line number Diff line number Diff line Loading @@ -1175,17 +1175,21 @@ public class ActivityManagerService extends IActivityManager.Stub 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 + "}"; } } Loading Loading @@ -11119,6 +11123,9 @@ public class ActivityManagerService extends IActivityManager.Stub 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: "); Loading Loading @@ -14008,16 +14015,25 @@ public class ActivityManagerService extends IActivityManager.Stub 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); Loading Loading @@ -14895,12 +14911,13 @@ public class ActivityManagerService extends IActivityManager.Stub 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)); } }
services/core/java/com/android/server/am/BroadcastRecord.java +29 −2 Original line number Diff line number Diff line Loading @@ -79,6 +79,9 @@ final class BroadcastRecord extends Binder { 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? Loading Loading @@ -330,7 +333,8 @@ final class BroadcastRecord extends Binder { 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); Loading Loading @@ -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, Intent _intent, ProcessRecord _callerApp, String _callerPackage, @Nullable String _callerFeatureId, int _callingPid, int _callingUid, Loading @@ -408,7 +433,7 @@ final class BroadcastRecord extends Binder { 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) { Loading Loading @@ -460,6 +485,7 @@ final class BroadcastRecord extends Binder { interactive = options != null && options.isInteractive(); shareIdentity = options != null && options.isShareIdentityEnabled(); this.filterExtrasForReceiver = filterExtrasForReceiver; this.originalStickyCallingUid = originalStickyCallingUid; } /** Loading Loading @@ -524,6 +550,7 @@ final class BroadcastRecord extends Binder { shareIdentity = from.shareIdentity; urgent = from.urgent; filterExtrasForReceiver = from.filterExtrasForReceiver; originalStickyCallingUid = from.originalStickyCallingUid; } /** Loading
services/core/java/com/android/server/am/BroadcastSkipPolicy.java +3 −2 Original line number Diff line number Diff line Loading @@ -563,14 +563,15 @@ public class BroadcastSkipPolicy { // 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"; Loading
services/tests/mockingservicestests/src/com/android/server/am/ActivityManagerServiceTest.java +9 −6 Original line number Diff line number Diff line Loading @@ -648,24 +648,24 @@ public class ActivityManagerServiceTest { 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") Loading Loading @@ -698,6 +698,9 @@ public class ActivityManagerServiceTest { if (a.deferUntilActive != b.deferUntilActive) { return false; } if (a.originalCallingUid != b.originalCallingUid) { return false; } return true; } Loading