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