1 /* 2 * Copyright (C) 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.am; 18 19 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW; 20 import static com.android.server.am.ActivityManagerService.checkComponentPermission; 21 import static com.android.server.am.BroadcastQueue.TAG; 22 23 import android.annotation.NonNull; 24 import android.annotation.Nullable; 25 import android.app.ActivityManager; 26 import android.app.AppGlobals; 27 import android.app.AppOpsManager; 28 import android.app.BroadcastOptions; 29 import android.app.PendingIntent; 30 import android.content.AttributionSource; 31 import android.content.ComponentName; 32 import android.content.IIntentSender; 33 import android.content.Intent; 34 import android.content.IntentSender; 35 import android.content.pm.ActivityInfo; 36 import android.content.pm.PackageManager; 37 import android.content.pm.PermissionInfo; 38 import android.content.pm.ResolveInfo; 39 import android.os.Process; 40 import android.os.RemoteException; 41 import android.os.UserHandle; 42 import android.permission.IPermissionManager; 43 import android.permission.PermissionManager; 44 import android.util.Slog; 45 46 import com.android.internal.util.ArrayUtils; 47 48 import java.util.Objects; 49 50 /** 51 * Policy logic that decides if delivery of a particular {@link BroadcastRecord} 52 * should be skipped for a given {@link ResolveInfo} or {@link BroadcastFilter}. 53 * <p> 54 * This policy should be consulted as close as possible to the actual dispatch. 55 */ 56 public class BroadcastSkipPolicy { 57 private final ActivityManagerService mService; 58 59 @Nullable 60 private PermissionManager mPermissionManager; 61 BroadcastSkipPolicy(@onNull ActivityManagerService service)62 public BroadcastSkipPolicy(@NonNull ActivityManagerService service) { 63 mService = Objects.requireNonNull(service); 64 } 65 66 /** 67 * Determine if the given {@link BroadcastRecord} is eligible to be sent to 68 * the given {@link BroadcastFilter} or {@link ResolveInfo}. 69 * 70 * @return message indicating why the argument should be skipped, otherwise 71 * {@code null} if it can proceed. 72 */ shouldSkipMessage(@onNull BroadcastRecord r, @NonNull Object target)73 public @Nullable String shouldSkipMessage(@NonNull BroadcastRecord r, @NonNull Object target) { 74 return shouldSkipMessage(r, target, false /* preflight */); 75 } 76 shouldSkipAtEnqueueMessage(@onNull BroadcastRecord r, @NonNull Object target)77 public @Nullable String shouldSkipAtEnqueueMessage(@NonNull BroadcastRecord r, 78 @NonNull Object target) { 79 return shouldSkipMessage(r, target, true /* preflight */); 80 } 81 shouldSkipMessage(@onNull BroadcastRecord r, @NonNull Object target, boolean preflight)82 private @Nullable String shouldSkipMessage(@NonNull BroadcastRecord r, @NonNull Object target, 83 boolean preflight) { 84 if (target instanceof BroadcastFilter) { 85 return shouldSkipMessage(r, (BroadcastFilter) target, preflight); 86 } else { 87 return shouldSkipMessage(r, (ResolveInfo) target, preflight); 88 } 89 } 90 91 /** 92 * Determine if the given {@link BroadcastRecord} is eligible to be sent to 93 * the given {@link ResolveInfo}. 94 * 95 * @return message indicating why the argument should be skipped, otherwise 96 * {@code null} if it can proceed. 97 */ shouldSkipMessage(@onNull BroadcastRecord r, @NonNull ResolveInfo info, boolean preflight)98 private @Nullable String shouldSkipMessage(@NonNull BroadcastRecord r, 99 @NonNull ResolveInfo info, boolean preflight) { 100 final BroadcastOptions brOptions = r.options; 101 final ComponentName component = new ComponentName( 102 info.activityInfo.applicationInfo.packageName, 103 info.activityInfo.name); 104 105 if (brOptions != null && 106 (info.activityInfo.applicationInfo.targetSdkVersion 107 < brOptions.getMinManifestReceiverApiLevel() || 108 info.activityInfo.applicationInfo.targetSdkVersion 109 > brOptions.getMaxManifestReceiverApiLevel())) { 110 return "Target SDK mismatch: receiver " + info.activityInfo 111 + " targets " + info.activityInfo.applicationInfo.targetSdkVersion 112 + " but delivery restricted to [" 113 + brOptions.getMinManifestReceiverApiLevel() + ", " 114 + brOptions.getMaxManifestReceiverApiLevel() 115 + "] broadcasting " + broadcastDescription(r, component); 116 } 117 if (brOptions != null && 118 !brOptions.testRequireCompatChange(info.activityInfo.applicationInfo.uid)) { 119 return "Compat change filtered: broadcasting " + broadcastDescription(r, component) 120 + " to uid " + info.activityInfo.applicationInfo.uid + " due to compat change " 121 + r.options.getRequireCompatChangeId(); 122 } 123 if (!mService.validateAssociationAllowedLocked(r.callerPackage, r.callingUid, 124 component.getPackageName(), info.activityInfo.applicationInfo.uid)) { 125 return "Association not allowed: broadcasting " 126 + broadcastDescription(r, component); 127 } 128 if (!mService.mIntentFirewall.checkBroadcast(r.intent, r.callingUid, 129 r.callingPid, r.resolvedType, info.activityInfo.applicationInfo.uid)) { 130 return "Firewall blocked: broadcasting " 131 + broadcastDescription(r, component); 132 } 133 int perm = checkComponentPermission(info.activityInfo.permission, 134 r.callingPid, r.callingUid, info.activityInfo.applicationInfo.uid, 135 info.activityInfo.exported); 136 if (perm != PackageManager.PERMISSION_GRANTED) { 137 if (!info.activityInfo.exported) { 138 return "Permission Denial: broadcasting " 139 + broadcastDescription(r, component) 140 + " is not exported from uid " + info.activityInfo.applicationInfo.uid; 141 } else { 142 return "Permission Denial: broadcasting " 143 + broadcastDescription(r, component) 144 + " requires " + info.activityInfo.permission; 145 } 146 } else if (info.activityInfo.permission != null) { 147 final String op = AppOpsManager.permissionToOp(info.activityInfo.permission); 148 if (op != null) { 149 final int mode; 150 if (preflight) { 151 mode = mService.getAppOpsManager().checkOpNoThrow(op, 152 r.callingUid, r.callerPackage, r.callerFeatureId); 153 } else { 154 mode = mService.getAppOpsManager().noteOpNoThrow(op, 155 r.callingUid, r.callerPackage, r.callerFeatureId, 156 "Broadcast delivered to " + info.activityInfo.name); 157 } 158 if (mode != AppOpsManager.MODE_ALLOWED) { 159 return "Appop Denial: broadcasting " 160 + broadcastDescription(r, component) 161 + " requires appop " + AppOpsManager.permissionToOp( 162 info.activityInfo.permission); 163 } 164 } 165 } 166 167 if ((info.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 168 if (ActivityManager.checkUidPermission( 169 android.Manifest.permission.INTERACT_ACROSS_USERS, 170 info.activityInfo.applicationInfo.uid) 171 != PackageManager.PERMISSION_GRANTED) { 172 return "Permission Denial: Receiver " + component.flattenToShortString() 173 + " requests FLAG_SINGLE_USER, but app does not hold " 174 + android.Manifest.permission.INTERACT_ACROSS_USERS; 175 } 176 } 177 if (info.activityInfo.applicationInfo.isInstantApp() 178 && r.callingUid != info.activityInfo.applicationInfo.uid) { 179 return "Instant App Denial: receiving " 180 + r.intent 181 + " to " + component.flattenToShortString() 182 + " due to sender " + r.callerPackage 183 + " (uid " + r.callingUid + ")" 184 + " Instant Apps do not support manifest receivers"; 185 } 186 if (r.callerInstantApp 187 && (info.activityInfo.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0 188 && r.callingUid != info.activityInfo.applicationInfo.uid) { 189 return "Instant App Denial: receiving " 190 + r.intent 191 + " to " + component.flattenToShortString() 192 + " requires receiver have visibleToInstantApps set" 193 + " due to sender " + r.callerPackage 194 + " (uid " + r.callingUid + ")"; 195 } 196 if (r.curApp != null && r.curApp.mErrorState.isCrashing()) { 197 // If the target process is crashing, just skip it. 198 return "Skipping deliver ordered [" + r.queue.toString() + "] " + r 199 + " to " + r.curApp + ": process crashing"; 200 } 201 202 boolean isAvailable = false; 203 try { 204 isAvailable = AppGlobals.getPackageManager().isPackageAvailable( 205 info.activityInfo.packageName, 206 UserHandle.getUserId(info.activityInfo.applicationInfo.uid)); 207 } catch (Exception e) { 208 // all such failures mean we skip this receiver 209 return "Exception getting recipient info for " 210 + info.activityInfo.packageName; 211 } 212 if (!isAvailable) { 213 return "Skipping delivery to " + info.activityInfo.packageName + " / " 214 + info.activityInfo.applicationInfo.uid 215 + " : package no longer available"; 216 } 217 218 // If permissions need a review before any of the app components can run, we drop 219 // the broadcast and if the calling app is in the foreground and the broadcast is 220 // explicit we launch the review UI passing it a pending intent to send the skipped 221 // broadcast. 222 if (!requestStartTargetPermissionsReviewIfNeededLocked(r, 223 info.activityInfo.packageName, UserHandle.getUserId( 224 info.activityInfo.applicationInfo.uid))) { 225 return "Skipping delivery: permission review required for " 226 + broadcastDescription(r, component); 227 } 228 229 final int allowed = mService.getAppStartModeLOSP( 230 info.activityInfo.applicationInfo.uid, info.activityInfo.packageName, 231 info.activityInfo.applicationInfo.targetSdkVersion, -1, true, false, false); 232 if (allowed != ActivityManager.APP_START_MODE_NORMAL) { 233 // We won't allow this receiver to be launched if the app has been 234 // completely disabled from launches, or it was not explicitly sent 235 // to it and the app is in a state that should not receive it 236 // (depending on how getAppStartModeLOSP has determined that). 237 if (allowed == ActivityManager.APP_START_MODE_DISABLED) { 238 return "Background execution disabled: receiving " 239 + r.intent + " to " 240 + component.flattenToShortString(); 241 } else if (disallowBackgroundStart(r)) { 242 mService.addBackgroundCheckViolationLocked(r.intent.getAction(), 243 component.getPackageName()); 244 return "Background execution not allowed: receiving " 245 + r.intent + " to " 246 + component.flattenToShortString(); 247 } 248 } 249 250 if (!Intent.ACTION_SHUTDOWN.equals(r.intent.getAction()) 251 && !mService.mUserController 252 .isUserRunning(UserHandle.getUserId(info.activityInfo.applicationInfo.uid), 253 0 /* flags */)) { 254 return "Skipping delivery to " + info.activityInfo.packageName + " / " 255 + info.activityInfo.applicationInfo.uid + " : user is not running"; 256 } 257 258 if (r.excludedPermissions != null && r.excludedPermissions.length > 0) { 259 for (int i = 0; i < r.excludedPermissions.length; i++) { 260 String excludedPermission = r.excludedPermissions[i]; 261 try { 262 perm = AppGlobals.getPackageManager() 263 .checkPermission(excludedPermission, 264 info.activityInfo.applicationInfo.packageName, 265 UserHandle 266 .getUserId(info.activityInfo.applicationInfo.uid)); 267 } catch (RemoteException e) { 268 perm = PackageManager.PERMISSION_DENIED; 269 } 270 271 final String appOp = AppOpsManager.permissionToOp(excludedPermission); 272 if (appOp != null) { 273 // When there is an app op associated with the permission, 274 // skip when both the permission and the app op are 275 // granted. 276 if ((perm == PackageManager.PERMISSION_GRANTED) && ( 277 mService.getAppOpsManager().checkOpNoThrow(appOp, 278 info.activityInfo.applicationInfo.uid, 279 info.activityInfo.packageName) 280 == AppOpsManager.MODE_ALLOWED)) { 281 return "Skipping delivery to " + info.activityInfo.packageName 282 + " due to excluded permission " + excludedPermission; 283 } 284 } else { 285 // When there is no app op associated with the permission, 286 // skip when permission is granted. 287 if (perm == PackageManager.PERMISSION_GRANTED) { 288 return "Skipping delivery to " + info.activityInfo.packageName 289 + " due to excluded permission " + excludedPermission; 290 } 291 } 292 } 293 } 294 295 // Check that the receiver does *not* belong to any of the excluded packages 296 if (r.excludedPackages != null && r.excludedPackages.length > 0) { 297 if (ArrayUtils.contains(r.excludedPackages, component.getPackageName())) { 298 return "Skipping delivery of excluded package " 299 + r.intent + " to " 300 + component.flattenToShortString() 301 + " excludes package " + component.getPackageName() 302 + " due to sender " + r.callerPackage 303 + " (uid " + r.callingUid + ")"; 304 } 305 } 306 307 if (info.activityInfo.applicationInfo.uid != Process.SYSTEM_UID && 308 r.requiredPermissions != null && r.requiredPermissions.length > 0) { 309 final AttributionSource[] attributionSources = 310 createAttributionSourcesForResolveInfo(info); 311 for (int i = 0; i < r.requiredPermissions.length; i++) { 312 String requiredPermission = r.requiredPermissions[i]; 313 perm = hasPermission( 314 requiredPermission, 315 "Broadcast delivered to " + info.activityInfo.name, 316 preflight, 317 attributionSources) 318 ? PackageManager.PERMISSION_GRANTED 319 : PackageManager.PERMISSION_DENIED; 320 if (perm != PackageManager.PERMISSION_GRANTED) { 321 return "Permission Denial: receiving " 322 + r.intent + " to " 323 + component.flattenToShortString() 324 + " requires " + requiredPermission 325 + " due to sender " + r.callerPackage 326 + " (uid " + r.callingUid + ")"; 327 } 328 } 329 } 330 if (r.appOp != AppOpsManager.OP_NONE && AppOpsManager.isValidOp(r.appOp)) { 331 final String op = AppOpsManager.opToPublicName(r.appOp); 332 final boolean appOpAllowed = preflight 333 ? checkOpForManifestReceiver(r.appOp, op, r, info, component) 334 : noteOpForManifestReceiver(r.appOp, op, r, info, component); 335 if (!appOpAllowed) { 336 return "Skipping delivery to " + info.activityInfo.packageName 337 + " due to required appop " + AppOpsManager.opToName(r.appOp); 338 } 339 } 340 341 return null; 342 } 343 344 /** 345 * Determine if the given {@link BroadcastRecord} is eligible to launch processes. 346 */ disallowBackgroundStart(@onNull BroadcastRecord r)347 public boolean disallowBackgroundStart(@NonNull BroadcastRecord r) { 348 return ((r.intent.getFlags() & Intent.FLAG_RECEIVER_EXCLUDE_BACKGROUND) != 0) 349 || (r.intent.getComponent() == null 350 && r.intent.getPackage() == null 351 && ((r.intent.getFlags() 352 & Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND) == 0) 353 && !isSignaturePerm(r.requiredPermissions)); 354 } 355 356 /** 357 * Determine if the given {@link BroadcastRecord} is eligible to be sent to 358 * the given {@link BroadcastFilter}. 359 * 360 * @return message indicating why the argument should be skipped, otherwise 361 * {@code null} if it can proceed. 362 */ shouldSkipMessage(@onNull BroadcastRecord r, @NonNull BroadcastFilter filter, boolean preflight)363 private @Nullable String shouldSkipMessage(@NonNull BroadcastRecord r, 364 @NonNull BroadcastFilter filter, boolean preflight) { 365 if (r.options != null && !r.options.testRequireCompatChange(filter.owningUid)) { 366 return "Compat change filtered: broadcasting " + r.intent.toString() 367 + " to uid " + filter.owningUid + " due to compat change " 368 + r.options.getRequireCompatChangeId(); 369 } 370 if (!mService.validateAssociationAllowedLocked(r.callerPackage, r.callingUid, 371 filter.packageName, filter.owningUid)) { 372 return "Association not allowed: broadcasting " 373 + r.intent.toString() 374 + " from " + r.callerPackage + " (pid=" + r.callingPid 375 + ", uid=" + r.callingUid + ") to " + filter.packageName + " through " 376 + filter; 377 } 378 if (!mService.mIntentFirewall.checkBroadcast(r.intent, r.callingUid, 379 r.callingPid, r.resolvedType, filter.receiverList.uid)) { 380 return "Firewall blocked: broadcasting " 381 + r.intent.toString() 382 + " from " + r.callerPackage + " (pid=" + r.callingPid 383 + ", uid=" + r.callingUid + ") to " + filter.packageName + " through " 384 + filter; 385 } 386 // Check that the sender has permission to send to this receiver 387 if (filter.requiredPermission != null) { 388 int perm = checkComponentPermission(filter.requiredPermission, 389 r.callingPid, r.callingUid, -1, true); 390 if (perm != PackageManager.PERMISSION_GRANTED) { 391 return "Permission Denial: broadcasting " 392 + r.intent.toString() 393 + " from " + r.callerPackage + " (pid=" 394 + r.callingPid + ", uid=" + r.callingUid + ")" 395 + " requires " + filter.requiredPermission 396 + " due to registered receiver " + filter; 397 } else { 398 final String op = AppOpsManager.permissionToOp(filter.requiredPermission); 399 if (op != null) { 400 final int mode; 401 if (preflight) { 402 mode = mService.getAppOpsManager().checkOpNoThrow(op, 403 r.callingUid, r.callerPackage, r.callerFeatureId); 404 } else { 405 mode = mService.getAppOpsManager().noteOpNoThrow(op, r.callingUid, 406 r.callerPackage, r.callerFeatureId, 407 "Broadcast sent to protected receiver"); 408 } 409 if (mode != AppOpsManager.MODE_ALLOWED) { 410 return "Appop Denial: broadcasting " 411 + r.intent 412 + " from " + r.callerPackage + " (pid=" 413 + r.callingPid + ", uid=" + r.callingUid + ")" 414 + " requires appop " + op 415 + " due to registered receiver " + filter; 416 } 417 } 418 } 419 } 420 421 if ((filter.receiverList.app == null || filter.receiverList.app.isKilled() 422 || filter.receiverList.app.mErrorState.isCrashing())) { 423 return "Skipping deliver [" + r.queue.toString() + "] " + r 424 + " to " + filter.receiverList + ": process gone or crashing"; 425 } 426 427 // Ensure that broadcasts are only sent to other Instant Apps if they are marked as 428 // visible to Instant Apps. 429 final boolean visibleToInstantApps = 430 (r.intent.getFlags() & Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS) != 0; 431 432 if (!visibleToInstantApps && filter.instantApp 433 && filter.receiverList.uid != r.callingUid) { 434 return "Instant App Denial: receiving " 435 + r.intent.toString() 436 + " to " + filter.receiverList.app 437 + " (pid=" + filter.receiverList.pid 438 + ", uid=" + filter.receiverList.uid + ")" 439 + " due to sender " + r.callerPackage 440 + " (uid " + r.callingUid + ")" 441 + " not specifying FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS"; 442 } 443 444 if (!filter.visibleToInstantApp && r.callerInstantApp 445 && filter.receiverList.uid != r.callingUid) { 446 return "Instant App Denial: receiving " 447 + r.intent.toString() 448 + " to " + filter.receiverList.app 449 + " (pid=" + filter.receiverList.pid 450 + ", uid=" + filter.receiverList.uid + ")" 451 + " requires receiver be visible to instant apps" 452 + " due to sender " + r.callerPackage 453 + " (uid " + r.callingUid + ")"; 454 } 455 456 // Check that the receiver has the required permission(s) to receive this broadcast. 457 if (r.requiredPermissions != null && r.requiredPermissions.length > 0) { 458 final AttributionSource attributionSource = 459 new AttributionSource.Builder(filter.receiverList.uid) 460 .setPid(filter.receiverList.pid) 461 .setPackageName(filter.packageName) 462 .setAttributionTag(filter.featureId) 463 .build(); 464 for (int i = 0; i < r.requiredPermissions.length; i++) { 465 String requiredPermission = r.requiredPermissions[i]; 466 final int perm = hasPermission( 467 requiredPermission, 468 "Broadcast delivered to registered receiver " + filter.receiverId, 469 preflight, 470 attributionSource) 471 ? PackageManager.PERMISSION_GRANTED 472 : PackageManager.PERMISSION_DENIED; 473 if (perm != PackageManager.PERMISSION_GRANTED) { 474 return "Permission Denial: receiving " 475 + r.intent.toString() 476 + " to " + filter.receiverList.app 477 + " (pid=" + filter.receiverList.pid 478 + ", uid=" + filter.receiverList.uid + ")" 479 + " requires " + requiredPermission 480 + " due to sender " + r.callerPackage 481 + " (uid " + r.callingUid + ")"; 482 } 483 } 484 } 485 if ((r.requiredPermissions == null || r.requiredPermissions.length == 0)) { 486 int perm = checkComponentPermission(null, 487 filter.receiverList.pid, filter.receiverList.uid, -1, true); 488 if (perm != PackageManager.PERMISSION_GRANTED) { 489 return "Permission Denial: security check failed when receiving " 490 + r.intent.toString() 491 + " to " + filter.receiverList.app 492 + " (pid=" + filter.receiverList.pid 493 + ", uid=" + filter.receiverList.uid + ")" 494 + " due to sender " + r.callerPackage 495 + " (uid " + r.callingUid + ")"; 496 } 497 } 498 // Check that the receiver does *not* have any excluded permissions 499 if (r.excludedPermissions != null && r.excludedPermissions.length > 0) { 500 for (int i = 0; i < r.excludedPermissions.length; i++) { 501 String excludedPermission = r.excludedPermissions[i]; 502 final int perm = checkComponentPermission(excludedPermission, 503 filter.receiverList.pid, filter.receiverList.uid, -1, true); 504 505 final String appOp = AppOpsManager.permissionToOp(excludedPermission); 506 if (appOp != null) { 507 // When there is an app op associated with the permission, 508 // skip when both the permission and the app op are 509 // granted. 510 if ((perm == PackageManager.PERMISSION_GRANTED) && ( 511 mService.getAppOpsManager().checkOpNoThrow(appOp, 512 filter.receiverList.uid, 513 filter.packageName) 514 == AppOpsManager.MODE_ALLOWED)) { 515 return "Appop Denial: receiving " 516 + r.intent 517 + " to " + filter.receiverList.app 518 + " (pid=" + filter.receiverList.pid 519 + ", uid=" + filter.receiverList.uid + ")" 520 + " excludes appop " + appOp 521 + " due to sender " + r.callerPackage 522 + " (uid " + r.callingUid + ")"; 523 } 524 } else { 525 // When there is no app op associated with the permission, 526 // skip when permission is granted. 527 if (perm == PackageManager.PERMISSION_GRANTED) { 528 return "Permission Denial: receiving " 529 + r.intent 530 + " to " + filter.receiverList.app 531 + " (pid=" + filter.receiverList.pid 532 + ", uid=" + filter.receiverList.uid + ")" 533 + " excludes " + excludedPermission 534 + " due to sender " + r.callerPackage 535 + " (uid " + r.callingUid + ")"; 536 } 537 } 538 } 539 } 540 541 // Check that the receiver does *not* belong to any of the excluded packages 542 if (r.excludedPackages != null && r.excludedPackages.length > 0) { 543 if (ArrayUtils.contains(r.excludedPackages, filter.packageName)) { 544 return "Skipping delivery of excluded package " 545 + r.intent.toString() 546 + " to " + filter.receiverList.app 547 + " (pid=" + filter.receiverList.pid 548 + ", uid=" + filter.receiverList.uid + ")" 549 + " excludes package " + filter.packageName 550 + " due to sender " + r.callerPackage 551 + " (uid " + r.callingUid + ")"; 552 } 553 } 554 555 // If the broadcast also requires an app op check that as well. 556 if (r.appOp != AppOpsManager.OP_NONE && AppOpsManager.isValidOp(r.appOp)) { 557 final String op = AppOpsManager.opToPublicName(r.appOp); 558 final int mode; 559 if (preflight) { 560 mode = mService.getAppOpsManager().checkOpNoThrow(op, 561 filter.receiverList.uid, filter.packageName, filter.featureId); 562 } else { 563 mode = mService.getAppOpsManager().noteOpNoThrow(op, 564 filter.receiverList.uid, filter.packageName, filter.featureId, 565 "Broadcast delivered to registered receiver " + filter.receiverId); 566 } 567 if (mode != AppOpsManager.MODE_ALLOWED) { 568 return "Appop Denial: receiving " 569 + r.intent 570 + " to " + filter.receiverList.app 571 + " (pid=" + filter.receiverList.pid 572 + ", uid=" + filter.receiverList.uid + ")" 573 + " requires appop " + AppOpsManager.opToName(r.appOp) 574 + " due to sender " + r.callerPackage 575 + " (uid " + r.callingUid + ")"; 576 } 577 } 578 579 // Ensure that broadcasts are only sent to other apps if they are explicitly marked as 580 // exported, or are System level broadcasts 581 final int originalCallingUid = r.sticky ? r.originalStickyCallingUid : r.callingUid; 582 if (!filter.exported && checkComponentPermission(null, r.callingPid, 583 originalCallingUid, filter.receiverList.uid, filter.exported) 584 != PackageManager.PERMISSION_GRANTED) { 585 return "Exported Denial: sending " 586 + r.intent.toString() 587 + ", action: " + r.intent.getAction() 588 + " from " + r.callerPackage 589 + " (uid=" + originalCallingUid + ")" 590 + " due to receiver " + filter.receiverList.app 591 + " (uid " + filter.receiverList.uid + ")" 592 + " not specifying RECEIVER_EXPORTED"; 593 } 594 595 // If permissions need a review before any of the app components can run, we drop 596 // the broadcast and if the calling app is in the foreground and the broadcast is 597 // explicit we launch the review UI passing it a pending intent to send the skipped 598 // broadcast. 599 if (!requestStartTargetPermissionsReviewIfNeededLocked(r, filter.packageName, 600 filter.owningUserId)) { 601 return "Skipping delivery to " + filter.packageName + " due to permissions review"; 602 } 603 604 return null; 605 } 606 broadcastDescription(BroadcastRecord r, ComponentName component)607 private static String broadcastDescription(BroadcastRecord r, ComponentName component) { 608 return r.intent.toString() 609 + " from " + r.callerPackage + " (pid=" + r.callingPid 610 + ", uid=" + r.callingUid + ") to " + component.flattenToShortString(); 611 } 612 noteOpForManifestReceiver(int opCode, String appOp, BroadcastRecord r, ResolveInfo info, ComponentName component)613 private boolean noteOpForManifestReceiver(int opCode, String appOp, BroadcastRecord r, 614 ResolveInfo info, ComponentName component) { 615 if (ArrayUtils.isEmpty(info.activityInfo.attributionTags)) { 616 return noteOpForManifestReceiverInner(opCode, appOp, r, info, component, null); 617 } else { 618 // Attribution tags provided, noteOp each tag 619 for (String tag : info.activityInfo.attributionTags) { 620 if (!noteOpForManifestReceiverInner(opCode, appOp, r, info, component, tag)) { 621 return false; 622 } 623 } 624 return true; 625 } 626 } 627 noteOpForManifestReceiverInner(int opCode, String appOp, BroadcastRecord r, ResolveInfo info, ComponentName component, String tag)628 private boolean noteOpForManifestReceiverInner(int opCode, String appOp, BroadcastRecord r, 629 ResolveInfo info, ComponentName component, String tag) { 630 if (mService.getAppOpsManager().noteOpNoThrow(appOp, 631 info.activityInfo.applicationInfo.uid, 632 info.activityInfo.packageName, 633 tag, 634 "Broadcast delivered to " + info.activityInfo.name) 635 != AppOpsManager.MODE_ALLOWED) { 636 Slog.w(TAG, "Appop Denial: receiving " 637 + r.intent + " to " 638 + component.flattenToShortString() 639 + " requires appop " + AppOpsManager.opToName(opCode) 640 + " due to sender " + r.callerPackage 641 + " (uid " + r.callingUid + ")"); 642 return false; 643 } 644 return true; 645 } 646 checkOpForManifestReceiver(int opCode, String appOp, BroadcastRecord r, ResolveInfo info, ComponentName component)647 private boolean checkOpForManifestReceiver(int opCode, String appOp, BroadcastRecord r, 648 ResolveInfo info, ComponentName component) { 649 if (ArrayUtils.isEmpty(info.activityInfo.attributionTags)) { 650 return checkOpForManifestReceiverInner(opCode, appOp, r, info, component, null); 651 } else { 652 // Attribution tags provided, noteOp each tag 653 for (String tag : info.activityInfo.attributionTags) { 654 if (!checkOpForManifestReceiverInner(opCode, appOp, r, info, component, tag)) { 655 return false; 656 } 657 } 658 return true; 659 } 660 } 661 checkOpForManifestReceiverInner(int opCode, String appOp, BroadcastRecord r, ResolveInfo info, ComponentName component, String tag)662 private boolean checkOpForManifestReceiverInner(int opCode, String appOp, BroadcastRecord r, 663 ResolveInfo info, ComponentName component, String tag) { 664 if (mService.getAppOpsManager().checkOpNoThrow(appOp, info.activityInfo.applicationInfo.uid, 665 info.activityInfo.packageName, tag) != AppOpsManager.MODE_ALLOWED) { 666 Slog.w(TAG, "Appop Denial: receiving " 667 + r.intent + " to " 668 + component.flattenToShortString() 669 + " requires appop " + AppOpsManager.opToName(opCode) 670 + " due to sender " + r.callerPackage 671 + " (uid " + r.callingUid + ")"); 672 return false; 673 } 674 return true; 675 } 676 677 /** 678 * Return true if all given permissions are signature-only perms. 679 */ isSignaturePerm(String[] perms)680 private static boolean isSignaturePerm(String[] perms) { 681 if (perms == null) { 682 return false; 683 } 684 IPermissionManager pm = AppGlobals.getPermissionManager(); 685 for (int i = perms.length-1; i >= 0; i--) { 686 try { 687 PermissionInfo pi = pm.getPermissionInfo(perms[i], "android", 0); 688 if (pi == null) { 689 // a required permission that no package has actually 690 // defined cannot be signature-required. 691 return false; 692 } 693 if ((pi.protectionLevel & (PermissionInfo.PROTECTION_MASK_BASE 694 | PermissionInfo.PROTECTION_FLAG_PRIVILEGED)) 695 != PermissionInfo.PROTECTION_SIGNATURE) { 696 // If this a signature permission and NOT allowed for privileged apps, it 697 // is okay... otherwise, nope! 698 return false; 699 } 700 } catch (RemoteException e) { 701 return false; 702 } 703 } 704 return true; 705 } 706 requestStartTargetPermissionsReviewIfNeededLocked( BroadcastRecord receiverRecord, String receivingPackageName, final int receivingUserId)707 private boolean requestStartTargetPermissionsReviewIfNeededLocked( 708 BroadcastRecord receiverRecord, String receivingPackageName, 709 final int receivingUserId) { 710 if (!mService.getPackageManagerInternal().isPermissionsReviewRequired( 711 receivingPackageName, receivingUserId)) { 712 return true; 713 } 714 715 final boolean callerForeground = receiverRecord.callerApp != null 716 ? receiverRecord.callerApp.mState.getSetSchedGroup() 717 != ProcessList.SCHED_GROUP_BACKGROUND : true; 718 719 // Show a permission review UI only for explicit broadcast from a foreground app 720 if (callerForeground && receiverRecord.intent.getComponent() != null) { 721 IIntentSender target = mService.mPendingIntentController.getIntentSender( 722 ActivityManager.INTENT_SENDER_BROADCAST, receiverRecord.callerPackage, 723 receiverRecord.callerFeatureId, receiverRecord.callingUid, 724 receiverRecord.userId, null, null, 0, 725 new Intent[]{receiverRecord.intent}, 726 new String[]{receiverRecord.intent.resolveType(mService.mContext 727 .getContentResolver())}, 728 PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT 729 | PendingIntent.FLAG_IMMUTABLE, null); 730 731 final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS); 732 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK 733 | Intent.FLAG_ACTIVITY_MULTIPLE_TASK 734 | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 735 intent.putExtra(Intent.EXTRA_PACKAGE_NAME, receivingPackageName); 736 intent.putExtra(Intent.EXTRA_INTENT, new IntentSender(target)); 737 738 if (DEBUG_PERMISSIONS_REVIEW) { 739 Slog.i(TAG, "u" + receivingUserId + " Launching permission review for package " 740 + receivingPackageName); 741 } 742 743 mService.mHandler.post(new Runnable() { 744 @Override 745 public void run() { 746 mService.mContext.startActivityAsUser(intent, new UserHandle(receivingUserId)); 747 } 748 }); 749 } else { 750 Slog.w(TAG, "u" + receivingUserId + " Receiving a broadcast in package" 751 + receivingPackageName + " requires a permissions review"); 752 } 753 754 return false; 755 } 756 757 @Nullable getPermissionManager()758 private PermissionManager getPermissionManager() { 759 if (mPermissionManager == null) { 760 mPermissionManager = mService.mContext.getSystemService(PermissionManager.class); 761 } 762 return mPermissionManager; 763 } 764 hasPermission( @onNull String permission, @NonNull String message, boolean preflight, @NonNull AttributionSource... attributionSources)765 private boolean hasPermission( 766 @NonNull String permission, 767 @NonNull String message, 768 boolean preflight, 769 @NonNull AttributionSource... attributionSources) { 770 final PermissionManager permissionManager = getPermissionManager(); 771 if (permissionManager == null) { 772 return false; 773 } 774 775 for (AttributionSource attributionSource : attributionSources) { 776 final int permissionCheckResult; 777 if (preflight) { 778 permissionCheckResult = permissionManager.checkPermissionForPreflight( 779 permission, attributionSource); 780 } else { 781 permissionCheckResult = permissionManager.checkPermissionForDataDelivery( 782 permission, attributionSource, message); 783 } 784 if (permissionCheckResult != PackageManager.PERMISSION_GRANTED) { 785 return false; 786 } 787 } 788 789 return true; 790 } 791 createAttributionSourcesForResolveInfo(ResolveInfo info)792 private AttributionSource[] createAttributionSourcesForResolveInfo(ResolveInfo info) { 793 final String[] attributionTags = info.activityInfo.attributionTags; 794 if (ArrayUtils.isEmpty(attributionTags)) { 795 return new AttributionSource[] { 796 new AttributionSource.Builder(info.activityInfo.applicationInfo.uid) 797 .setPackageName(info.activityInfo.packageName) 798 .build() 799 }; 800 } 801 802 final AttributionSource[] attributionSources = 803 new AttributionSource[attributionTags.length]; 804 for (int i = 0; i < attributionTags.length; i++) { 805 attributionSources[i] = 806 new AttributionSource.Builder(info.activityInfo.applicationInfo.uid) 807 .setPackageName(info.activityInfo.packageName) 808 .setAttributionTag(attributionTags[i]) 809 .build(); 810 } 811 return attributionSources; 812 } 813 } 814