From 3ce2e87452ebec95ab7801d2c2bb1eb31dbaf40a Mon Sep 17 00:00:00 2001 From: Chad Brubaker Date: Thu, 1 Apr 2021 16:55:50 +0000 Subject: [PATCH] Reorder Broadcast checks Permission checking for a broadcast delivery results in a noteOp against the application, this should be the last check to avoid "blaming" the application for a broadcast that is skipped for other reasons (such as background restrictions). Fixes: 184262933 Test: build, flash Change-Id: I8912243c3d6c8cddedc6375c613c22491c13fef2 --- .../com/android/server/am/BroadcastQueue.java | 155 +++++++++--------- 1 file changed, 80 insertions(+), 75 deletions(-) diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java index 7f2eae8ff1538..a5474d0b8c72c 100644 --- a/services/core/java/com/android/server/am/BroadcastQueue.java +++ b/services/core/java/com/android/server/am/BroadcastQueue.java @@ -638,6 +638,7 @@ public final class BroadcastQueue { + filter); skip = true; } + // Check that the sender has permission to send to this receiver if (filter.requiredPermission != null) { int perm = mService.checkComponentPermission(filter.requiredPermission, r.callingPid, r.callingUid, -1, true); @@ -666,6 +667,46 @@ public final class BroadcastQueue { } } } + + if (!skip && (filter.receiverList.app == null || filter.receiverList.app.isKilled() + || filter.receiverList.app.mErrorState.isCrashing())) { + Slog.w(TAG, "Skipping deliver [" + mQueueName + "] " + r + + " to " + filter.receiverList + ": process gone or crashing"); + skip = true; + } + + // Ensure that broadcasts are only sent to other Instant Apps if they are marked as + // visible to Instant Apps. + final boolean visibleToInstantApps = + (r.intent.getFlags() & Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS) != 0; + + if (!skip && !visibleToInstantApps && filter.instantApp + && 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 + ")" + + " due to sender " + r.callerPackage + + " (uid " + r.callingUid + ")" + + " not specifying FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS"); + 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; + } + + // Check that the receiver has the required permission(s) to receive this broadcast. if (!skip && r.requiredPermissions != null && r.requiredPermissions.length > 0) { for (int i = 0; i < r.requiredPermissions.length; i++) { String requiredPermission = r.requiredPermissions[i]; @@ -717,6 +758,7 @@ public final class BroadcastQueue { skip = true; } } + // If the broadcast also requires an app op check that as well. if (!skip && r.appOp != AppOpsManager.OP_NONE && mService.getAppOpsManager().noteOpNoThrow(r.appOp, filter.receiverList.uid, filter.packageName, filter.featureId, @@ -733,44 +775,6 @@ public final class BroadcastQueue { skip = true; } - if (!skip && (filter.receiverList.app == null || filter.receiverList.app.isKilled() - || filter.receiverList.app.mErrorState.isCrashing())) { - Slog.w(TAG, "Skipping deliver [" + mQueueName + "] " + r - + " to " + filter.receiverList + ": process gone or crashing"); - skip = true; - } - - // Ensure that broadcasts are only sent to other Instant Apps if they are marked as - // visible to Instant Apps. - final boolean visibleToInstantApps = - (r.intent.getFlags() & Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS) != 0; - - if (!skip && !visibleToInstantApps && filter.instantApp - && 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 + ")" - + " due to sender " + r.callerPackage - + " (uid " + r.callingUid + ")" - + " not specifying FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS"); - 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; @@ -1415,43 +1419,6 @@ public final class BroadcastQueue { skip = true; } } - if (!skip && info.activityInfo.applicationInfo.uid != Process.SYSTEM_UID && - r.requiredPermissions != null && r.requiredPermissions.length > 0) { - for (int i = 0; i < r.requiredPermissions.length; i++) { - String requiredPermission = r.requiredPermissions[i]; - try { - perm = AppGlobals.getPackageManager(). - checkPermission(requiredPermission, - info.activityInfo.applicationInfo.packageName, - UserHandle - .getUserId(info.activityInfo.applicationInfo.uid)); - } catch (RemoteException e) { - perm = PackageManager.PERMISSION_DENIED; - } - if (perm != PackageManager.PERMISSION_GRANTED) { - Slog.w(TAG, "Permission Denial: receiving " - + r.intent + " to " - + component.flattenToShortString() - + " requires " + requiredPermission - + " due to sender " + r.callerPackage - + " (uid " + r.callingUid + ")"); - skip = true; - break; - } - int appOp = AppOpsManager.permissionToOpCode(requiredPermission); - if (appOp != AppOpsManager.OP_NONE && appOp != r.appOp) { - if (!noteOpForManifestReceiver(appOp, r, info, component)) { - skip = true; - break; - } - } - } - } - if (!skip && r.appOp != AppOpsManager.OP_NONE) { - if (!noteOpForManifestReceiver(r.appOp, r, info, component)) { - skip = true; - } - } boolean isSingleton = false; try { isSingleton = mService.isSingleton(info.activityInfo.processName, @@ -1586,6 +1553,44 @@ public final class BroadcastQueue { + info.activityInfo.applicationInfo.uid + " : user is not running"); } + if (!skip && info.activityInfo.applicationInfo.uid != Process.SYSTEM_UID && + r.requiredPermissions != null && r.requiredPermissions.length > 0) { + for (int i = 0; i < r.requiredPermissions.length; i++) { + String requiredPermission = r.requiredPermissions[i]; + try { + perm = AppGlobals.getPackageManager(). + checkPermission(requiredPermission, + info.activityInfo.applicationInfo.packageName, + UserHandle + .getUserId(info.activityInfo.applicationInfo.uid)); + } catch (RemoteException e) { + perm = PackageManager.PERMISSION_DENIED; + } + if (perm != PackageManager.PERMISSION_GRANTED) { + Slog.w(TAG, "Permission Denial: receiving " + + r.intent + " to " + + component.flattenToShortString() + + " requires " + requiredPermission + + " due to sender " + r.callerPackage + + " (uid " + r.callingUid + ")"); + skip = true; + break; + } + int appOp = AppOpsManager.permissionToOpCode(requiredPermission); + if (appOp != AppOpsManager.OP_NONE && appOp != r.appOp) { + if (!noteOpForManifestReceiver(appOp, r, info, component)) { + skip = true; + break; + } + } + } + } + if (!skip && r.appOp != AppOpsManager.OP_NONE) { + if (!noteOpForManifestReceiver(r.appOp, r, info, component)) { + skip = true; + } + } + if (skip) { if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Skipping delivery of ordered [" + mQueueName + "] "