• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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