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