1 /* 2 * Copyright (C) 2017 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.pm.permission; 18 19 import static android.Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY; 20 import static android.Manifest.permission.CAPTURE_AUDIO_HOTWORD; 21 import static android.Manifest.permission.READ_EXTERNAL_STORAGE; 22 import static android.Manifest.permission.RECORD_AUDIO; 23 import static android.Manifest.permission.UPDATE_APP_OPS_STATS; 24 import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE; 25 import static android.app.AppOpsManager.ATTRIBUTION_CHAIN_ID_NONE; 26 import static android.app.AppOpsManager.ATTRIBUTION_FLAGS_NONE; 27 import static android.app.AppOpsManager.MODE_ALLOWED; 28 import static android.app.AppOpsManager.MODE_ERRORED; 29 import static android.app.AppOpsManager.MODE_IGNORED; 30 import static android.content.pm.ApplicationInfo.AUTO_REVOKE_DISALLOWED; 31 import static android.content.pm.ApplicationInfo.AUTO_REVOKE_DISCOURAGED; 32 import static android.content.pm.PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT; 33 import static android.content.pm.PackageManager.FLAG_PERMISSION_APPLY_RESTRICTION; 34 import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT; 35 import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_ROLE; 36 import static android.content.pm.PackageManager.FLAG_PERMISSION_ONE_TIME; 37 import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED; 38 import static android.content.pm.PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT; 39 import static android.content.pm.PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT; 40 import static android.content.pm.PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT; 41 import static android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED; 42 import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKED_COMPAT; 43 import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_WHEN_REQUESTED; 44 import static android.content.pm.PackageManager.FLAG_PERMISSION_SELECTED_LOCATION_ACCURACY; 45 import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 46 import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED; 47 import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET; 48 import static android.content.pm.PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER; 49 import static android.content.pm.PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM; 50 import static android.content.pm.PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE; 51 import static android.content.pm.PackageManager.MASK_PERMISSION_FLAGS_ALL; 52 import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING; 53 import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER; 54 import static android.permission.PermissionManager.KILL_APP_REASON_GIDS_CHANGED; 55 import static android.permission.PermissionManager.KILL_APP_REASON_PERMISSIONS_REVOKED; 56 57 import static com.android.server.pm.ApexManager.MATCH_ACTIVE_PACKAGE; 58 import static com.android.server.pm.PackageManagerService.DEBUG_INSTALL; 59 import static com.android.server.pm.PackageManagerService.DEBUG_PACKAGE_SCANNING; 60 import static com.android.server.pm.PackageManagerService.DEBUG_PERMISSIONS; 61 import static com.android.server.pm.PackageManagerService.DEBUG_REMOVE; 62 import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME; 63 64 import static java.util.concurrent.TimeUnit.SECONDS; 65 66 import android.Manifest; 67 import android.annotation.AppIdInt; 68 import android.annotation.IntDef; 69 import android.annotation.NonNull; 70 import android.annotation.Nullable; 71 import android.annotation.UserIdInt; 72 import android.app.ActivityManager; 73 import android.app.AppOpsManager; 74 import android.app.AppOpsManager.AttributionFlags; 75 import android.app.IActivityManager; 76 import android.app.admin.DevicePolicyManagerInternal; 77 import android.compat.annotation.ChangeId; 78 import android.compat.annotation.EnabledAfter; 79 import android.content.AttributionSource; 80 import android.content.AttributionSourceState; 81 import android.content.Context; 82 import android.content.PermissionChecker; 83 import android.content.pm.ApplicationInfo; 84 import android.content.pm.FeatureInfo; 85 import android.content.pm.PackageManager; 86 import android.content.pm.PackageManager.PermissionGroupInfoFlags; 87 import android.content.pm.PackageManager.PermissionInfoFlags; 88 import android.content.pm.PackageManager.PermissionWhitelistFlags; 89 import android.content.pm.PackageManagerInternal; 90 import android.content.pm.PackageParser; 91 import android.content.pm.ParceledListSlice; 92 import android.content.pm.PermissionGroupInfo; 93 import android.content.pm.PermissionInfo; 94 import android.content.pm.parsing.component.ParsedPermission; 95 import android.content.pm.parsing.component.ParsedPermissionGroup; 96 import android.content.pm.permission.SplitPermissionInfoParcelable; 97 import android.metrics.LogMaker; 98 import android.os.AsyncTask; 99 import android.os.Binder; 100 import android.os.Build; 101 import android.os.Debug; 102 import android.os.Handler; 103 import android.os.HandlerThread; 104 import android.os.IBinder; 105 import android.os.Looper; 106 import android.os.Message; 107 import android.os.Process; 108 import android.os.RemoteCallbackList; 109 import android.os.RemoteException; 110 import android.os.ServiceManager; 111 import android.os.Trace; 112 import android.os.UserHandle; 113 import android.os.UserManager; 114 import android.os.storage.StorageManager; 115 import android.permission.IOnPermissionsChangeListener; 116 import android.permission.IPermissionChecker; 117 import android.permission.IPermissionManager; 118 import android.permission.PermissionCheckerManager; 119 import android.permission.PermissionControllerManager; 120 import android.permission.PermissionManager; 121 import android.permission.PermissionManagerInternal; 122 import android.text.TextUtils; 123 import android.util.ArrayMap; 124 import android.util.ArraySet; 125 import android.util.DebugUtils; 126 import android.util.EventLog; 127 import android.util.IntArray; 128 import android.util.Log; 129 import android.util.Slog; 130 import android.util.SparseArray; 131 import android.util.SparseBooleanArray; 132 133 import com.android.internal.annotations.GuardedBy; 134 import com.android.internal.compat.IPlatformCompat; 135 import com.android.internal.logging.MetricsLogger; 136 import com.android.internal.logging.nano.MetricsProto.MetricsEvent; 137 import com.android.internal.os.RoSystemProperties; 138 import com.android.internal.util.ArrayUtils; 139 import com.android.internal.util.CollectionUtils; 140 import com.android.internal.util.DumpUtils; 141 import com.android.internal.util.IntPair; 142 import com.android.internal.util.Preconditions; 143 import com.android.internal.util.function.TriFunction; 144 import com.android.internal.util.function.pooled.PooledLambda; 145 import com.android.server.FgThread; 146 import com.android.server.LocalServices; 147 import com.android.server.ServiceThread; 148 import com.android.server.SystemConfig; 149 import com.android.server.Watchdog; 150 import com.android.server.pm.ApexManager; 151 import com.android.server.pm.PackageSetting; 152 import com.android.server.pm.UserManagerInternal; 153 import com.android.server.pm.UserManagerService; 154 import com.android.server.pm.parsing.PackageInfoUtils; 155 import com.android.server.pm.parsing.pkg.AndroidPackage; 156 import com.android.server.pm.permission.PermissionManagerServiceInternal.HotwordDetectionServiceProvider; 157 import com.android.server.pm.permission.PermissionManagerServiceInternal.OnRuntimePermissionStateChangedListener; 158 import com.android.server.policy.PermissionPolicyInternal; 159 import com.android.server.policy.SoftRestrictedPermissionPolicy; 160 161 import libcore.util.EmptyArray; 162 163 import java.io.FileDescriptor; 164 import java.io.PrintWriter; 165 import java.lang.annotation.Retention; 166 import java.lang.annotation.RetentionPolicy; 167 import java.util.ArrayList; 168 import java.util.Arrays; 169 import java.util.Collection; 170 import java.util.Collections; 171 import java.util.HashMap; 172 import java.util.Iterator; 173 import java.util.List; 174 import java.util.Map; 175 import java.util.NoSuchElementException; 176 import java.util.Objects; 177 import java.util.Set; 178 import java.util.WeakHashMap; 179 import java.util.concurrent.CompletableFuture; 180 import java.util.concurrent.ConcurrentHashMap; 181 import java.util.concurrent.ExecutionException; 182 import java.util.concurrent.TimeUnit; 183 import java.util.concurrent.TimeoutException; 184 import java.util.concurrent.atomic.AtomicBoolean; 185 import java.util.concurrent.atomic.AtomicInteger; 186 import java.util.function.BiFunction; 187 188 /** 189 * Manages all permissions and handles permissions related tasks. 190 */ 191 public class PermissionManagerService extends IPermissionManager.Stub { 192 private static final String TAG = "PackageManager"; 193 private static final String LOG_TAG = PermissionManagerService.class.getSimpleName(); 194 195 private static final long BACKUP_TIMEOUT_MILLIS = SECONDS.toMillis(60); 196 197 // For automotive products, CarService enforces allow-listing of the privileged permissions 198 // com.android.car is the package name which declares auto specific permissions 199 private static final String CAR_PACKAGE_NAME = "com.android.car"; 200 201 /** Cap the size of permission trees that 3rd party apps can define; in characters of text */ 202 private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768; 203 /** Empty array to avoid allocations */ 204 private static final int[] EMPTY_INT_ARRAY = new int[0]; 205 206 /** 207 * When these flags are set, the system should not automatically modify the permission grant 208 * state. 209 */ 210 private static final int BLOCKING_PERMISSION_FLAGS = FLAG_PERMISSION_SYSTEM_FIXED 211 | FLAG_PERMISSION_POLICY_FIXED 212 | FLAG_PERMISSION_GRANTED_BY_DEFAULT; 213 214 /** Permission flags set by the user */ 215 private static final int USER_PERMISSION_FLAGS = FLAG_PERMISSION_USER_SET 216 | FLAG_PERMISSION_USER_FIXED; 217 218 /** All storage permissions */ 219 private static final List<String> STORAGE_PERMISSIONS = new ArrayList<>(); 220 /** All nearby devices permissions */ 221 private static final List<String> NEARBY_DEVICES_PERMISSIONS = new ArrayList<>(); 222 223 /** If the permission of the value is granted, so is the key */ 224 private static final Map<String, String> FULLER_PERMISSION_MAP = new HashMap<>(); 225 226 /** Map of IBinder -> Running AttributionSource */ 227 private static final ConcurrentHashMap<IBinder, RegisteredAttribution> 228 sRunningAttributionSources = new ConcurrentHashMap<>(); 229 230 static { FULLER_PERMISSION_MAP.put(Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION)231 FULLER_PERMISSION_MAP.put(Manifest.permission.ACCESS_COARSE_LOCATION, 232 Manifest.permission.ACCESS_FINE_LOCATION); FULLER_PERMISSION_MAP.put(Manifest.permission.INTERACT_ACROSS_USERS, Manifest.permission.INTERACT_ACROSS_USERS_FULL)233 FULLER_PERMISSION_MAP.put(Manifest.permission.INTERACT_ACROSS_USERS, 234 Manifest.permission.INTERACT_ACROSS_USERS_FULL); 235 STORAGE_PERMISSIONS.add(Manifest.permission.READ_EXTERNAL_STORAGE); 236 STORAGE_PERMISSIONS.add(Manifest.permission.WRITE_EXTERNAL_STORAGE); 237 STORAGE_PERMISSIONS.add(Manifest.permission.ACCESS_MEDIA_LOCATION); 238 NEARBY_DEVICES_PERMISSIONS.add(Manifest.permission.BLUETOOTH_ADVERTISE); 239 NEARBY_DEVICES_PERMISSIONS.add(Manifest.permission.BLUETOOTH_CONNECT); 240 NEARBY_DEVICES_PERMISSIONS.add(Manifest.permission.BLUETOOTH_SCAN); 241 } 242 243 /** Set of source package names for Privileged Permission Allowlist */ 244 private final ArraySet<String> mPrivilegedPermissionAllowlistSourcePackageNames = 245 new ArraySet<>(); 246 247 /** Lock to protect internal data access */ 248 private final Object mLock = new Object(); 249 250 /** Internal connection to the package manager */ 251 private final PackageManagerInternal mPackageManagerInt; 252 253 /** Internal connection to the user manager */ 254 private final UserManagerInternal mUserManagerInt; 255 256 @GuardedBy("mLock") 257 @NonNull 258 private final DevicePermissionState mState = new DevicePermissionState(); 259 260 /** Permission controller: User space permission management */ 261 private PermissionControllerManager mPermissionControllerManager; 262 263 /** Map of OneTimePermissionUserManagers keyed by userId */ 264 @GuardedBy("mLock") 265 @NonNull 266 private final SparseArray<OneTimePermissionUserManager> mOneTimePermissionUserManagers = 267 new SparseArray<>(); 268 269 /** App ops manager */ 270 private final AppOpsManager mAppOpsManager; 271 272 /** 273 * Built-in permissions. Read from system configuration files. Mapping is from 274 * UID to permission name. 275 */ 276 private final SparseArray<ArraySet<String>> mSystemPermissions; 277 278 /** Built-in group IDs given to all packages. Read from system configuration files. */ 279 @NonNull 280 private final int[] mGlobalGids; 281 282 private final HandlerThread mHandlerThread; 283 private final Handler mHandler; 284 private final Context mContext; 285 private final MetricsLogger mMetricsLogger = new MetricsLogger(); 286 private final IPlatformCompat mPlatformCompat = IPlatformCompat.Stub.asInterface( 287 ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE)); 288 289 /** Internal storage for permissions and related settings */ 290 @GuardedBy("mLock") 291 @NonNull 292 private final PermissionRegistry mRegistry = new PermissionRegistry(); 293 294 @NonNull 295 private final AttributionSourceRegistry mAttributionSourceRegistry; 296 297 @GuardedBy("mLock") 298 @Nullable 299 private ArraySet<String> mPrivappPermissionsViolations; 300 301 @GuardedBy("mLock") 302 private boolean mSystemReady; 303 304 @GuardedBy("mLock") 305 private PermissionPolicyInternal mPermissionPolicyInternal; 306 307 /** 308 * A permission backup might contain apps that are not installed. In this case we delay the 309 * restoration until the app is installed. 310 * 311 * <p>This array ({@code userId -> noDelayedBackupLeft}) is {@code true} for all the users where 312 * there is <u>no more</u> delayed backup left. 313 */ 314 @GuardedBy("mLock") 315 private final SparseBooleanArray mHasNoDelayedPermBackup = new SparseBooleanArray(); 316 317 /** Listeners for permission state (granting and flags) changes */ 318 @GuardedBy("mLock") 319 final private ArrayList<OnRuntimePermissionStateChangedListener> 320 mRuntimePermissionStateChangedListeners = new ArrayList<>(); 321 322 @GuardedBy("mLock") 323 private CheckPermissionDelegate mCheckPermissionDelegate; 324 325 @NonNull 326 private final OnPermissionChangeListeners mOnPermissionChangeListeners; 327 328 @Nullable 329 private HotwordDetectionServiceProvider mHotwordDetectionServiceProvider; 330 331 // TODO: Take a look at the methods defined in the callback. 332 // The callback was initially created to support the split between permission 333 // manager and the package manager. However, it's started to be used for other 334 // purposes. It may make sense to keep as an abstraction, but, the methods 335 // necessary to be overridden may be different than what was initially needed 336 // for the split. 337 private final PermissionCallback mDefaultPermissionCallback = new PermissionCallback() { 338 @Override 339 public void onGidsChanged(int appId, int userId) { 340 mHandler.post(() -> killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED)); 341 } 342 @Override 343 public void onPermissionGranted(int uid, int userId) { 344 mOnPermissionChangeListeners.onPermissionsChanged(uid); 345 346 // Not critical; if this is lost, the application has to request again. 347 mPackageManagerInt.writeSettings(true); 348 } 349 @Override 350 public void onInstallPermissionGranted() { 351 mPackageManagerInt.writeSettings(true); 352 } 353 @Override 354 public void onPermissionRevoked(int uid, int userId, String reason) { 355 mOnPermissionChangeListeners.onPermissionsChanged(uid); 356 357 // Critical; after this call the application should never have the permission 358 mPackageManagerInt.writeSettings(false); 359 final int appId = UserHandle.getAppId(uid); 360 if (reason == null) { 361 mHandler.post(() -> killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED)); 362 } else { 363 mHandler.post(() -> killUid(appId, userId, reason)); 364 } 365 } 366 @Override 367 public void onInstallPermissionRevoked() { 368 mPackageManagerInt.writeSettings(true); 369 } 370 @Override 371 public void onPermissionUpdated(int[] userIds, boolean sync) { 372 mPackageManagerInt.writePermissionSettings(userIds, !sync); 373 } 374 @Override 375 public void onInstallPermissionUpdated() { 376 mPackageManagerInt.writeSettings(true); 377 } 378 @Override 379 public void onPermissionRemoved() { 380 mPackageManagerInt.writeSettings(false); 381 } 382 public void onPermissionUpdatedNotifyListener(@UserIdInt int[] updatedUserIds, boolean sync, 383 int uid) { 384 onPermissionUpdated(updatedUserIds, sync); 385 for (int i = 0; i < updatedUserIds.length; i++) { 386 int userUid = UserHandle.getUid(updatedUserIds[i], UserHandle.getAppId(uid)); 387 mOnPermissionChangeListeners.onPermissionsChanged(userUid); 388 } 389 } 390 public void onInstallPermissionUpdatedNotifyListener(int uid) { 391 onInstallPermissionUpdated(); 392 mOnPermissionChangeListeners.onPermissionsChanged(uid); 393 } 394 }; 395 PermissionManagerService(@onNull Context context, @NonNull ArrayMap<String, FeatureInfo> availableFeatures)396 PermissionManagerService(@NonNull Context context, 397 @NonNull ArrayMap<String, FeatureInfo> availableFeatures) { 398 // The package info cache is the cache for package and permission information. 399 // Disable the package info and package permission caches locally but leave the 400 // checkPermission cache active. 401 PackageManager.invalidatePackageInfoCache(); 402 PermissionManager.disablePackageNamePermissionCache(); 403 404 mContext = context; 405 mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class); 406 mUserManagerInt = LocalServices.getService(UserManagerInternal.class); 407 mAppOpsManager = context.getSystemService(AppOpsManager.class); 408 409 mPrivilegedPermissionAllowlistSourcePackageNames.add(PLATFORM_PACKAGE_NAME); 410 // PackageManager.hasSystemFeature() is not used here because PackageManagerService 411 // isn't ready yet. 412 if (availableFeatures.containsKey(PackageManager.FEATURE_AUTOMOTIVE)) { 413 mPrivilegedPermissionAllowlistSourcePackageNames.add(CAR_PACKAGE_NAME); 414 } 415 416 mHandlerThread = new ServiceThread(TAG, 417 Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/); 418 mHandlerThread.start(); 419 mHandler = new Handler(mHandlerThread.getLooper()); 420 Watchdog.getInstance().addThread(mHandler); 421 422 SystemConfig systemConfig = SystemConfig.getInstance(); 423 mSystemPermissions = systemConfig.getSystemPermissions(); 424 mGlobalGids = systemConfig.getGlobalGids(); 425 mOnPermissionChangeListeners = new OnPermissionChangeListeners(FgThread.get().getLooper()); 426 mAttributionSourceRegistry = new AttributionSourceRegistry(context); 427 428 // propagate permission configuration 429 final ArrayMap<String, SystemConfig.PermissionEntry> permConfig = 430 SystemConfig.getInstance().getPermissions(); 431 synchronized (mLock) { 432 for (int i=0; i<permConfig.size(); i++) { 433 final SystemConfig.PermissionEntry perm = permConfig.valueAt(i); 434 Permission bp = mRegistry.getPermission(perm.name); 435 if (bp == null) { 436 bp = new Permission(perm.name, "android", Permission.TYPE_CONFIG); 437 mRegistry.addPermission(bp); 438 } 439 if (perm.gids != null) { 440 bp.setGids(perm.gids, perm.perUser); 441 } 442 } 443 } 444 445 PermissionManagerServiceInternalImpl localService = 446 new PermissionManagerServiceInternalImpl(); 447 LocalServices.addService(PermissionManagerServiceInternal.class, localService); 448 LocalServices.addService(PermissionManagerInternal.class, localService); 449 } 450 451 @Override dump(FileDescriptor fd, PrintWriter pw, String[] args)452 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 453 if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) { 454 return; 455 } 456 457 mContext.getSystemService(PermissionControllerManager.class).dump(fd, args); 458 } 459 460 /** 461 * Creates and returns an initialized, internal service for use by other components. 462 * <p> 463 * The object returned is identical to the one returned by the LocalServices class using: 464 * {@code LocalServices.getService(PermissionManagerServiceInternal.class);} 465 * <p> 466 * NOTE: The external lock is temporary and should be removed. This needs to be a 467 * lock created by the permission manager itself. 468 */ 469 @NonNull create(@onNull Context context, ArrayMap<String, FeatureInfo> availableFeatures)470 public static PermissionManagerServiceInternal create(@NonNull Context context, 471 ArrayMap<String, FeatureInfo> availableFeatures) { 472 final PermissionManagerServiceInternal permMgrInt = 473 LocalServices.getService(PermissionManagerServiceInternal.class); 474 if (permMgrInt != null) { 475 return permMgrInt; 476 } 477 PermissionManagerService permissionService = 478 (PermissionManagerService) ServiceManager.getService("permissionmgr"); 479 if (permissionService == null) { 480 permissionService = new PermissionManagerService(context, availableFeatures); 481 ServiceManager.addService("permissionmgr", permissionService); 482 ServiceManager.addService("permission_checker", new PermissionCheckerService(context)); 483 } 484 return LocalServices.getService(PermissionManagerServiceInternal.class); 485 } 486 487 /** 488 * This method should typically only be used when granting or revoking 489 * permissions, since the app may immediately restart after this call. 490 * <p> 491 * If you're doing surgery on app code/data, use {@link PackageFreezer} to 492 * guard your work against the app being relaunched. 493 */ killUid(int appId, int userId, String reason)494 public static void killUid(int appId, int userId, String reason) { 495 final long identity = Binder.clearCallingIdentity(); 496 try { 497 IActivityManager am = ActivityManager.getService(); 498 if (am != null) { 499 try { 500 am.killUidForPermissionChange(appId, userId, reason); 501 } catch (RemoteException e) { 502 /* ignore - same process */ 503 } 504 } 505 } finally { 506 Binder.restoreCallingIdentity(identity); 507 } 508 } 509 510 @NonNull getAppOpPermissionPackagesInternal(@onNull String permissionName)511 private String[] getAppOpPermissionPackagesInternal(@NonNull String permissionName) { 512 synchronized (mLock) { 513 final ArraySet<String> packageNames = mRegistry.getAppOpPermissionPackages( 514 permissionName); 515 if (packageNames == null) { 516 return EmptyArray.STRING; 517 } 518 return packageNames.toArray(new String[0]); 519 } 520 } 521 522 @Override 523 @NonNull getAllPermissionGroups( @ermissionGroupInfoFlags int flags)524 public ParceledListSlice<PermissionGroupInfo> getAllPermissionGroups( 525 @PermissionGroupInfoFlags int flags) { 526 final int callingUid = getCallingUid(); 527 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) { 528 return ParceledListSlice.emptyList(); 529 } 530 531 final List<PermissionGroupInfo> out = new ArrayList<>(); 532 synchronized (mLock) { 533 for (ParsedPermissionGroup pg : mRegistry.getPermissionGroups()) { 534 out.add(PackageInfoUtils.generatePermissionGroupInfo(pg, flags)); 535 } 536 } 537 538 final int callingUserId = UserHandle.getUserId(callingUid); 539 out.removeIf(it -> mPackageManagerInt.filterAppAccess(it.packageName, callingUid, 540 callingUserId)); 541 return new ParceledListSlice<>(out); 542 } 543 544 545 @Override 546 @Nullable getPermissionGroupInfo(String groupName, @PermissionGroupInfoFlags int flags)547 public PermissionGroupInfo getPermissionGroupInfo(String groupName, 548 @PermissionGroupInfoFlags int flags) { 549 final int callingUid = getCallingUid(); 550 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) { 551 return null; 552 } 553 554 final PermissionGroupInfo permissionGroupInfo; 555 synchronized (mLock) { 556 final ParsedPermissionGroup permissionGroup = mRegistry.getPermissionGroup(groupName); 557 if (permissionGroup == null) { 558 return null; 559 } 560 permissionGroupInfo = PackageInfoUtils.generatePermissionGroupInfo(permissionGroup, 561 flags); 562 } 563 564 final int callingUserId = UserHandle.getUserId(callingUid); 565 if (mPackageManagerInt.filterAppAccess(permissionGroupInfo.packageName, callingUid, 566 callingUserId)) { 567 EventLog.writeEvent(0x534e4554, "186113473", callingUid, groupName); 568 return null; 569 } 570 return permissionGroupInfo; 571 } 572 573 574 @Override 575 @Nullable getPermissionInfo(@onNull String permName, @NonNull String opPackageName, @PermissionInfoFlags int flags)576 public PermissionInfo getPermissionInfo(@NonNull String permName, @NonNull String opPackageName, 577 @PermissionInfoFlags int flags) { 578 final int callingUid = getCallingUid(); 579 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) { 580 return null; 581 } 582 583 final AndroidPackage opPackage = mPackageManagerInt.getPackage(opPackageName); 584 final int targetSdkVersion = getPermissionInfoCallingTargetSdkVersion(opPackage, 585 callingUid); 586 final PermissionInfo permissionInfo; 587 synchronized (mLock) { 588 final Permission bp = mRegistry.getPermission(permName); 589 if (bp == null) { 590 return null; 591 } 592 permissionInfo = bp.generatePermissionInfo(flags, targetSdkVersion); 593 } 594 595 final int callingUserId = UserHandle.getUserId(callingUid); 596 if (mPackageManagerInt.filterAppAccess(permissionInfo.packageName, callingUid, 597 callingUserId)) { 598 EventLog.writeEvent(0x534e4554, "183122164", callingUid, permName); 599 return null; 600 } 601 return permissionInfo; 602 } 603 getPermissionInfoCallingTargetSdkVersion(@ullable AndroidPackage pkg, int uid)604 private int getPermissionInfoCallingTargetSdkVersion(@Nullable AndroidPackage pkg, int uid) { 605 final int appId = UserHandle.getAppId(uid); 606 if (appId == Process.ROOT_UID || appId == Process.SYSTEM_UID 607 || appId == Process.SHELL_UID) { 608 // System sees all flags. 609 return Build.VERSION_CODES.CUR_DEVELOPMENT; 610 } 611 if (pkg == null) { 612 return Build.VERSION_CODES.CUR_DEVELOPMENT; 613 } 614 return pkg.getTargetSdkVersion(); 615 } 616 617 @Override 618 @Nullable queryPermissionsByGroup(String groupName, @PermissionInfoFlags int flags)619 public ParceledListSlice<PermissionInfo> queryPermissionsByGroup(String groupName, 620 @PermissionInfoFlags int flags) { 621 final int callingUid = getCallingUid(); 622 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) { 623 return null; 624 } 625 626 final List<PermissionInfo> out = new ArrayList<>(10); 627 synchronized (mLock) { 628 if (groupName != null && mRegistry.getPermissionGroup(groupName) == null) { 629 return null; 630 } 631 for (Permission bp : mRegistry.getPermissions()) { 632 if (Objects.equals(bp.getGroup(), groupName)) { 633 out.add(bp.generatePermissionInfo(flags)); 634 } 635 } 636 } 637 638 final int callingUserId = UserHandle.getUserId(callingUid); 639 out.removeIf(it -> mPackageManagerInt.filterAppAccess(it.packageName, callingUid, 640 callingUserId)); 641 return new ParceledListSlice<>(out); 642 } 643 644 @Override addPermission(PermissionInfo info, boolean async)645 public boolean addPermission(PermissionInfo info, boolean async) { 646 final int callingUid = getCallingUid(); 647 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) { 648 throw new SecurityException("Instant apps can't add permissions"); 649 } 650 if (info.labelRes == 0 && info.nonLocalizedLabel == null) { 651 throw new SecurityException("Label must be specified in permission"); 652 } 653 final boolean added; 654 final boolean changed; 655 synchronized (mLock) { 656 final Permission tree = mRegistry.enforcePermissionTree(info.name, callingUid); 657 Permission bp = mRegistry.getPermission(info.name); 658 added = bp == null; 659 int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel); 660 if (added) { 661 enforcePermissionCapLocked(info, tree); 662 bp = new Permission(info.name, tree.getPackageName(), Permission.TYPE_DYNAMIC); 663 } else if (!bp.isDynamic()) { 664 throw new SecurityException("Not allowed to modify non-dynamic permission " 665 + info.name); 666 } 667 changed = bp.addToTree(fixedLevel, info, tree); 668 if (added) { 669 mRegistry.addPermission(bp); 670 } 671 } 672 if (changed) { 673 mPackageManagerInt.writeSettings(async); 674 } 675 return added; 676 } 677 678 @Override removePermission(String permName)679 public void removePermission(String permName) { 680 final int callingUid = getCallingUid(); 681 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) { 682 throw new SecurityException("Instant applications don't have access to this method"); 683 } 684 synchronized (mLock) { 685 mRegistry.enforcePermissionTree(permName, callingUid); 686 final Permission bp = mRegistry.getPermission(permName); 687 if (bp == null) { 688 return; 689 } 690 if (bp.isDynamic()) { 691 // TODO: switch this back to SecurityException 692 Slog.wtf(TAG, "Not allowed to modify non-dynamic permission " 693 + permName); 694 } 695 mRegistry.removePermission(permName); 696 } 697 mPackageManagerInt.writeSettings(false); 698 } 699 700 @Override getPermissionFlags(String packageName, String permName, int userId)701 public int getPermissionFlags(String packageName, String permName, int userId) { 702 final int callingUid = getCallingUid(); 703 return getPermissionFlagsInternal(packageName, permName, callingUid, userId); 704 } 705 getPermissionFlagsInternal( String packageName, String permName, int callingUid, int userId)706 private int getPermissionFlagsInternal( 707 String packageName, String permName, int callingUid, int userId) { 708 if (!mUserManagerInt.exists(userId)) { 709 return 0; 710 } 711 712 enforceGrantRevokeGetRuntimePermissionPermissions("getPermissionFlags"); 713 enforceCrossUserPermission(callingUid, userId, 714 true, // requireFullPermission 715 false, // checkShell 716 "getPermissionFlags"); 717 718 final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName); 719 if (pkg == null) { 720 return 0; 721 } 722 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) { 723 return 0; 724 } 725 726 synchronized (mLock) { 727 if (mRegistry.getPermission(permName) == null) { 728 return 0; 729 } 730 731 final UidPermissionState uidState = getUidStateLocked(pkg, userId); 732 if (uidState == null) { 733 Slog.e(TAG, "Missing permissions state for " + packageName + " and user " + userId); 734 return 0; 735 } 736 737 return uidState.getPermissionFlags(permName); 738 } 739 } 740 741 @Override updatePermissionFlags(String packageName, String permName, int flagMask, int flagValues, boolean checkAdjustPolicyFlagPermission, int userId)742 public void updatePermissionFlags(String packageName, String permName, int flagMask, 743 int flagValues, boolean checkAdjustPolicyFlagPermission, int userId) { 744 final int callingUid = getCallingUid(); 745 boolean overridePolicy = false; 746 747 if (callingUid != Process.SYSTEM_UID && callingUid != Process.ROOT_UID) { 748 final long callingIdentity = Binder.clearCallingIdentity(); 749 try { 750 if ((flagMask & FLAG_PERMISSION_POLICY_FIXED) != 0) { 751 if (checkAdjustPolicyFlagPermission) { 752 mContext.enforceCallingOrSelfPermission( 753 Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY, 754 "Need " + Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY 755 + " to change policy flags"); 756 } else if (mPackageManagerInt.getUidTargetSdkVersion(callingUid) 757 >= Build.VERSION_CODES.Q) { 758 throw new IllegalArgumentException( 759 Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY + " needs " 760 + " to be checked for packages targeting " 761 + Build.VERSION_CODES.Q + " or later when changing policy " 762 + "flags"); 763 } 764 overridePolicy = true; 765 } 766 } finally { 767 Binder.restoreCallingIdentity(callingIdentity); 768 } 769 } 770 771 updatePermissionFlagsInternal( 772 packageName, permName, flagMask, flagValues, callingUid, userId, 773 overridePolicy, mDefaultPermissionCallback); 774 } 775 updatePermissionFlagsInternal(String packageName, String permName, int flagMask, int flagValues, int callingUid, int userId, boolean overridePolicy, PermissionCallback callback)776 private void updatePermissionFlagsInternal(String packageName, String permName, int flagMask, 777 int flagValues, int callingUid, int userId, boolean overridePolicy, 778 PermissionCallback callback) { 779 if (PermissionManager.DEBUG_TRACE_PERMISSION_UPDATES 780 && PermissionManager.shouldTraceGrant(packageName, permName, userId)) { 781 Log.i(TAG, "System is updating flags for " + packageName + " " 782 + permName + " for user " + userId + " " 783 + DebugUtils.flagsToString( 784 PackageManager.class, "FLAG_PERMISSION_", flagMask) 785 + " := " 786 + DebugUtils.flagsToString( 787 PackageManager.class, "FLAG_PERMISSION_", flagValues) 788 + " on behalf of uid " + callingUid 789 + " " + mPackageManagerInt.getNameForUid(callingUid), 790 new RuntimeException()); 791 } 792 793 if (!mUserManagerInt.exists(userId)) { 794 return; 795 } 796 797 enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags"); 798 799 enforceCrossUserPermission(callingUid, userId, 800 true, // requireFullPermission 801 true, // checkShell 802 "updatePermissionFlags"); 803 804 if ((flagMask & FLAG_PERMISSION_POLICY_FIXED) != 0 && !overridePolicy) { 805 throw new SecurityException("updatePermissionFlags requires " 806 + Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY); 807 } 808 809 // Only the system can change these flags and nothing else. 810 if (callingUid != Process.SYSTEM_UID) { 811 flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 812 flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 813 flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT; 814 flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT; 815 flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED; 816 flagValues &= ~FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT; 817 flagValues &= ~FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT; 818 flagValues &= ~FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT; 819 flagValues &= ~PackageManager.FLAG_PERMISSION_APPLY_RESTRICTION; 820 } 821 822 final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName); 823 if (pkg == null) { 824 Log.e(TAG, "Unknown package: " + packageName); 825 return; 826 } 827 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) { 828 throw new IllegalArgumentException("Unknown package: " + packageName); 829 } 830 831 boolean isRequested = false; 832 // Fast path, the current package has requested the permission. 833 if (pkg.getRequestedPermissions().contains(permName)) { 834 isRequested = true; 835 } 836 if (!isRequested) { 837 // Slow path, go through all shared user packages. 838 String[] sharedUserPackageNames = 839 mPackageManagerInt.getSharedUserPackagesForPackage(packageName, userId); 840 for (String sharedUserPackageName : sharedUserPackageNames) { 841 AndroidPackage sharedUserPkg = mPackageManagerInt.getPackage( 842 sharedUserPackageName); 843 if (sharedUserPkg != null 844 && sharedUserPkg.getRequestedPermissions().contains(permName)) { 845 isRequested = true; 846 break; 847 } 848 } 849 } 850 851 final boolean isRuntimePermission; 852 final boolean permissionUpdated; 853 synchronized (mLock) { 854 final Permission bp = mRegistry.getPermission(permName); 855 if (bp == null) { 856 throw new IllegalArgumentException("Unknown permission: " + permName); 857 } 858 859 isRuntimePermission = bp.isRuntime(); 860 861 final UidPermissionState uidState = getUidStateLocked(pkg, userId); 862 if (uidState == null) { 863 Slog.e(TAG, "Missing permissions state for " + packageName + " and user " + userId); 864 return; 865 } 866 867 if (!uidState.hasPermissionState(permName) && !isRequested) { 868 Log.e(TAG, "Permission " + permName + " isn't requested by package " + packageName); 869 return; 870 } 871 872 permissionUpdated = uidState.updatePermissionFlags(bp, flagMask, flagValues); 873 } 874 875 if (permissionUpdated && isRuntimePermission) { 876 notifyRuntimePermissionStateChanged(packageName, userId); 877 } 878 if (permissionUpdated && callback != null) { 879 // Install and runtime permissions are stored in different places, 880 // so figure out what permission changed and persist the change. 881 if (!isRuntimePermission) { 882 int userUid = UserHandle.getUid(userId, pkg.getUid()); 883 callback.onInstallPermissionUpdatedNotifyListener(userUid); 884 } else { 885 callback.onPermissionUpdatedNotifyListener(new int[]{userId}, false, pkg.getUid()); 886 } 887 } 888 } 889 890 /** 891 * Update the permission flags for all packages and runtime permissions of a user in order 892 * to allow device or profile owner to remove POLICY_FIXED. 893 */ 894 @Override updatePermissionFlagsForAllApps(int flagMask, int flagValues, final int userId)895 public void updatePermissionFlagsForAllApps(int flagMask, int flagValues, 896 final int userId) { 897 final int callingUid = getCallingUid(); 898 if (!mUserManagerInt.exists(userId)) { 899 return; 900 } 901 902 enforceGrantRevokeRuntimePermissionPermissions( 903 "updatePermissionFlagsForAllApps"); 904 enforceCrossUserPermission(callingUid, userId, 905 true, // requireFullPermission 906 true, // checkShell 907 "updatePermissionFlagsForAllApps"); 908 909 // Only the system can change system fixed flags. 910 final int effectiveFlagMask = (callingUid != Process.SYSTEM_UID) 911 ? flagMask : flagMask & ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 912 final int effectiveFlagValues = (callingUid != Process.SYSTEM_UID) 913 ? flagValues : flagValues & ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 914 915 final boolean[] changed = new boolean[1]; 916 mPackageManagerInt.forEachPackage(pkg -> { 917 synchronized (mLock) { 918 final UidPermissionState uidState = getUidStateLocked(pkg, userId); 919 if (uidState == null) { 920 Slog.e(TAG, 921 "Missing permissions state for " + pkg.getPackageName() + " and user " 922 + userId); 923 return; 924 } 925 changed[0] |= uidState.updatePermissionFlagsForAllPermissions( 926 effectiveFlagMask, effectiveFlagValues); 927 } 928 mOnPermissionChangeListeners.onPermissionsChanged(pkg.getUid()); 929 }); 930 931 if (changed[0]) { 932 mPackageManagerInt.writePermissionSettings(new int[] { userId }, true); 933 } 934 } 935 checkPermission(String pkgName, String permName, @UserIdInt int userId)936 private int checkPermission(String pkgName, String permName, @UserIdInt int userId) { 937 // Not using Objects.requireNonNull() here for compatibility reasons. 938 if (pkgName == null || permName == null) { 939 return PackageManager.PERMISSION_DENIED; 940 } 941 if (!mUserManagerInt.exists(userId)) { 942 return PackageManager.PERMISSION_DENIED; 943 } 944 945 final CheckPermissionDelegate checkPermissionDelegate; 946 synchronized (mLock) { 947 checkPermissionDelegate = mCheckPermissionDelegate; 948 } 949 if (checkPermissionDelegate == null) { 950 return checkPermissionImpl(pkgName, permName, userId); 951 } 952 return checkPermissionDelegate.checkPermission(pkgName, permName, userId, 953 this::checkPermissionImpl); 954 } 955 checkPermissionImpl(String pkgName, String permName, int userId)956 private int checkPermissionImpl(String pkgName, String permName, int userId) { 957 final AndroidPackage pkg = mPackageManagerInt.getPackage(pkgName); 958 if (pkg == null) { 959 return PackageManager.PERMISSION_DENIED; 960 } 961 return checkPermissionInternal(pkg, true, permName, userId); 962 } 963 checkPermissionInternal(@onNull AndroidPackage pkg, boolean isPackageExplicit, @NonNull String permissionName, @UserIdInt int userId)964 private int checkPermissionInternal(@NonNull AndroidPackage pkg, boolean isPackageExplicit, 965 @NonNull String permissionName, @UserIdInt int userId) { 966 final int callingUid = getCallingUid(); 967 if (isPackageExplicit || pkg.getSharedUserId() == null) { 968 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) { 969 return PackageManager.PERMISSION_DENIED; 970 } 971 } else { 972 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) { 973 return PackageManager.PERMISSION_DENIED; 974 } 975 } 976 977 final int uid = UserHandle.getUid(userId, pkg.getUid()); 978 final boolean isInstantApp = mPackageManagerInt.getInstantAppPackageName(uid) != null; 979 980 synchronized (mLock) { 981 final UidPermissionState uidState = getUidStateLocked(pkg, userId); 982 if (uidState == null) { 983 Slog.e(TAG, "Missing permissions state for " + pkg.getPackageName() + " and user " 984 + userId); 985 return PackageManager.PERMISSION_DENIED; 986 } 987 988 if (checkSinglePermissionInternalLocked(uidState, permissionName, isInstantApp)) { 989 return PackageManager.PERMISSION_GRANTED; 990 } 991 992 final String fullerPermissionName = FULLER_PERMISSION_MAP.get(permissionName); 993 if (fullerPermissionName != null && checkSinglePermissionInternalLocked(uidState, 994 fullerPermissionName, isInstantApp)) { 995 return PackageManager.PERMISSION_GRANTED; 996 } 997 } 998 999 return PackageManager.PERMISSION_DENIED; 1000 } 1001 1002 @GuardedBy("mLock") checkSinglePermissionInternalLocked(@onNull UidPermissionState uidState, @NonNull String permissionName, boolean isInstantApp)1003 private boolean checkSinglePermissionInternalLocked(@NonNull UidPermissionState uidState, 1004 @NonNull String permissionName, boolean isInstantApp) { 1005 if (!uidState.isPermissionGranted(permissionName)) { 1006 return false; 1007 } 1008 1009 if (isInstantApp) { 1010 final Permission permission = mRegistry.getPermission(permissionName); 1011 return permission != null && permission.isInstant(); 1012 } 1013 1014 return true; 1015 } 1016 checkUidPermission(int uid, String permName)1017 private int checkUidPermission(int uid, String permName) { 1018 // Not using Objects.requireNonNull() here for compatibility reasons. 1019 if (permName == null) { 1020 return PackageManager.PERMISSION_DENIED; 1021 } 1022 final int userId = UserHandle.getUserId(uid); 1023 if (!mUserManagerInt.exists(userId)) { 1024 return PackageManager.PERMISSION_DENIED; 1025 } 1026 1027 final CheckPermissionDelegate checkPermissionDelegate; 1028 synchronized (mLock) { 1029 checkPermissionDelegate = mCheckPermissionDelegate; 1030 } 1031 if (checkPermissionDelegate == null) { 1032 return checkUidPermissionImpl(uid, permName); 1033 } 1034 return checkPermissionDelegate.checkUidPermission(uid, permName, 1035 this::checkUidPermissionImpl); 1036 } 1037 checkUidPermissionImpl(int uid, String permName)1038 private int checkUidPermissionImpl(int uid, String permName) { 1039 final AndroidPackage pkg = mPackageManagerInt.getPackage(uid); 1040 return checkUidPermissionInternal(pkg, uid, permName); 1041 } 1042 1043 /** 1044 * Checks whether or not the given package has been granted the specified 1045 * permission. If the given package is {@code null}, we instead check the 1046 * system permissions for the given UID. 1047 * 1048 * @see SystemConfig#getSystemPermissions() 1049 */ checkUidPermissionInternal(@ullable AndroidPackage pkg, int uid, @NonNull String permissionName)1050 private int checkUidPermissionInternal(@Nullable AndroidPackage pkg, int uid, 1051 @NonNull String permissionName) { 1052 if (pkg != null) { 1053 final int userId = UserHandle.getUserId(uid); 1054 return checkPermissionInternal(pkg, false, permissionName, userId); 1055 } 1056 1057 synchronized (mLock) { 1058 if (checkSingleUidPermissionInternalLocked(uid, permissionName)) { 1059 return PackageManager.PERMISSION_GRANTED; 1060 } 1061 1062 final String fullerPermissionName = FULLER_PERMISSION_MAP.get(permissionName); 1063 if (fullerPermissionName != null 1064 && checkSingleUidPermissionInternalLocked(uid, fullerPermissionName)) { 1065 return PackageManager.PERMISSION_GRANTED; 1066 } 1067 } 1068 1069 return PackageManager.PERMISSION_DENIED; 1070 } 1071 1072 @GuardedBy("mLock") checkSingleUidPermissionInternalLocked(int uid, @NonNull String permissionName)1073 private boolean checkSingleUidPermissionInternalLocked(int uid, 1074 @NonNull String permissionName) { 1075 ArraySet<String> permissions = mSystemPermissions.get(uid); 1076 return permissions != null && permissions.contains(permissionName); 1077 } 1078 1079 @Override addOnPermissionsChangeListener(IOnPermissionsChangeListener listener)1080 public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) { 1081 mContext.enforceCallingOrSelfPermission( 1082 Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS, 1083 "addOnPermissionsChangeListener"); 1084 1085 mOnPermissionChangeListeners.addListener(listener); 1086 } 1087 1088 @Override removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener)1089 public void removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener) { 1090 if (mPackageManagerInt.getInstantAppPackageName(Binder.getCallingUid()) != null) { 1091 throw new SecurityException("Instant applications don't have access to this method"); 1092 } 1093 mOnPermissionChangeListeners.removeListener(listener); 1094 } 1095 1096 @Nullable 1097 @Override getAllowlistedRestrictedPermissions(@onNull String packageName, @PermissionWhitelistFlags int flags, @UserIdInt int userId)1098 public List<String> getAllowlistedRestrictedPermissions(@NonNull String packageName, 1099 @PermissionWhitelistFlags int flags, @UserIdInt int userId) { 1100 Objects.requireNonNull(packageName); 1101 Preconditions.checkFlagsArgument(flags, 1102 PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE 1103 | PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM 1104 | PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER); 1105 Preconditions.checkArgumentNonNegative(userId, null); 1106 1107 if (UserHandle.getCallingUserId() != userId) { 1108 mContext.enforceCallingOrSelfPermission( 1109 android.Manifest.permission.INTERACT_ACROSS_USERS, 1110 "getAllowlistedRestrictedPermissions for user " + userId); 1111 } 1112 1113 final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName); 1114 if (pkg == null) { 1115 return null; 1116 } 1117 1118 final int callingUid = Binder.getCallingUid(); 1119 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, UserHandle.getCallingUserId())) { 1120 return null; 1121 } 1122 final boolean isCallerPrivileged = mContext.checkCallingOrSelfPermission( 1123 Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS) 1124 == PackageManager.PERMISSION_GRANTED; 1125 final boolean isCallerInstallerOnRecord = 1126 mPackageManagerInt.isCallerInstallerOfRecord(pkg, callingUid); 1127 1128 if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM) != 0 1129 && !isCallerPrivileged) { 1130 throw new SecurityException("Querying system allowlist requires " 1131 + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS); 1132 } 1133 1134 if ((flags & (PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE 1135 | PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER)) != 0) { 1136 if (!isCallerPrivileged && !isCallerInstallerOnRecord) { 1137 throw new SecurityException("Querying upgrade or installer allowlist" 1138 + " requires being installer on record or " 1139 + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS); 1140 } 1141 } 1142 1143 final long identity = Binder.clearCallingIdentity(); 1144 try { 1145 return getAllowlistedRestrictedPermissionsInternal(pkg, flags, userId); 1146 } finally { 1147 Binder.restoreCallingIdentity(identity); 1148 } 1149 } 1150 1151 @Nullable getAllowlistedRestrictedPermissionsInternal(@onNull AndroidPackage pkg, @PermissionWhitelistFlags int flags, @UserIdInt int userId)1152 private List<String> getAllowlistedRestrictedPermissionsInternal(@NonNull AndroidPackage pkg, 1153 @PermissionWhitelistFlags int flags, @UserIdInt int userId) { 1154 synchronized (mLock) { 1155 final UidPermissionState uidState = getUidStateLocked(pkg, userId); 1156 if (uidState == null) { 1157 Slog.e(TAG, "Missing permissions state for " + pkg.getPackageName() + " and user " 1158 + userId); 1159 return null; 1160 } 1161 1162 int queryFlags = 0; 1163 if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM) != 0) { 1164 queryFlags |= FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT; 1165 } 1166 if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE) != 0) { 1167 queryFlags |= FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT; 1168 } 1169 if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER) != 0) { 1170 queryFlags |= FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT; 1171 } 1172 1173 ArrayList<String> allowlistedPermissions = null; 1174 1175 final int permissionCount = ArrayUtils.size(pkg.getRequestedPermissions()); 1176 for (int i = 0; i < permissionCount; i++) { 1177 final String permissionName = pkg.getRequestedPermissions().get(i); 1178 final int currentFlags = 1179 uidState.getPermissionFlags(permissionName); 1180 if ((currentFlags & queryFlags) != 0) { 1181 if (allowlistedPermissions == null) { 1182 allowlistedPermissions = new ArrayList<>(); 1183 } 1184 allowlistedPermissions.add(permissionName); 1185 } 1186 } 1187 1188 return allowlistedPermissions; 1189 } 1190 } 1191 1192 @Override addAllowlistedRestrictedPermission(@onNull String packageName, @NonNull String permName, @PermissionWhitelistFlags int flags, @UserIdInt int userId)1193 public boolean addAllowlistedRestrictedPermission(@NonNull String packageName, 1194 @NonNull String permName, @PermissionWhitelistFlags int flags, 1195 @UserIdInt int userId) { 1196 // Other argument checks are done in get/setAllowlistedRestrictedPermissions 1197 Objects.requireNonNull(permName); 1198 1199 if (!checkExistsAndEnforceCannotModifyImmutablyRestrictedPermission(permName)) { 1200 return false; 1201 } 1202 1203 List<String> permissions = 1204 getAllowlistedRestrictedPermissions(packageName, flags, userId); 1205 if (permissions == null) { 1206 permissions = new ArrayList<>(1); 1207 } 1208 if (permissions.indexOf(permName) < 0) { 1209 permissions.add(permName); 1210 return setAllowlistedRestrictedPermissions(packageName, permissions, 1211 flags, userId); 1212 } 1213 return false; 1214 } 1215 checkExistsAndEnforceCannotModifyImmutablyRestrictedPermission( @onNull String permName)1216 private boolean checkExistsAndEnforceCannotModifyImmutablyRestrictedPermission( 1217 @NonNull String permName) { 1218 final boolean isImmutablyRestrictedPermission; 1219 synchronized (mLock) { 1220 final Permission bp = mRegistry.getPermission(permName); 1221 if (bp == null) { 1222 Slog.w(TAG, "No such permissions: " + permName); 1223 return false; 1224 } 1225 isImmutablyRestrictedPermission = bp.isHardOrSoftRestricted() 1226 && bp.isImmutablyRestricted(); 1227 } 1228 if (isImmutablyRestrictedPermission && mContext.checkCallingOrSelfPermission( 1229 Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS) 1230 != PackageManager.PERMISSION_GRANTED) { 1231 throw new SecurityException("Cannot modify allowlisting of an immutably " 1232 + "restricted permission: " + permName); 1233 } 1234 return true; 1235 } 1236 1237 @Override removeAllowlistedRestrictedPermission(@onNull String packageName, @NonNull String permName, @PermissionWhitelistFlags int flags, @UserIdInt int userId)1238 public boolean removeAllowlistedRestrictedPermission(@NonNull String packageName, 1239 @NonNull String permName, @PermissionWhitelistFlags int flags, 1240 @UserIdInt int userId) { 1241 // Other argument checks are done in get/setAllowlistedRestrictedPermissions 1242 Objects.requireNonNull(permName); 1243 1244 if (!checkExistsAndEnforceCannotModifyImmutablyRestrictedPermission(permName)) { 1245 return false; 1246 } 1247 1248 final List<String> permissions = 1249 getAllowlistedRestrictedPermissions(packageName, flags, userId); 1250 if (permissions != null && permissions.remove(permName)) { 1251 return setAllowlistedRestrictedPermissions(packageName, permissions, 1252 flags, userId); 1253 } 1254 return false; 1255 } 1256 setAllowlistedRestrictedPermissions(@onNull String packageName, @Nullable List<String> permissions, @PermissionWhitelistFlags int flags, @UserIdInt int userId)1257 private boolean setAllowlistedRestrictedPermissions(@NonNull String packageName, 1258 @Nullable List<String> permissions, @PermissionWhitelistFlags int flags, 1259 @UserIdInt int userId) { 1260 Objects.requireNonNull(packageName); 1261 Preconditions.checkFlagsArgument(flags, 1262 PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE 1263 | PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM 1264 | PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER); 1265 Preconditions.checkArgument(Integer.bitCount(flags) == 1); 1266 Preconditions.checkArgumentNonNegative(userId, null); 1267 1268 if (UserHandle.getCallingUserId() != userId) { 1269 mContext.enforceCallingOrSelfPermission( 1270 Manifest.permission.INTERACT_ACROSS_USERS, 1271 "setAllowlistedRestrictedPermissions for user " + userId); 1272 } 1273 1274 final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName); 1275 if (pkg == null) { 1276 return false; 1277 } 1278 1279 final int callingUid = Binder.getCallingUid(); 1280 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, UserHandle.getCallingUserId())) { 1281 return false; 1282 } 1283 1284 final boolean isCallerPrivileged = mContext.checkCallingOrSelfPermission( 1285 Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS) 1286 == PackageManager.PERMISSION_GRANTED; 1287 final boolean isCallerInstallerOnRecord = 1288 mPackageManagerInt.isCallerInstallerOfRecord(pkg, callingUid); 1289 1290 if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM) != 0 && !isCallerPrivileged) { 1291 throw new SecurityException("Modifying system allowlist requires " 1292 + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS); 1293 } 1294 1295 if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE) != 0) { 1296 if (!isCallerPrivileged && !isCallerInstallerOnRecord) { 1297 throw new SecurityException("Modifying upgrade allowlist requires" 1298 + " being installer on record or " 1299 + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS); 1300 } 1301 final List<String> allowlistedPermissions = 1302 getAllowlistedRestrictedPermissions(pkg.getPackageName(), flags, userId); 1303 if (permissions == null || permissions.isEmpty()) { 1304 if (allowlistedPermissions == null || allowlistedPermissions.isEmpty()) { 1305 return true; 1306 } 1307 } else { 1308 // Only the system can add and remove while the installer can only remove. 1309 final int permissionCount = permissions.size(); 1310 for (int i = 0; i < permissionCount; i++) { 1311 if ((allowlistedPermissions == null 1312 || !allowlistedPermissions.contains(permissions.get(i))) 1313 && !isCallerPrivileged) { 1314 throw new SecurityException("Adding to upgrade allowlist requires" 1315 + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS); 1316 } 1317 } 1318 } 1319 1320 if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER) != 0) { 1321 if (!isCallerPrivileged && !isCallerInstallerOnRecord) { 1322 throw new SecurityException("Modifying installer allowlist requires" 1323 + " being installer on record or " 1324 + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS); 1325 } 1326 } 1327 } 1328 1329 final long identity = Binder.clearCallingIdentity(); 1330 try { 1331 setAllowlistedRestrictedPermissionsInternal(pkg, permissions, flags, userId); 1332 } finally { 1333 Binder.restoreCallingIdentity(identity); 1334 } 1335 1336 return true; 1337 } 1338 1339 @Override setAutoRevokeExempted( @onNull String packageName, boolean exempted, int userId)1340 public boolean setAutoRevokeExempted( 1341 @NonNull String packageName, boolean exempted, int userId) { 1342 Objects.requireNonNull(packageName); 1343 1344 final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName); 1345 final int callingUid = Binder.getCallingUid(); 1346 1347 if (!checkAutoRevokeAccess(pkg, callingUid)) { 1348 return false; 1349 } 1350 1351 return setAutoRevokeExemptedInternal(pkg, exempted, userId); 1352 } 1353 setAutoRevokeExemptedInternal(@onNull AndroidPackage pkg, boolean exempted, @UserIdInt int userId)1354 private boolean setAutoRevokeExemptedInternal(@NonNull AndroidPackage pkg, boolean exempted, 1355 @UserIdInt int userId) { 1356 final int packageUid = UserHandle.getUid(userId, pkg.getUid()); 1357 if (mAppOpsManager.checkOpNoThrow(AppOpsManager.OP_AUTO_REVOKE_MANAGED_BY_INSTALLER, 1358 packageUid, pkg.getPackageName()) != MODE_ALLOWED) { 1359 // Allowlist user set - don't override 1360 return false; 1361 } 1362 1363 final long identity = Binder.clearCallingIdentity(); 1364 try { 1365 mAppOpsManager.setMode(AppOpsManager.OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED, packageUid, 1366 pkg.getPackageName(), exempted ? MODE_IGNORED : MODE_ALLOWED); 1367 } finally { 1368 Binder.restoreCallingIdentity(identity); 1369 } 1370 return true; 1371 } 1372 checkAutoRevokeAccess(AndroidPackage pkg, int callingUid)1373 private boolean checkAutoRevokeAccess(AndroidPackage pkg, int callingUid) { 1374 if (pkg == null) { 1375 return false; 1376 } 1377 1378 final boolean isCallerPrivileged = mContext.checkCallingOrSelfPermission( 1379 Manifest.permission.WHITELIST_AUTO_REVOKE_PERMISSIONS) 1380 == PackageManager.PERMISSION_GRANTED; 1381 final boolean isCallerInstallerOnRecord = 1382 mPackageManagerInt.isCallerInstallerOfRecord(pkg, callingUid); 1383 1384 if (!isCallerPrivileged && !isCallerInstallerOnRecord) { 1385 throw new SecurityException("Caller must either hold " 1386 + Manifest.permission.WHITELIST_AUTO_REVOKE_PERMISSIONS 1387 + " or be the installer on record"); 1388 } 1389 return true; 1390 } 1391 1392 @Override isAutoRevokeExempted(@onNull String packageName, int userId)1393 public boolean isAutoRevokeExempted(@NonNull String packageName, int userId) { 1394 Objects.requireNonNull(packageName); 1395 1396 final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName); 1397 final int callingUid = Binder.getCallingUid(); 1398 if (mPackageManagerInt.filterAppAccess(packageName, callingUid, userId)) { 1399 return false; 1400 } 1401 1402 if (!checkAutoRevokeAccess(pkg, callingUid)) { 1403 return false; 1404 } 1405 1406 final int packageUid = UserHandle.getUid(userId, pkg.getUid()); 1407 1408 final long identity = Binder.clearCallingIdentity(); 1409 try { 1410 return mAppOpsManager.checkOpNoThrow( 1411 AppOpsManager.OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED, packageUid, packageName) 1412 == MODE_IGNORED; 1413 } finally { 1414 Binder.restoreCallingIdentity(identity); 1415 } 1416 } 1417 1418 @Override grantRuntimePermission(String packageName, String permName, final int userId)1419 public void grantRuntimePermission(String packageName, String permName, final int userId) { 1420 final int callingUid = Binder.getCallingUid(); 1421 final boolean overridePolicy = 1422 checkUidPermission(callingUid, ADJUST_RUNTIME_PERMISSIONS_POLICY) 1423 == PackageManager.PERMISSION_GRANTED; 1424 1425 grantRuntimePermissionInternal(packageName, permName, overridePolicy, 1426 callingUid, userId, mDefaultPermissionCallback); 1427 } 1428 grantRuntimePermissionInternal(String packageName, String permName, boolean overridePolicy, int callingUid, final int userId, PermissionCallback callback)1429 private void grantRuntimePermissionInternal(String packageName, String permName, 1430 boolean overridePolicy, int callingUid, final int userId, PermissionCallback callback) { 1431 if (PermissionManager.DEBUG_TRACE_GRANTS 1432 && PermissionManager.shouldTraceGrant(packageName, permName, userId)) { 1433 Log.i(PermissionManager.LOG_TAG_TRACE_GRANTS, "System is granting " + packageName + " " 1434 + permName + " for user " + userId + " on behalf of uid " + callingUid 1435 + " " + mPackageManagerInt.getNameForUid(callingUid), 1436 new RuntimeException()); 1437 } 1438 if (!mUserManagerInt.exists(userId)) { 1439 Log.e(TAG, "No such user:" + userId); 1440 return; 1441 } 1442 1443 mContext.enforceCallingOrSelfPermission( 1444 android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS, 1445 "grantRuntimePermission"); 1446 1447 enforceCrossUserPermission(callingUid, userId, 1448 true, // requireFullPermission 1449 true, // checkShell 1450 "grantRuntimePermission"); 1451 1452 final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName); 1453 final PackageSetting ps = mPackageManagerInt.getPackageSetting(packageName); 1454 if (pkg == null || ps == null) { 1455 Log.e(TAG, "Unknown package: " + packageName); 1456 return; 1457 } 1458 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) { 1459 throw new IllegalArgumentException("Unknown package: " + packageName); 1460 } 1461 1462 final boolean isRolePermission; 1463 final boolean isSoftRestrictedPermission; 1464 synchronized (mLock) { 1465 final Permission permission = mRegistry.getPermission(permName); 1466 if (permission == null) { 1467 throw new IllegalArgumentException("Unknown permission: " + permName); 1468 } 1469 isRolePermission = permission.isRole(); 1470 isSoftRestrictedPermission = permission.isSoftRestricted(); 1471 } 1472 final boolean mayGrantRolePermission = isRolePermission 1473 && mayManageRolePermission(callingUid); 1474 final boolean mayGrantSoftRestrictedPermission = isSoftRestrictedPermission 1475 && SoftRestrictedPermissionPolicy.forPermission(mContext, 1476 pkg.toAppInfoWithoutState(), pkg, UserHandle.of(userId), permName) 1477 .mayGrantPermission(); 1478 1479 final boolean isRuntimePermission; 1480 final boolean permissionHasGids; 1481 synchronized (mLock) { 1482 final Permission bp = mRegistry.getPermission(permName); 1483 if (bp == null) { 1484 throw new IllegalArgumentException("Unknown permission: " + permName); 1485 } 1486 1487 isRuntimePermission = bp.isRuntime(); 1488 permissionHasGids = bp.hasGids(); 1489 if (isRuntimePermission || bp.isDevelopment()) { 1490 // Good. 1491 } else if (bp.isRole()) { 1492 if (!mayGrantRolePermission) { 1493 throw new SecurityException("Permission " + permName + " is managed by role"); 1494 } 1495 } else { 1496 throw new SecurityException("Permission " + permName + " requested by " 1497 + pkg.getPackageName() + " is not a changeable permission type"); 1498 } 1499 1500 final UidPermissionState uidState = getUidStateLocked(pkg, userId); 1501 if (uidState == null) { 1502 Slog.e(TAG, "Missing permissions state for " + pkg.getPackageName() + " and user " 1503 + userId); 1504 return; 1505 } 1506 1507 if (!(uidState.hasPermissionState(permName) 1508 || pkg.getRequestedPermissions().contains(permName))) { 1509 throw new SecurityException("Package " + pkg.getPackageName() 1510 + " has not requested permission " + permName); 1511 } 1512 1513 // If a permission review is required for legacy apps we represent 1514 // their permissions as always granted runtime ones since we need 1515 // to keep the review required permission flag per user while an 1516 // install permission's state is shared across all users. 1517 if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.M && bp.isRuntime()) { 1518 return; 1519 } 1520 1521 final int flags = uidState.getPermissionFlags(permName); 1522 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) { 1523 Log.e(TAG, "Cannot grant system fixed permission " 1524 + permName + " for package " + packageName); 1525 return; 1526 } 1527 if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) { 1528 Log.e(TAG, "Cannot grant policy fixed permission " 1529 + permName + " for package " + packageName); 1530 return; 1531 } 1532 1533 if (bp.isHardRestricted() 1534 && (flags & PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) == 0) { 1535 Log.e(TAG, "Cannot grant hard restricted non-exempt permission " 1536 + permName + " for package " + packageName); 1537 return; 1538 } 1539 1540 if (bp.isSoftRestricted() && !mayGrantSoftRestrictedPermission) { 1541 Log.e(TAG, "Cannot grant soft restricted permission " + permName + " for package " 1542 + packageName); 1543 return; 1544 } 1545 1546 if (bp.isDevelopment() || bp.isRole()) { 1547 // Development permissions must be handled specially, since they are not 1548 // normal runtime permissions. For now they apply to all users. 1549 // TODO(zhanghai): We are breaking the behavior above by making all permission state 1550 // per-user. It isn't documented behavior and relatively rarely used anyway. 1551 if (!uidState.grantPermission(bp)) { 1552 return; 1553 } 1554 } else { 1555 if (ps.getInstantApp(userId) && !bp.isInstant()) { 1556 throw new SecurityException("Cannot grant non-ephemeral permission" + permName 1557 + " for package " + packageName); 1558 } 1559 1560 if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.M) { 1561 Slog.w(TAG, "Cannot grant runtime permission to a legacy app"); 1562 return; 1563 } 1564 1565 if (!uidState.grantPermission(bp)) { 1566 return; 1567 } 1568 } 1569 } 1570 1571 if (isRuntimePermission) { 1572 logPermission(MetricsEvent.ACTION_PERMISSION_GRANTED, permName, packageName); 1573 } 1574 1575 final int uid = UserHandle.getUid(userId, pkg.getUid()); 1576 if (callback != null) { 1577 if (isRuntimePermission) { 1578 callback.onPermissionGranted(uid, userId); 1579 } else { 1580 callback.onInstallPermissionGranted(); 1581 } 1582 if (permissionHasGids) { 1583 callback.onGidsChanged(UserHandle.getAppId(pkg.getUid()), userId); 1584 } 1585 } 1586 1587 if (isRuntimePermission) { 1588 notifyRuntimePermissionStateChanged(packageName, userId); 1589 } 1590 } 1591 1592 @Override revokeRuntimePermission(String packageName, String permName, int userId, String reason)1593 public void revokeRuntimePermission(String packageName, String permName, int userId, 1594 String reason) { 1595 final int callingUid = Binder.getCallingUid(); 1596 final boolean overridePolicy = 1597 checkUidPermission(callingUid, ADJUST_RUNTIME_PERMISSIONS_POLICY) 1598 == PackageManager.PERMISSION_GRANTED; 1599 1600 revokeRuntimePermissionInternal(packageName, permName, overridePolicy, callingUid, userId, 1601 reason, mDefaultPermissionCallback); 1602 } 1603 revokeRuntimePermissionInternal(String packageName, String permName, boolean overridePolicy, int callingUid, final int userId, String reason, PermissionCallback callback)1604 private void revokeRuntimePermissionInternal(String packageName, String permName, 1605 boolean overridePolicy, int callingUid, final int userId, String reason, 1606 PermissionCallback callback) { 1607 if (PermissionManager.DEBUG_TRACE_PERMISSION_UPDATES 1608 && PermissionManager.shouldTraceGrant(packageName, permName, userId)) { 1609 Log.i(TAG, "System is revoking " + packageName + " " 1610 + permName + " for user " + userId + " on behalf of uid " + callingUid 1611 + " " + mPackageManagerInt.getNameForUid(callingUid), 1612 new RuntimeException()); 1613 } 1614 if (!mUserManagerInt.exists(userId)) { 1615 Log.e(TAG, "No such user:" + userId); 1616 return; 1617 } 1618 1619 mContext.enforceCallingOrSelfPermission( 1620 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS, 1621 "revokeRuntimePermission"); 1622 1623 enforceCrossUserPermission(callingUid, userId, 1624 true, // requireFullPermission 1625 true, // checkShell 1626 "revokeRuntimePermission"); 1627 1628 final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName); 1629 if (pkg == null) { 1630 Log.e(TAG, "Unknown package: " + packageName); 1631 return; 1632 } 1633 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) { 1634 throw new IllegalArgumentException("Unknown package: " + packageName); 1635 } 1636 1637 final boolean isRolePermission; 1638 synchronized (mLock) { 1639 final Permission permission = mRegistry.getPermission(permName); 1640 if (permission == null) { 1641 throw new IllegalArgumentException("Unknown permission: " + permName); 1642 } 1643 isRolePermission = permission.isRole(); 1644 } 1645 final boolean mayRevokeRolePermission = isRolePermission 1646 && mayManageRolePermission(callingUid); 1647 1648 final boolean isRuntimePermission; 1649 synchronized (mLock) { 1650 final Permission bp = mRegistry.getPermission(permName); 1651 if (bp == null) { 1652 throw new IllegalArgumentException("Unknown permission: " + permName); 1653 } 1654 1655 isRuntimePermission = bp.isRuntime(); 1656 if (isRuntimePermission || bp.isDevelopment()) { 1657 // Good. 1658 } else if (bp.isRole()) { 1659 if (!mayRevokeRolePermission) { 1660 throw new SecurityException("Permission " + permName + " is managed by role"); 1661 } 1662 } else { 1663 throw new SecurityException("Permission " + permName + " requested by " 1664 + pkg.getPackageName() + " is not a changeable permission type"); 1665 } 1666 1667 final UidPermissionState uidState = getUidStateLocked(pkg, userId); 1668 if (uidState == null) { 1669 Slog.e(TAG, "Missing permissions state for " + pkg.getPackageName() + " and user " 1670 + userId); 1671 return; 1672 } 1673 1674 if (!(uidState.hasPermissionState(permName) 1675 || pkg.getRequestedPermissions().contains(permName))) { 1676 throw new SecurityException("Package " + pkg.getPackageName() 1677 + " has not requested permission " + permName); 1678 } 1679 1680 // If a permission review is required for legacy apps we represent 1681 // their permissions as always granted runtime ones since we need 1682 // to keep the review required permission flag per user while an 1683 // install permission's state is shared across all users. 1684 if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.M && bp.isRuntime()) { 1685 return; 1686 } 1687 1688 final int flags = uidState.getPermissionFlags(permName); 1689 // Only the system may revoke SYSTEM_FIXED permissions. 1690 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0 1691 && UserHandle.getCallingAppId() != Process.SYSTEM_UID) { 1692 throw new SecurityException("Non-System UID cannot revoke system fixed permission " 1693 + permName + " for package " + packageName); 1694 } 1695 if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) { 1696 throw new SecurityException("Cannot revoke policy fixed permission " 1697 + permName + " for package " + packageName); 1698 } 1699 1700 // Development permissions must be handled specially, since they are not 1701 // normal runtime permissions. For now they apply to all users. 1702 // TODO(zhanghai): We are breaking the behavior above by making all permission state 1703 // per-user. It isn't documented behavior and relatively rarely used anyway. 1704 if (!uidState.revokePermission(bp)) { 1705 return; 1706 } 1707 } 1708 1709 if (isRuntimePermission) { 1710 logPermission(MetricsEvent.ACTION_PERMISSION_REVOKED, permName, packageName); 1711 } 1712 1713 if (callback != null) { 1714 if (isRuntimePermission) { 1715 callback.onPermissionRevoked(UserHandle.getUid(userId, pkg.getUid()), userId, 1716 reason); 1717 } else { 1718 mDefaultPermissionCallback.onInstallPermissionRevoked(); 1719 } 1720 } 1721 1722 if (isRuntimePermission) { 1723 notifyRuntimePermissionStateChanged(packageName, userId); 1724 } 1725 } 1726 mayManageRolePermission(int uid)1727 private boolean mayManageRolePermission(int uid) { 1728 final PackageManager packageManager = mContext.getPackageManager(); 1729 final String[] packageNames = packageManager.getPackagesForUid(uid); 1730 if (packageNames == null) { 1731 return false; 1732 } 1733 final String permissionControllerPackageName = 1734 packageManager.getPermissionControllerPackageName(); 1735 return Arrays.asList(packageNames).contains(permissionControllerPackageName); 1736 } 1737 1738 /** 1739 * Reverts user permission state changes (permissions and flags). 1740 * 1741 * @param pkg The package for which to reset. 1742 * @param userId The device user for which to do a reset. 1743 */ resetRuntimePermissionsInternal(@onNull AndroidPackage pkg, @UserIdInt int userId)1744 private void resetRuntimePermissionsInternal(@NonNull AndroidPackage pkg, 1745 @UserIdInt int userId) { 1746 final String packageName = pkg.getPackageName(); 1747 1748 // These are flags that can change base on user actions. 1749 final int userSettableMask = FLAG_PERMISSION_USER_SET 1750 | FLAG_PERMISSION_USER_FIXED 1751 | FLAG_PERMISSION_REVOKED_COMPAT 1752 | FLAG_PERMISSION_REVIEW_REQUIRED 1753 | FLAG_PERMISSION_ONE_TIME 1754 | FLAG_PERMISSION_SELECTED_LOCATION_ACCURACY; 1755 1756 final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED 1757 | FLAG_PERMISSION_POLICY_FIXED; 1758 1759 // Delay and combine non-async permission callbacks 1760 final int permissionCount = ArrayUtils.size(pkg.getRequestedPermissions()); 1761 final boolean[] permissionRemoved = new boolean[1]; 1762 final ArraySet<Long> revokedPermissions = new ArraySet<>(); 1763 final IntArray syncUpdatedUsers = new IntArray(permissionCount); 1764 final IntArray asyncUpdatedUsers = new IntArray(permissionCount); 1765 1766 PermissionCallback delayingPermCallback = new PermissionCallback() { 1767 public void onGidsChanged(int appId, int userId) { 1768 mDefaultPermissionCallback.onGidsChanged(appId, userId); 1769 } 1770 1771 public void onPermissionChanged() { 1772 mDefaultPermissionCallback.onPermissionChanged(); 1773 } 1774 1775 public void onPermissionGranted(int uid, int userId) { 1776 mDefaultPermissionCallback.onPermissionGranted(uid, userId); 1777 } 1778 1779 public void onInstallPermissionGranted() { 1780 mDefaultPermissionCallback.onInstallPermissionGranted(); 1781 } 1782 1783 public void onPermissionRevoked(int uid, int userId, String reason) { 1784 revokedPermissions.add(IntPair.of(uid, userId)); 1785 1786 syncUpdatedUsers.add(userId); 1787 } 1788 1789 public void onInstallPermissionRevoked() { 1790 mDefaultPermissionCallback.onInstallPermissionRevoked(); 1791 } 1792 1793 public void onPermissionUpdated(int[] updatedUserIds, boolean sync) { 1794 for (int userId : updatedUserIds) { 1795 if (sync) { 1796 syncUpdatedUsers.add(userId); 1797 asyncUpdatedUsers.remove(userId); 1798 } else { 1799 // Don't override sync=true by sync=false 1800 if (syncUpdatedUsers.indexOf(userId) == -1) { 1801 asyncUpdatedUsers.add(userId); 1802 } 1803 } 1804 } 1805 } 1806 1807 public void onPermissionRemoved() { 1808 permissionRemoved[0] = true; 1809 } 1810 1811 public void onInstallPermissionUpdated() { 1812 mDefaultPermissionCallback.onInstallPermissionUpdated(); 1813 } 1814 1815 public void onPermissionUpdatedNotifyListener(@UserIdInt int[] updatedUserIds, 1816 boolean sync, int uid) { 1817 onPermissionUpdated(updatedUserIds, sync); 1818 mOnPermissionChangeListeners.onPermissionsChanged(uid); 1819 } 1820 1821 public void onInstallPermissionUpdatedNotifyListener(int uid) { 1822 mDefaultPermissionCallback.onInstallPermissionUpdatedNotifyListener(uid); 1823 } 1824 }; 1825 1826 for (int i = 0; i < permissionCount; i++) { 1827 final String permName = pkg.getRequestedPermissions().get(i); 1828 1829 final boolean isRuntimePermission; 1830 synchronized (mLock) { 1831 final Permission permission = mRegistry.getPermission(permName); 1832 if (permission == null) { 1833 continue; 1834 } 1835 1836 if (permission.isRemoved()) { 1837 continue; 1838 } 1839 isRuntimePermission = permission.isRuntime(); 1840 } 1841 1842 // If shared user we just reset the state to which only this app contributed. 1843 final String[] pkgNames = mPackageManagerInt.getSharedUserPackagesForPackage( 1844 pkg.getPackageName(), userId); 1845 if (pkgNames.length > 0) { 1846 boolean used = false; 1847 for (String sharedPkgName : pkgNames) { 1848 final AndroidPackage sharedPkg = 1849 mPackageManagerInt.getPackage(sharedPkgName); 1850 if (sharedPkg != null && !sharedPkg.getPackageName().equals(packageName) 1851 && sharedPkg.getRequestedPermissions().contains(permName)) { 1852 used = true; 1853 break; 1854 } 1855 } 1856 if (used) { 1857 continue; 1858 } 1859 } 1860 1861 final int oldFlags = 1862 getPermissionFlagsInternal(packageName, permName, Process.SYSTEM_UID, userId); 1863 1864 // Always clear the user settable flags. 1865 // If permission review is enabled and this is a legacy app, mark the 1866 // permission as requiring a review as this is the initial state. 1867 final int uid = mPackageManagerInt.getPackageUid(packageName, 0, userId); 1868 final int targetSdk = mPackageManagerInt.getUidTargetSdkVersion(uid); 1869 final int flags = (targetSdk < Build.VERSION_CODES.M && isRuntimePermission) 1870 ? FLAG_PERMISSION_REVIEW_REQUIRED | FLAG_PERMISSION_REVOKED_COMPAT 1871 : 0; 1872 1873 updatePermissionFlagsInternal( 1874 packageName, permName, userSettableMask, flags, Process.SYSTEM_UID, userId, 1875 false, delayingPermCallback); 1876 1877 // Below is only runtime permission handling. 1878 if (!isRuntimePermission) { 1879 continue; 1880 } 1881 1882 // Never clobber system or policy. 1883 if ((oldFlags & policyOrSystemFlags) != 0) { 1884 continue; 1885 } 1886 1887 // If this permission was granted by default or role, make sure it is. 1888 if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0 1889 || (oldFlags & FLAG_PERMISSION_GRANTED_BY_ROLE) != 0) { 1890 // PermissionPolicyService will handle the app op for runtime permissions later. 1891 grantRuntimePermissionInternal(packageName, permName, false, 1892 Process.SYSTEM_UID, userId, delayingPermCallback); 1893 // In certain cases we should leave the state unchanged: 1894 // -- If permission review is enabled the permissions for a legacy apps 1895 // are represented as constantly granted runtime ones 1896 // -- If the permission was split from a non-runtime permission 1897 } else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0 1898 && !isPermissionSplitFromNonRuntime(permName, targetSdk)) { 1899 // Otherwise, reset the permission. 1900 revokeRuntimePermissionInternal(packageName, permName, false, Process.SYSTEM_UID, 1901 userId, null, delayingPermCallback); 1902 } 1903 } 1904 1905 // Execute delayed callbacks 1906 if (permissionRemoved[0]) { 1907 mDefaultPermissionCallback.onPermissionRemoved(); 1908 } 1909 1910 // Slight variation on the code in mPermissionCallback.onPermissionRevoked() as we cannot 1911 // kill uid while holding mPackages-lock 1912 if (!revokedPermissions.isEmpty()) { 1913 int numRevokedPermissions = revokedPermissions.size(); 1914 for (int i = 0; i < numRevokedPermissions; i++) { 1915 int revocationUID = IntPair.first(revokedPermissions.valueAt(i)); 1916 int revocationUserId = IntPair.second(revokedPermissions.valueAt(i)); 1917 1918 mOnPermissionChangeListeners.onPermissionsChanged(revocationUID); 1919 1920 // Kill app later as we are holding mPackages 1921 mHandler.post(() -> killUid(UserHandle.getAppId(revocationUID), revocationUserId, 1922 KILL_APP_REASON_PERMISSIONS_REVOKED)); 1923 } 1924 } 1925 1926 mPackageManagerInt.writePermissionSettings(syncUpdatedUsers.toArray(), false); 1927 mPackageManagerInt.writePermissionSettings(asyncUpdatedUsers.toArray(), true); 1928 } 1929 1930 /** 1931 * Determine if the given permission should be treated as split from a 1932 * non-runtime permission for an application targeting the given SDK level. 1933 */ isPermissionSplitFromNonRuntime(String permName, int targetSdk)1934 private boolean isPermissionSplitFromNonRuntime(String permName, int targetSdk) { 1935 final List<PermissionManager.SplitPermissionInfo> splitPerms = getSplitPermissionInfos(); 1936 final int size = splitPerms.size(); 1937 for (int i = 0; i < size; i++) { 1938 final PermissionManager.SplitPermissionInfo splitPerm = splitPerms.get(i); 1939 if (targetSdk < splitPerm.getTargetSdk() 1940 && splitPerm.getNewPermissions().contains(permName)) { 1941 synchronized (mLock) { 1942 final Permission perm = 1943 mRegistry.getPermission(splitPerm.getSplitPermission()); 1944 return perm != null && !perm.isRuntime(); 1945 } 1946 } 1947 } 1948 return false; 1949 } 1950 1951 /** 1952 * This change makes it so that apps are told to show rationale for asking for background 1953 * location access every time they request. 1954 */ 1955 @ChangeId 1956 @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.Q) 1957 private static final long BACKGROUND_RATIONALE_CHANGE_ID = 147316723L; 1958 1959 @Override shouldShowRequestPermissionRationale(String packageName, String permName, @UserIdInt int userId)1960 public boolean shouldShowRequestPermissionRationale(String packageName, String permName, 1961 @UserIdInt int userId) { 1962 final int callingUid = Binder.getCallingUid(); 1963 if (UserHandle.getCallingUserId() != userId) { 1964 mContext.enforceCallingPermission( 1965 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 1966 "canShowRequestPermissionRationale for user " + userId); 1967 } 1968 1969 final int uid = 1970 mPackageManagerInt.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId); 1971 if (UserHandle.getAppId(callingUid) != UserHandle.getAppId(uid)) { 1972 return false; 1973 } 1974 1975 if (checkPermission(packageName, permName, userId) 1976 == PackageManager.PERMISSION_GRANTED) { 1977 return false; 1978 } 1979 1980 final int flags; 1981 1982 final long identity = Binder.clearCallingIdentity(); 1983 try { 1984 flags = getPermissionFlagsInternal(packageName, permName, callingUid, userId); 1985 } finally { 1986 Binder.restoreCallingIdentity(identity); 1987 } 1988 1989 final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED 1990 | PackageManager.FLAG_PERMISSION_POLICY_FIXED 1991 | PackageManager.FLAG_PERMISSION_USER_FIXED; 1992 1993 if ((flags & fixedFlags) != 0) { 1994 return false; 1995 } 1996 1997 synchronized (mLock) { 1998 final Permission permission = mRegistry.getPermission(permName); 1999 if (permission == null) { 2000 return false; 2001 } 2002 if (permission.isHardRestricted() 2003 && (flags & FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) == 0) { 2004 return false; 2005 } 2006 } 2007 2008 final long token = Binder.clearCallingIdentity(); 2009 try { 2010 if (permName.equals(Manifest.permission.ACCESS_BACKGROUND_LOCATION) 2011 && mPlatformCompat.isChangeEnabledByPackageName(BACKGROUND_RATIONALE_CHANGE_ID, 2012 packageName, userId)) { 2013 return true; 2014 } 2015 } catch (RemoteException e) { 2016 Log.e(TAG, "Unable to check if compatibility change is enabled.", e); 2017 } finally { 2018 Binder.restoreCallingIdentity(token); 2019 } 2020 2021 return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0; 2022 } 2023 2024 @Override isPermissionRevokedByPolicy(String packageName, String permName, int userId)2025 public boolean isPermissionRevokedByPolicy(String packageName, String permName, int userId) { 2026 if (UserHandle.getCallingUserId() != userId) { 2027 mContext.enforceCallingPermission( 2028 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 2029 "isPermissionRevokedByPolicy for user " + userId); 2030 } 2031 2032 if (checkPermission(packageName, permName, userId) == PackageManager.PERMISSION_GRANTED) { 2033 return false; 2034 } 2035 2036 final int callingUid = Binder.getCallingUid(); 2037 if (mPackageManagerInt.filterAppAccess(packageName, callingUid, userId)) { 2038 return false; 2039 } 2040 2041 final long identity = Binder.clearCallingIdentity(); 2042 try { 2043 final int flags = getPermissionFlagsInternal(packageName, permName, callingUid, userId); 2044 return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0; 2045 } finally { 2046 Binder.restoreCallingIdentity(identity); 2047 } 2048 } 2049 2050 /** 2051 * Get the state of the runtime permissions as xml file. 2052 * 2053 * <p>Can not be called on main thread. 2054 * 2055 * @param userId The user ID the data should be extracted for 2056 * 2057 * @return The state as a xml file 2058 */ 2059 @Nullable backupRuntimePermissions(@serIdInt int userId)2060 private byte[] backupRuntimePermissions(@UserIdInt int userId) { 2061 CompletableFuture<byte[]> backup = new CompletableFuture<>(); 2062 mPermissionControllerManager.getRuntimePermissionBackup(UserHandle.of(userId), 2063 mContext.getMainExecutor(), backup::complete); 2064 2065 try { 2066 return backup.get(BACKUP_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS); 2067 } catch (InterruptedException | ExecutionException | TimeoutException e) { 2068 Slog.e(TAG, "Cannot create permission backup for user " + userId, e); 2069 return null; 2070 } 2071 } 2072 2073 /** 2074 * Restore a permission state previously backed up via {@link #backupRuntimePermissions}. 2075 * 2076 * <p>If not all state can be restored, the un-appliable state will be delayed and can be 2077 * applied via {@link #restoreDelayedRuntimePermissions}. 2078 * 2079 * @param backup The state as an xml file 2080 * @param userId The user ID the data should be restored for 2081 */ restoreRuntimePermissions(@onNull byte[] backup, @UserIdInt int userId)2082 private void restoreRuntimePermissions(@NonNull byte[] backup, @UserIdInt int userId) { 2083 synchronized (mLock) { 2084 mHasNoDelayedPermBackup.delete(userId); 2085 } 2086 mPermissionControllerManager.stageAndApplyRuntimePermissionsBackup(backup, 2087 UserHandle.of(userId)); 2088 } 2089 2090 /** 2091 * Try to apply permission backup that was previously not applied. 2092 * 2093 * <p>Can not be called on main thread. 2094 * 2095 * @param packageName The package that is newly installed 2096 * @param userId The user ID the package is installed for 2097 * 2098 * @see #restoreRuntimePermissions 2099 */ restoreDelayedRuntimePermissions(@onNull String packageName, @UserIdInt int userId)2100 private void restoreDelayedRuntimePermissions(@NonNull String packageName, 2101 @UserIdInt int userId) { 2102 synchronized (mLock) { 2103 if (mHasNoDelayedPermBackup.get(userId, false)) { 2104 return; 2105 } 2106 } 2107 mPermissionControllerManager.applyStagedRuntimePermissionBackup(packageName, 2108 UserHandle.of(userId), mContext.getMainExecutor(), (hasMoreBackup) -> { 2109 if (hasMoreBackup) { 2110 return; 2111 } 2112 synchronized (mLock) { 2113 mHasNoDelayedPermBackup.put(userId, true); 2114 } 2115 }); 2116 } 2117 addOnRuntimePermissionStateChangedListener(@onNull OnRuntimePermissionStateChangedListener listener)2118 private void addOnRuntimePermissionStateChangedListener(@NonNull 2119 OnRuntimePermissionStateChangedListener listener) { 2120 synchronized (mLock) { 2121 mRuntimePermissionStateChangedListeners.add(listener); 2122 } 2123 } 2124 removeOnRuntimePermissionStateChangedListener(@onNull OnRuntimePermissionStateChangedListener listener)2125 private void removeOnRuntimePermissionStateChangedListener(@NonNull 2126 OnRuntimePermissionStateChangedListener listener) { 2127 synchronized (mLock) { 2128 mRuntimePermissionStateChangedListeners.remove(listener); 2129 } 2130 } 2131 notifyRuntimePermissionStateChanged(@onNull String packageName, @UserIdInt int userId)2132 private void notifyRuntimePermissionStateChanged(@NonNull String packageName, 2133 @UserIdInt int userId) { 2134 FgThread.getHandler().sendMessage(PooledLambda.obtainMessage 2135 (PermissionManagerService::doNotifyRuntimePermissionStateChanged, 2136 PermissionManagerService.this, packageName, userId)); 2137 } 2138 doNotifyRuntimePermissionStateChanged(@onNull String packageName, @UserIdInt int userId)2139 private void doNotifyRuntimePermissionStateChanged(@NonNull String packageName, 2140 @UserIdInt int userId) { 2141 final ArrayList<OnRuntimePermissionStateChangedListener> listeners; 2142 synchronized (mLock) { 2143 if (mRuntimePermissionStateChangedListeners.isEmpty()) { 2144 return; 2145 } 2146 listeners = new ArrayList<>(mRuntimePermissionStateChangedListeners); 2147 } 2148 final int listenerCount = listeners.size(); 2149 for (int i = 0; i < listenerCount; i++) { 2150 listeners.get(i).onRuntimePermissionStateChanged(packageName, userId); 2151 } 2152 } 2153 startShellPermissionIdentityDelegationInternal(int uid, @NonNull String packageName, @Nullable List<String> permissionNames)2154 private void startShellPermissionIdentityDelegationInternal(int uid, 2155 @NonNull String packageName, @Nullable List<String> permissionNames) { 2156 synchronized (mLock) { 2157 final CheckPermissionDelegate oldDelegate = mCheckPermissionDelegate; 2158 if (oldDelegate != null && oldDelegate.getDelegatedUid() != uid) { 2159 throw new SecurityException( 2160 "Shell can delegate permissions only to one UID at a time"); 2161 } 2162 final ShellDelegate delegate = new ShellDelegate(uid, packageName, permissionNames); 2163 setCheckPermissionDelegateLocked(delegate); 2164 } 2165 } 2166 stopShellPermissionIdentityDelegationInternal()2167 private void stopShellPermissionIdentityDelegationInternal() { 2168 synchronized (mLock) { 2169 setCheckPermissionDelegateLocked(null); 2170 } 2171 } 2172 2173 @Nullable getDelegatedShellPermissionsInternal()2174 private List<String> getDelegatedShellPermissionsInternal() { 2175 synchronized (mLock) { 2176 if (mCheckPermissionDelegate == null) { 2177 return Collections.EMPTY_LIST; 2178 } 2179 return mCheckPermissionDelegate.getDelegatedPermissionNames(); 2180 } 2181 } 2182 setCheckPermissionDelegateLocked(@ullable CheckPermissionDelegate delegate)2183 private void setCheckPermissionDelegateLocked(@Nullable CheckPermissionDelegate delegate) { 2184 if (delegate != null || mCheckPermissionDelegate != null) { 2185 PackageManager.invalidatePackageInfoCache(); 2186 } 2187 mCheckPermissionDelegate = delegate; 2188 } 2189 2190 /** 2191 * If the app is updated, and has scoped storage permissions, then it is possible that the 2192 * app updated in an attempt to get unscoped storage. If so, revoke all storage permissions. 2193 * @param newPackage The new package that was installed 2194 * @param oldPackage The old package that was updated 2195 */ revokeStoragePermissionsIfScopeExpandedInternal( @onNull AndroidPackage newPackage, @NonNull AndroidPackage oldPackage)2196 private void revokeStoragePermissionsIfScopeExpandedInternal( 2197 @NonNull AndroidPackage newPackage, 2198 @NonNull AndroidPackage oldPackage) { 2199 boolean downgradedSdk = oldPackage.getTargetSdkVersion() >= Build.VERSION_CODES.Q 2200 && newPackage.getTargetSdkVersion() < Build.VERSION_CODES.Q; 2201 boolean upgradedSdk = oldPackage.getTargetSdkVersion() < Build.VERSION_CODES.Q 2202 && newPackage.getTargetSdkVersion() >= Build.VERSION_CODES.Q; 2203 boolean newlyRequestsLegacy = !upgradedSdk && !oldPackage.isRequestLegacyExternalStorage() 2204 && newPackage.isRequestLegacyExternalStorage(); 2205 2206 if (!newlyRequestsLegacy && !downgradedSdk) { 2207 return; 2208 } 2209 2210 final int callingUid = Binder.getCallingUid(); 2211 for (int userId: getAllUserIds()) { 2212 int numRequestedPermissions = newPackage.getRequestedPermissions().size(); 2213 for (int i = 0; i < numRequestedPermissions; i++) { 2214 PermissionInfo permInfo = getPermissionInfo( 2215 newPackage.getRequestedPermissions().get(i), 2216 newPackage.getPackageName(), 0); 2217 if (permInfo == null || !STORAGE_PERMISSIONS.contains(permInfo.name)) { 2218 continue; 2219 } 2220 2221 EventLog.writeEvent(0x534e4554, "171430330", newPackage.getUid(), 2222 "Revoking permission " + permInfo.name + " from package " 2223 + newPackage.getPackageName() + " as either the sdk downgraded " 2224 + downgradedSdk + " or newly requested legacy full storage " 2225 + newlyRequestsLegacy); 2226 2227 try { 2228 revokeRuntimePermissionInternal(newPackage.getPackageName(), permInfo.name, 2229 false, callingUid, userId, null, mDefaultPermissionCallback); 2230 } catch (IllegalStateException | SecurityException e) { 2231 Log.e(TAG, "unable to revoke " + permInfo.name + " for " 2232 + newPackage.getPackageName() + " user " + userId, e); 2233 } 2234 } 2235 } 2236 2237 } 2238 2239 /** 2240 * We might auto-grant permissions if any permission of the group is already granted. Hence if 2241 * the group of a granted permission changes we need to revoke it to avoid having permissions of 2242 * the new group auto-granted. 2243 * 2244 * @param newPackage The new package that was installed 2245 * @param oldPackage The old package that was updated 2246 */ 2247 private void revokeRuntimePermissionsIfGroupChangedInternal(@NonNull AndroidPackage newPackage, 2248 @NonNull AndroidPackage oldPackage) { 2249 final int numOldPackagePermissions = ArrayUtils.size(oldPackage.getPermissions()); 2250 final ArrayMap<String, String> oldPermissionNameToGroupName 2251 = new ArrayMap<>(numOldPackagePermissions); 2252 2253 for (int i = 0; i < numOldPackagePermissions; i++) { 2254 final ParsedPermission permission = oldPackage.getPermissions().get(i); 2255 2256 if (permission.getParsedPermissionGroup() != null) { 2257 oldPermissionNameToGroupName.put(permission.getName(), 2258 permission.getParsedPermissionGroup().getName()); 2259 } 2260 } 2261 2262 final int callingUid = Binder.getCallingUid(); 2263 final int numNewPackagePermissions = ArrayUtils.size(newPackage.getPermissions()); 2264 for (int newPermissionNum = 0; newPermissionNum < numNewPackagePermissions; 2265 newPermissionNum++) { 2266 final ParsedPermission newPermission = 2267 newPackage.getPermissions().get(newPermissionNum); 2268 final int newProtection = newPermission.getProtection(); 2269 2270 if ((newProtection & PermissionInfo.PROTECTION_DANGEROUS) != 0) { 2271 final String permissionName = newPermission.getName(); 2272 final String newPermissionGroupName = 2273 newPermission.getParsedPermissionGroup() == null 2274 ? null : newPermission.getParsedPermissionGroup().getName(); 2275 final String oldPermissionGroupName = oldPermissionNameToGroupName.get( 2276 permissionName); 2277 2278 if (newPermissionGroupName != null 2279 && !newPermissionGroupName.equals(oldPermissionGroupName)) { 2280 final int[] userIds = mUserManagerInt.getUserIds(); 2281 mPackageManagerInt.forEachPackage(pkg -> { 2282 final String packageName = pkg.getPackageName(); 2283 for (final int userId : userIds) { 2284 final int permissionState = checkPermission(packageName, permissionName, 2285 userId); 2286 if (permissionState == PackageManager.PERMISSION_GRANTED) { 2287 EventLog.writeEvent(0x534e4554, "72710897", 2288 newPackage.getUid(), 2289 "Revoking permission " + permissionName + 2290 " from package " + packageName + 2291 " as the group changed from " + oldPermissionGroupName + 2292 " to " + newPermissionGroupName); 2293 2294 try { 2295 revokeRuntimePermissionInternal(packageName, permissionName, 2296 false, callingUid, userId, null, 2297 mDefaultPermissionCallback); 2298 } catch (IllegalArgumentException e) { 2299 Slog.e(TAG, "Could not revoke " + permissionName + " from " 2300 + packageName, e); 2301 } 2302 } 2303 } 2304 }); 2305 } 2306 } 2307 } 2308 } 2309 2310 /** 2311 * If permissions are upgraded to runtime, or their owner changes to the system, then any 2312 * granted permissions must be revoked. 2313 * 2314 * @param permissionsToRevoke A list of permission names to revoke 2315 */ 2316 private void revokeRuntimePermissionsIfPermissionDefinitionChangedInternal( 2317 @NonNull List<String> permissionsToRevoke) { 2318 final int[] userIds = mUserManagerInt.getUserIds(); 2319 final int numPermissions = permissionsToRevoke.size(); 2320 final int callingUid = Binder.getCallingUid(); 2321 2322 for (int permNum = 0; permNum < numPermissions; permNum++) { 2323 final String permName = permissionsToRevoke.get(permNum); 2324 synchronized (mLock) { 2325 final Permission bp = mRegistry.getPermission(permName); 2326 if (bp == null || !bp.isRuntime()) { 2327 continue; 2328 } 2329 } 2330 mPackageManagerInt.forEachPackage(pkg -> { 2331 final String packageName = pkg.getPackageName(); 2332 final int appId = pkg.getUid(); 2333 if (appId < Process.FIRST_APPLICATION_UID) { 2334 // do not revoke from system apps 2335 return; 2336 } 2337 for (final int userId : userIds) { 2338 final int permissionState = checkPermissionImpl(packageName, permName, 2339 userId); 2340 final int flags = getPermissionFlags(packageName, permName, userId); 2341 final int flagMask = FLAG_PERMISSION_SYSTEM_FIXED 2342 | FLAG_PERMISSION_POLICY_FIXED 2343 | FLAG_PERMISSION_GRANTED_BY_DEFAULT 2344 | FLAG_PERMISSION_GRANTED_BY_ROLE; 2345 if (permissionState == PackageManager.PERMISSION_GRANTED 2346 && (flags & flagMask) == 0) { 2347 final int uid = UserHandle.getUid(userId, appId); 2348 EventLog.writeEvent(0x534e4554, "154505240", uid, 2349 "Revoking permission " + permName + " from package " 2350 + packageName + " due to definition change"); 2351 EventLog.writeEvent(0x534e4554, "168319670", uid, 2352 "Revoking permission " + permName + " from package " 2353 + packageName + " due to definition change"); 2354 Slog.e(TAG, "Revoking permission " + permName + " from package " 2355 + packageName + " due to definition change"); 2356 try { 2357 revokeRuntimePermissionInternal(packageName, permName, 2358 false, callingUid, userId, null, mDefaultPermissionCallback); 2359 } catch (Exception e) { 2360 Slog.e(TAG, "Could not revoke " + permName + " from " 2361 + packageName, e); 2362 } 2363 } 2364 } 2365 }); 2366 } 2367 } 2368 2369 private List<String> addAllPermissionsInternal(@NonNull AndroidPackage pkg) { 2370 final int N = ArrayUtils.size(pkg.getPermissions()); 2371 ArrayList<String> definitionChangedPermissions = new ArrayList<>(); 2372 for (int i=0; i<N; i++) { 2373 ParsedPermission p = pkg.getPermissions().get(i); 2374 2375 // Assume by default that we did not install this permission into the system. 2376 p.setFlags(p.getFlags() & ~PermissionInfo.FLAG_INSTALLED); 2377 2378 final PermissionInfo permissionInfo; 2379 final Permission oldPermission; 2380 synchronized (mLock) { 2381 // Now that permission groups have a special meaning, we ignore permission 2382 // groups for legacy apps to prevent unexpected behavior. In particular, 2383 // permissions for one app being granted to someone just because they happen 2384 // to be in a group defined by another app (before this had no implications). 2385 if (pkg.getTargetSdkVersion() > Build.VERSION_CODES.LOLLIPOP_MR1) { 2386 p.setParsedPermissionGroup(mRegistry.getPermissionGroup(p.getGroup())); 2387 // Warn for a permission in an unknown group. 2388 if (DEBUG_PERMISSIONS 2389 && p.getGroup() != null && p.getParsedPermissionGroup() == null) { 2390 Slog.i(TAG, "Permission " + p.getName() + " from package " 2391 + p.getPackageName() + " in an unknown group " + p.getGroup()); 2392 } 2393 } 2394 2395 permissionInfo = PackageInfoUtils.generatePermissionInfo(p, 2396 PackageManager.GET_META_DATA); 2397 oldPermission = p.isTree() ? mRegistry.getPermissionTree(p.getName()) 2398 : mRegistry.getPermission(p.getName()); 2399 } 2400 // TODO(zhanghai): Maybe we should store whether a permission is owned by system inside 2401 // itself. 2402 final boolean isOverridingSystemPermission = Permission.isOverridingSystemPermission( 2403 oldPermission, permissionInfo, mPackageManagerInt); 2404 synchronized (mLock) { 2405 final Permission permission = Permission.createOrUpdate(oldPermission, 2406 permissionInfo, pkg, mRegistry.getPermissionTrees(), 2407 isOverridingSystemPermission); 2408 if (p.isTree()) { 2409 mRegistry.addPermissionTree(permission); 2410 } else { 2411 mRegistry.addPermission(permission); 2412 } 2413 if (permission.isInstalled()) { 2414 p.setFlags(p.getFlags() | PermissionInfo.FLAG_INSTALLED); 2415 } 2416 if (permission.isDefinitionChanged()) { 2417 definitionChangedPermissions.add(p.getName()); 2418 permission.setDefinitionChanged(false); 2419 } 2420 } 2421 } 2422 return definitionChangedPermissions; 2423 } 2424 2425 private void addAllPermissionGroupsInternal(@NonNull AndroidPackage pkg) { 2426 synchronized (mLock) { 2427 final int N = ArrayUtils.size(pkg.getPermissionGroups()); 2428 StringBuilder r = null; 2429 for (int i = 0; i < N; i++) { 2430 final ParsedPermissionGroup pg = pkg.getPermissionGroups().get(i); 2431 final ParsedPermissionGroup cur = mRegistry.getPermissionGroup(pg.getName()); 2432 final String curPackageName = (cur == null) ? null : cur.getPackageName(); 2433 final boolean isPackageUpdate = pg.getPackageName().equals(curPackageName); 2434 if (cur == null || isPackageUpdate) { 2435 mRegistry.addPermissionGroup(pg); 2436 if (DEBUG_PACKAGE_SCANNING) { 2437 if (r == null) { 2438 r = new StringBuilder(256); 2439 } else { 2440 r.append(' '); 2441 } 2442 if (isPackageUpdate) { 2443 r.append("UPD:"); 2444 } 2445 r.append(pg.getName()); 2446 } 2447 } else { 2448 Slog.w(TAG, "Permission group " + pg.getName() + " from package " 2449 + pg.getPackageName() + " ignored: original from " 2450 + cur.getPackageName()); 2451 if (DEBUG_PACKAGE_SCANNING) { 2452 if (r == null) { 2453 r = new StringBuilder(256); 2454 } else { 2455 r.append(' '); 2456 } 2457 r.append("DUP:"); 2458 r.append(pg.getName()); 2459 } 2460 } 2461 } 2462 if (r != null && DEBUG_PACKAGE_SCANNING) { 2463 Log.d(TAG, " Permission Groups: " + r); 2464 } 2465 } 2466 } 2467 2468 private void removeAllPermissionsInternal(@NonNull AndroidPackage pkg) { 2469 synchronized (mLock) { 2470 int N = ArrayUtils.size(pkg.getPermissions()); 2471 StringBuilder r = null; 2472 for (int i=0; i<N; i++) { 2473 ParsedPermission p = pkg.getPermissions().get(i); 2474 Permission bp = mRegistry.getPermission(p.getName()); 2475 if (bp == null) { 2476 bp = mRegistry.getPermissionTree(p.getName()); 2477 } 2478 if (bp != null && bp.isPermission(p)) { 2479 bp.setPermissionInfo(null); 2480 if (DEBUG_REMOVE) { 2481 if (r == null) { 2482 r = new StringBuilder(256); 2483 } else { 2484 r.append(' '); 2485 } 2486 r.append(p.getName()); 2487 } 2488 } 2489 if (p.isAppOp()) { 2490 // TODO(zhanghai): Should we just remove the entry for this permission directly? 2491 mRegistry.removeAppOpPermissionPackage(p.getName(), pkg.getPackageName()); 2492 } 2493 } 2494 if (r != null) { 2495 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r); 2496 } 2497 2498 N = pkg.getRequestedPermissions().size(); 2499 r = null; 2500 for (int i=0; i<N; i++) { 2501 final String permissionName = pkg.getRequestedPermissions().get(i); 2502 final Permission permission = mRegistry.getPermission(permissionName); 2503 if (permission != null && permission.isAppOp()) { 2504 mRegistry.removeAppOpPermissionPackage(permissionName, 2505 pkg.getPackageName()); 2506 } 2507 } 2508 if (r != null) { 2509 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r); 2510 } 2511 } 2512 } 2513 2514 private void onUserRemoved(@UserIdInt int userId) { 2515 synchronized (mLock) { 2516 mState.removeUserState(userId); 2517 } 2518 } 2519 2520 @NonNull 2521 private Set<String> getGrantedPermissionsInternal(@NonNull String packageName, 2522 @UserIdInt int userId) { 2523 final PackageSetting ps = mPackageManagerInt.getPackageSetting(packageName); 2524 if (ps == null) { 2525 return Collections.emptySet(); 2526 } 2527 2528 synchronized (mLock) { 2529 final UidPermissionState uidState = getUidStateLocked(ps, userId); 2530 if (uidState == null) { 2531 Slog.e(TAG, "Missing permissions state for " + packageName + " and user " + userId); 2532 return Collections.emptySet(); 2533 } 2534 if (!ps.getInstantApp(userId)) { 2535 return uidState.getGrantedPermissions(); 2536 } else { 2537 // Install permission state is shared among all users, but instant app state is 2538 // per-user, so we can only filter it here unless we make install permission state 2539 // per-user as well. 2540 final Set<String> instantPermissions = 2541 new ArraySet<>(uidState.getGrantedPermissions()); 2542 instantPermissions.removeIf(permissionName -> { 2543 Permission permission = mRegistry.getPermission(permissionName); 2544 if (permission == null) { 2545 return true; 2546 } 2547 if (!permission.isInstant()) { 2548 EventLog.writeEvent(0x534e4554, "140256621", UserHandle.getUid(userId, 2549 ps.getAppId()), permissionName); 2550 return true; 2551 } 2552 return false; 2553 }); 2554 return instantPermissions; 2555 } 2556 } 2557 } 2558 2559 @NonNull 2560 private int[] getPermissionGidsInternal(@NonNull String permissionName, @UserIdInt int userId) { 2561 synchronized (mLock) { 2562 Permission permission = mRegistry.getPermission(permissionName); 2563 if (permission == null) { 2564 return EmptyArray.INT; 2565 } 2566 return permission.computeGids(userId); 2567 } 2568 } 2569 2570 /** 2571 * Restore the permission state for a package. 2572 * 2573 * <ul> 2574 * <li>During boot the state gets restored from the disk</li> 2575 * <li>During app update the state gets restored from the last version of the app</li> 2576 * </ul> 2577 * 2578 * @param pkg the package the permissions belong to 2579 * @param replace if the package is getting replaced (this might change the requested 2580 * permissions of this package) 2581 * @param packageOfInterest If this is the name of {@code pkg} add extra logging 2582 * @param callback Result call back 2583 * @param filterUserId If not {@link UserHandle.USER_ALL}, only restore the permission state for 2584 * this particular user 2585 */ 2586 private void restorePermissionState(@NonNull AndroidPackage pkg, boolean replace, 2587 @Nullable String packageOfInterest, @Nullable PermissionCallback callback, 2588 @UserIdInt int filterUserId) { 2589 // IMPORTANT: There are two types of permissions: install and runtime. 2590 // Install time permissions are granted when the app is installed to 2591 // all device users and users added in the future. Runtime permissions 2592 // are granted at runtime explicitly to specific users. Normal and signature 2593 // protected permissions are install time permissions. Dangerous permissions 2594 // are install permissions if the app's target SDK is Lollipop MR1 or older, 2595 // otherwise they are runtime permissions. This function does not manage 2596 // runtime permissions except for the case an app targeting Lollipop MR1 2597 // being upgraded to target a newer SDK, in which case dangerous permissions 2598 // are transformed from install time to runtime ones. 2599 2600 final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting( 2601 pkg.getPackageName()); 2602 if (ps == null) { 2603 return; 2604 } 2605 2606 final int[] userIds = filterUserId == UserHandle.USER_ALL ? getAllUserIds() 2607 : new int[] { filterUserId }; 2608 2609 boolean runtimePermissionsRevoked = false; 2610 int[] updatedUserIds = EMPTY_INT_ARRAY; 2611 2612 ArraySet<String> isPrivilegedPermissionAllowlisted = null; 2613 ArraySet<String> shouldGrantSignaturePermission = null; 2614 ArraySet<String> shouldGrantInternalPermission = null; 2615 ArraySet<String> shouldGrantPrivilegedPermissionIfWasGranted = new ArraySet<>(); 2616 final List<String> requestedPermissions = pkg.getRequestedPermissions(); 2617 final int requestedPermissionsSize = requestedPermissions.size(); 2618 for (int i = 0; i < requestedPermissionsSize; i++) { 2619 final String permissionName = pkg.getRequestedPermissions().get(i); 2620 2621 final Permission permission; 2622 synchronized (mLock) { 2623 permission = mRegistry.getPermission(permissionName); 2624 } 2625 if (permission == null) { 2626 continue; 2627 } 2628 if (permission.isPrivileged() 2629 && checkPrivilegedPermissionAllowlist(pkg, ps, permission)) { 2630 if (isPrivilegedPermissionAllowlisted == null) { 2631 isPrivilegedPermissionAllowlisted = new ArraySet<>(); 2632 } 2633 isPrivilegedPermissionAllowlisted.add(permissionName); 2634 } 2635 if (permission.isSignature() && (shouldGrantPermissionBySignature(pkg, permission) 2636 || shouldGrantPermissionByProtectionFlags(pkg, ps, permission, 2637 shouldGrantPrivilegedPermissionIfWasGranted))) { 2638 if (shouldGrantSignaturePermission == null) { 2639 shouldGrantSignaturePermission = new ArraySet<>(); 2640 } 2641 shouldGrantSignaturePermission.add(permissionName); 2642 } 2643 if (permission.isInternal() 2644 && shouldGrantPermissionByProtectionFlags(pkg, ps, permission, 2645 shouldGrantPrivilegedPermissionIfWasGranted)) { 2646 if (shouldGrantInternalPermission == null) { 2647 shouldGrantInternalPermission = new ArraySet<>(); 2648 } 2649 shouldGrantInternalPermission.add(permissionName); 2650 } 2651 } 2652 2653 final SparseBooleanArray isPermissionPolicyInitialized = new SparseBooleanArray(); 2654 if (mPermissionPolicyInternal != null) { 2655 for (final int userId : userIds) { 2656 if (mPermissionPolicyInternal.isInitialized(userId)) { 2657 isPermissionPolicyInitialized.put(userId, true); 2658 } 2659 } 2660 } 2661 2662 synchronized (mLock) { 2663 for (final int userId : userIds) { 2664 final UserPermissionState userState = mState.getOrCreateUserState(userId); 2665 final UidPermissionState uidState = userState.getOrCreateUidState(ps.getAppId()); 2666 2667 if (uidState.isMissing()) { 2668 Collection<String> uidRequestedPermissions; 2669 int targetSdkVersion; 2670 if (!ps.isSharedUser()) { 2671 uidRequestedPermissions = pkg.getRequestedPermissions(); 2672 targetSdkVersion = pkg.getTargetSdkVersion(); 2673 } else { 2674 uidRequestedPermissions = new ArraySet<>(); 2675 targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT; 2676 List<AndroidPackage> packages = ps.getSharedUser().getPackages(); 2677 int packagesSize = packages.size(); 2678 for (int i = 0; i < packagesSize; i++) { 2679 AndroidPackage sharedUserPackage = packages.get(i); 2680 uidRequestedPermissions.addAll( 2681 sharedUserPackage.getRequestedPermissions()); 2682 targetSdkVersion = Math.min(targetSdkVersion, 2683 sharedUserPackage.getTargetSdkVersion()); 2684 } 2685 } 2686 2687 for (String permissionName : uidRequestedPermissions) { 2688 Permission permission = mRegistry.getPermission(permissionName); 2689 if (permission == null) { 2690 continue; 2691 } 2692 if (Objects.equals(permission.getPackageName(), PLATFORM_PACKAGE_NAME) 2693 && permission.isRuntime() && !permission.isRemoved()) { 2694 if (permission.isHardOrSoftRestricted() 2695 || permission.isImmutablyRestricted()) { 2696 uidState.updatePermissionFlags(permission, 2697 FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT, 2698 FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT); 2699 } 2700 if (targetSdkVersion < Build.VERSION_CODES.M) { 2701 uidState.updatePermissionFlags(permission, 2702 PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED 2703 | PackageManager.FLAG_PERMISSION_REVOKED_COMPAT, 2704 PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED 2705 | PackageManager.FLAG_PERMISSION_REVOKED_COMPAT); 2706 uidState.grantPermission(permission); 2707 } 2708 } 2709 } 2710 2711 uidState.setMissing(false); 2712 updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId); 2713 } 2714 2715 UidPermissionState origState = uidState; 2716 2717 boolean changedInstallPermission = false; 2718 2719 if (replace) { 2720 userState.setInstallPermissionsFixed(ps.name, false); 2721 if (!ps.isSharedUser()) { 2722 origState = new UidPermissionState(uidState); 2723 uidState.reset(); 2724 } else { 2725 // We need to know only about runtime permission changes since the 2726 // calling code always writes the install permissions state but 2727 // the runtime ones are written only if changed. The only cases of 2728 // changed runtime permissions here are promotion of an install to 2729 // runtime and revocation of a runtime from a shared user. 2730 if (revokeUnusedSharedUserPermissionsLocked( 2731 ps.getSharedUser().getPackages(), uidState)) { 2732 updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId); 2733 runtimePermissionsRevoked = true; 2734 } 2735 } 2736 } 2737 2738 ArraySet<String> newImplicitPermissions = new ArraySet<>(); 2739 final String friendlyName = pkg.getPackageName() + "(" + pkg.getUid() + ")"; 2740 2741 for (int i = 0; i < requestedPermissionsSize; i++) { 2742 final String permName = requestedPermissions.get(i); 2743 2744 final Permission bp = mRegistry.getPermission(permName); 2745 final boolean appSupportsRuntimePermissions = 2746 pkg.getTargetSdkVersion() >= Build.VERSION_CODES.M; 2747 String legacyActivityRecognitionPermission = null; 2748 2749 if (DEBUG_INSTALL && bp != null) { 2750 Log.i(TAG, "Package " + friendlyName 2751 + " checking " + permName + ": " + bp); 2752 } 2753 2754 // TODO(zhanghai): I don't think we need to check source package setting if 2755 // permission is present, because otherwise the permission should have been 2756 // removed. 2757 if (bp == null /*|| getSourcePackageSetting(bp) == null*/) { 2758 if (packageOfInterest == null || packageOfInterest.equals( 2759 pkg.getPackageName())) { 2760 if (DEBUG_PERMISSIONS) { 2761 Slog.i(TAG, "Unknown permission " + permName 2762 + " in package " + friendlyName); 2763 } 2764 } 2765 continue; 2766 } 2767 2768 // Cache newImplicitPermissions before modifing permissionsState as for the 2769 // shared uids the original and new state are the same object 2770 if (!origState.hasPermissionState(permName) 2771 && (pkg.getImplicitPermissions().contains(permName) 2772 || (permName.equals(Manifest.permission.ACTIVITY_RECOGNITION)))) { 2773 if (pkg.getImplicitPermissions().contains(permName)) { 2774 // If permName is an implicit permission, try to auto-grant 2775 newImplicitPermissions.add(permName); 2776 2777 if (DEBUG_PERMISSIONS) { 2778 Slog.i(TAG, permName + " is newly added for " + friendlyName); 2779 } 2780 } else { 2781 // Special case for Activity Recognition permission. Even if AR 2782 // permission is not an implicit permission we want to add it to the 2783 // list (try to auto-grant it) if the app was installed on a device 2784 // before AR permission was split, regardless of if the app now requests 2785 // the new AR permission or has updated its target SDK and AR is no 2786 // longer implicit to it. This is a compatibility workaround for apps 2787 // when AR permission was split in Q. 2788 // TODO(zhanghai): This calls into SystemConfig, which generally 2789 // shouldn't cause deadlock, but maybe we should keep a cache of the 2790 // split permission list and just eliminate the possibility. 2791 final List<PermissionManager.SplitPermissionInfo> permissionList = 2792 getSplitPermissionInfos(); 2793 int numSplitPerms = permissionList.size(); 2794 for (int splitPermNum = 0; splitPermNum < numSplitPerms; 2795 splitPermNum++) { 2796 PermissionManager.SplitPermissionInfo sp = permissionList.get( 2797 splitPermNum); 2798 String splitPermName = sp.getSplitPermission(); 2799 if (sp.getNewPermissions().contains(permName) 2800 && origState.isPermissionGranted(splitPermName)) { 2801 legacyActivityRecognitionPermission = splitPermName; 2802 newImplicitPermissions.add(permName); 2803 2804 if (DEBUG_PERMISSIONS) { 2805 Slog.i(TAG, permName + " is newly added for " 2806 + friendlyName); 2807 } 2808 break; 2809 } 2810 } 2811 } 2812 } 2813 2814 // TODO(b/140256621): The package instant app method has been removed 2815 // as part of work in b/135203078, so this has been commented out in the 2816 // meantime 2817 // Limit ephemeral apps to ephemeral allowed permissions. 2818 // if (/*pkg.isInstantApp()*/ false && !bp.isInstant()) { 2819 // if (DEBUG_PERMISSIONS) { 2820 // Log.i(TAG, "Denying non-ephemeral permission " + bp.getName() 2821 // + " for package " + pkg.getPackageName()); 2822 // } 2823 // continue; 2824 // } 2825 2826 if (bp.isRuntimeOnly() && !appSupportsRuntimePermissions) { 2827 if (DEBUG_PERMISSIONS) { 2828 Log.i(TAG, "Denying runtime-only permission " + bp.getName() 2829 + " for package " + friendlyName); 2830 } 2831 continue; 2832 } 2833 2834 final String perm = bp.getName(); 2835 2836 // Keep track of app op permissions. 2837 if (bp.isAppOp()) { 2838 mRegistry.addAppOpPermissionPackage(perm, pkg.getPackageName()); 2839 } 2840 2841 boolean shouldGrantNormalPermission = true; 2842 if (bp.isNormal() && !origState.isPermissionGranted(perm)) { 2843 // If this is an existing, non-system package, then 2844 // we can't add any new permissions to it. Runtime 2845 // permissions can be added any time - they are dynamic. 2846 if (!ps.isSystem() && userState.areInstallPermissionsFixed(ps.name)) { 2847 // Except... if this is a permission that was added 2848 // to the platform (note: need to only do this when 2849 // updating the platform). 2850 if (!isNewPlatformPermissionForPackage(perm, pkg)) { 2851 shouldGrantNormalPermission = false; 2852 } 2853 } 2854 } 2855 2856 if (DEBUG_PERMISSIONS) { 2857 Slog.i(TAG, "Considering granting permission " + perm + " to package " 2858 + pkg.getPackageName()); 2859 } 2860 2861 if ((bp.isNormal() && shouldGrantNormalPermission) 2862 || (bp.isSignature() 2863 && (!bp.isPrivileged() || CollectionUtils.contains( 2864 isPrivilegedPermissionAllowlisted, permName)) 2865 && (CollectionUtils.contains(shouldGrantSignaturePermission, 2866 permName) 2867 || (((bp.isPrivileged() && CollectionUtils.contains( 2868 shouldGrantPrivilegedPermissionIfWasGranted, 2869 permName)) || bp.isDevelopment() || bp.isRole()) 2870 && origState.isPermissionGranted(permName)))) 2871 || (bp.isInternal() 2872 && (!bp.isPrivileged() || CollectionUtils.contains( 2873 isPrivilegedPermissionAllowlisted, permName)) 2874 && (CollectionUtils.contains(shouldGrantInternalPermission, 2875 permName) 2876 || (((bp.isPrivileged() && CollectionUtils.contains( 2877 shouldGrantPrivilegedPermissionIfWasGranted, 2878 permName)) || bp.isDevelopment() || bp.isRole()) 2879 && origState.isPermissionGranted(permName))))) { 2880 // Grant an install permission. 2881 if (uidState.grantPermission(bp)) { 2882 changedInstallPermission = true; 2883 } 2884 } else if (bp.isRuntime()) { 2885 boolean hardRestricted = bp.isHardRestricted(); 2886 boolean softRestricted = bp.isSoftRestricted(); 2887 2888 // If permission policy is not ready we don't deal with restricted 2889 // permissions as the policy may allowlist some permissions. Once 2890 // the policy is initialized we would re-evaluate permissions. 2891 final boolean permissionPolicyInitialized = 2892 isPermissionPolicyInitialized.get(userId); 2893 2894 PermissionState origPermState = origState.getPermissionState(perm); 2895 int flags = origPermState != null ? origPermState.getFlags() : 0; 2896 2897 boolean wasChanged = false; 2898 2899 boolean restrictionExempt = 2900 (origState.getPermissionFlags(bp.getName()) 2901 & FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) != 0; 2902 boolean restrictionApplied = (origState.getPermissionFlags( 2903 bp.getName()) & FLAG_PERMISSION_APPLY_RESTRICTION) != 0; 2904 2905 if (appSupportsRuntimePermissions) { 2906 // If hard restricted we don't allow holding it 2907 if (permissionPolicyInitialized && hardRestricted) { 2908 if (!restrictionExempt) { 2909 if (origPermState != null && origPermState.isGranted() 2910 && uidState.revokePermission(bp)) { 2911 wasChanged = true; 2912 } 2913 if (!restrictionApplied) { 2914 flags |= FLAG_PERMISSION_APPLY_RESTRICTION; 2915 wasChanged = true; 2916 } 2917 } 2918 // If soft restricted we allow holding in a restricted form 2919 } else if (permissionPolicyInitialized && softRestricted) { 2920 // Regardless if granted set the restriction flag as it 2921 // may affect app treatment based on this permission. 2922 if (!restrictionExempt && !restrictionApplied) { 2923 flags |= FLAG_PERMISSION_APPLY_RESTRICTION; 2924 wasChanged = true; 2925 } 2926 } 2927 2928 // Remove review flag as it is not necessary anymore 2929 if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) != 0) { 2930 flags &= ~FLAG_PERMISSION_REVIEW_REQUIRED; 2931 wasChanged = true; 2932 } 2933 2934 if ((flags & FLAG_PERMISSION_REVOKED_COMPAT) != 0 2935 && !isPermissionSplitFromNonRuntime(permName, 2936 pkg.getTargetSdkVersion())) { 2937 flags &= ~FLAG_PERMISSION_REVOKED_COMPAT; 2938 wasChanged = true; 2939 // Hard restricted permissions cannot be held. 2940 } else if (!permissionPolicyInitialized 2941 || (!hardRestricted || restrictionExempt)) { 2942 if ((origPermState != null && origPermState.isGranted()) 2943 || legacyActivityRecognitionPermission != null) { 2944 if (!uidState.grantPermission(bp)) { 2945 wasChanged = true; 2946 } 2947 } 2948 } 2949 } else { 2950 if (origPermState == null) { 2951 // New permission 2952 if (PLATFORM_PACKAGE_NAME.equals( 2953 bp.getPackageName())) { 2954 if (!bp.isRemoved()) { 2955 flags |= FLAG_PERMISSION_REVIEW_REQUIRED 2956 | FLAG_PERMISSION_REVOKED_COMPAT; 2957 wasChanged = true; 2958 } 2959 } 2960 } 2961 2962 if (!uidState.isPermissionGranted(bp.getName()) 2963 && uidState.grantPermission(bp)) { 2964 wasChanged = true; 2965 } 2966 2967 // If legacy app always grant the permission but if restricted 2968 // and not exempt take a note a restriction should be applied. 2969 if (permissionPolicyInitialized 2970 && (hardRestricted || softRestricted) 2971 && !restrictionExempt && !restrictionApplied) { 2972 flags |= FLAG_PERMISSION_APPLY_RESTRICTION; 2973 wasChanged = true; 2974 } 2975 } 2976 2977 // If unrestricted or restriction exempt, don't apply restriction. 2978 if (permissionPolicyInitialized) { 2979 if (!(hardRestricted || softRestricted) || restrictionExempt) { 2980 if (restrictionApplied) { 2981 flags &= ~FLAG_PERMISSION_APPLY_RESTRICTION; 2982 // Dropping restriction on a legacy app implies a review 2983 if (!appSupportsRuntimePermissions) { 2984 flags |= FLAG_PERMISSION_REVIEW_REQUIRED; 2985 } 2986 wasChanged = true; 2987 } 2988 } 2989 } 2990 2991 if (wasChanged) { 2992 updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId); 2993 } 2994 2995 uidState.updatePermissionFlags(bp, MASK_PERMISSION_FLAGS_ALL, 2996 flags); 2997 } else { 2998 if (DEBUG_PERMISSIONS) { 2999 boolean wasGranted = uidState.isPermissionGranted(bp.getName()); 3000 if (wasGranted || bp.isAppOp()) { 3001 Slog.i(TAG, (wasGranted ? "Un-granting" : "Not granting") 3002 + " permission " + perm 3003 + " from package " + friendlyName 3004 + " (protectionLevel=" + bp.getProtectionLevel() 3005 + " flags=0x" 3006 + Integer.toHexString(PackageInfoUtils.appInfoFlags(pkg, 3007 ps)) 3008 + ")"); 3009 } 3010 } 3011 if (uidState.removePermissionState(bp.getName())) { 3012 changedInstallPermission = true; 3013 } 3014 } 3015 } 3016 3017 if ((changedInstallPermission || replace) 3018 && !userState.areInstallPermissionsFixed(ps.name) 3019 && !ps.isSystem() || ps.getPkgState().isUpdatedSystemApp()) { 3020 // This is the first that we have heard about this package, so the 3021 // permissions we have now selected are fixed until explicitly 3022 // changed. 3023 userState.setInstallPermissionsFixed(ps.name, true); 3024 } 3025 3026 updatedUserIds = revokePermissionsNoLongerImplicitLocked(uidState, pkg, 3027 userId, updatedUserIds); 3028 updatedUserIds = setInitialGrantForNewImplicitPermissionsLocked(origState, 3029 uidState, pkg, newImplicitPermissions, userId, updatedUserIds); 3030 } 3031 } 3032 3033 updatedUserIds = checkIfLegacyStorageOpsNeedToBeUpdated(pkg, replace, userIds, 3034 updatedUserIds); 3035 3036 // TODO: Kill UIDs whose GIDs or runtime permissions changed. This might be more important 3037 // for shared users. 3038 // Persist the runtime permissions state for users with changes. If permissions 3039 // were revoked because no app in the shared user declares them we have to 3040 // write synchronously to avoid losing runtime permissions state. 3041 if (callback != null) { 3042 callback.onPermissionUpdated(updatedUserIds, runtimePermissionsRevoked); 3043 } 3044 3045 for (int userId : updatedUserIds) { 3046 notifyRuntimePermissionStateChanged(pkg.getPackageName(), userId); 3047 } 3048 } 3049 3050 /** 3051 * Returns all relevant user ids. This list include the current set of created user ids as well 3052 * as pre-created user ids. 3053 * @return user ids for created users and pre-created users 3054 */ 3055 private int[] getAllUserIds() { 3056 return UserManagerService.getInstance().getUserIdsIncludingPreCreated(); 3057 } 3058 3059 /** 3060 * Revoke permissions that are not implicit anymore and that have 3061 * {@link PackageManager#FLAG_PERMISSION_REVOKE_WHEN_REQUESTED} set. 3062 * 3063 * @param ps The state of the permissions of the package 3064 * @param pkg The package that is currently looked at 3065 * @param userIds All user IDs in the system, must be passed in because this method is locked 3066 * @param updatedUserIds a list of user ids that needs to be amended if the permission state 3067 * for a user is changed. 3068 * 3069 * @return The updated value of the {@code updatedUserIds} parameter 3070 */ 3071 @GuardedBy("mLock") 3072 private @NonNull int[] revokePermissionsNoLongerImplicitLocked(@NonNull UidPermissionState ps, 3073 @NonNull AndroidPackage pkg, int userId, @NonNull int[] updatedUserIds) { 3074 String pkgName = pkg.getPackageName(); 3075 boolean supportsRuntimePermissions = pkg.getTargetSdkVersion() 3076 >= Build.VERSION_CODES.M; 3077 3078 for (String permission : ps.getGrantedPermissions()) { 3079 if (pkg.getRequestedPermissions().contains(permission) 3080 && !pkg.getImplicitPermissions().contains(permission)) { 3081 Permission bp = mRegistry.getPermission(permission); 3082 if (bp != null && bp.isRuntime()) { 3083 int flags = ps.getPermissionFlags(permission); 3084 if ((flags & FLAG_PERMISSION_REVOKE_WHEN_REQUESTED) != 0) { 3085 int flagsToRemove = FLAG_PERMISSION_REVOKE_WHEN_REQUESTED; 3086 3087 // We're willing to preserve an implicit "Nearby devices" 3088 // permission grant if this app was already able to interact 3089 // with nearby devices via background location access 3090 boolean preserveGrant = false; 3091 if (ArrayUtils.contains(NEARBY_DEVICES_PERMISSIONS, permission) 3092 && ps.isPermissionGranted( 3093 android.Manifest.permission.ACCESS_BACKGROUND_LOCATION) 3094 && (ps.getPermissionFlags( 3095 android.Manifest.permission.ACCESS_BACKGROUND_LOCATION) 3096 & (FLAG_PERMISSION_REVOKE_WHEN_REQUESTED 3097 | FLAG_PERMISSION_REVOKED_COMPAT)) == 0) { 3098 preserveGrant = true; 3099 } 3100 3101 if ((flags & BLOCKING_PERMISSION_FLAGS) == 0 3102 && supportsRuntimePermissions 3103 && !preserveGrant) { 3104 if (ps.revokePermission(bp)) { 3105 if (DEBUG_PERMISSIONS) { 3106 Slog.i(TAG, "Revoking runtime permission " 3107 + permission + " for " + pkgName 3108 + " as it is now requested"); 3109 } 3110 } 3111 3112 flagsToRemove |= USER_PERMISSION_FLAGS; 3113 } 3114 3115 ps.updatePermissionFlags(bp, flagsToRemove, 0); 3116 updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId); 3117 } 3118 } 3119 } 3120 } 3121 3122 return updatedUserIds; 3123 } 3124 3125 /** 3126 * {@code newPerm} is newly added; Inherit the state from {@code sourcePerms}. 3127 * 3128 * <p>A single new permission can be split off from several source permissions. In this case 3129 * the most leniant state is inherited. 3130 * 3131 * <p>Warning: This does not handle foreground / background permissions 3132 * 3133 * @param sourcePerms The permissions to inherit from 3134 * @param newPerm The permission to inherit to 3135 * @param ps The permission state of the package 3136 * @param pkg The package requesting the permissions 3137 */ 3138 @GuardedBy("mLock") 3139 private void inheritPermissionStateToNewImplicitPermissionLocked( 3140 @NonNull ArraySet<String> sourcePerms, @NonNull String newPerm, 3141 @NonNull UidPermissionState ps, @NonNull AndroidPackage pkg) { 3142 String pkgName = pkg.getPackageName(); 3143 boolean isGranted = false; 3144 int flags = 0; 3145 3146 int numSourcePerm = sourcePerms.size(); 3147 for (int i = 0; i < numSourcePerm; i++) { 3148 String sourcePerm = sourcePerms.valueAt(i); 3149 if (ps.isPermissionGranted(sourcePerm)) { 3150 if (!isGranted) { 3151 flags = 0; 3152 } 3153 3154 isGranted = true; 3155 flags |= ps.getPermissionFlags(sourcePerm); 3156 } else { 3157 if (!isGranted) { 3158 flags |= ps.getPermissionFlags(sourcePerm); 3159 } 3160 } 3161 } 3162 3163 if (isGranted) { 3164 if (DEBUG_PERMISSIONS) { 3165 Slog.i(TAG, newPerm + " inherits runtime perm grant from " + sourcePerms 3166 + " for " + pkgName); 3167 } 3168 3169 ps.grantPermission(mRegistry.getPermission(newPerm)); 3170 } 3171 3172 // Add permission flags 3173 ps.updatePermissionFlags(mRegistry.getPermission(newPerm), flags, flags); 3174 } 3175 3176 /** 3177 * When the app has requested legacy storage we might need to update 3178 * {@link android.app.AppOpsManager#OP_LEGACY_STORAGE}. Hence force an update in 3179 * {@link com.android.server.policy.PermissionPolicyService#synchronizePackagePermissionsAndAppOpsForUser(Context, String, int)} 3180 * 3181 * @param pkg The package for which the permissions are updated 3182 * @param replace If the app is being replaced 3183 * @param userIds All user IDs in the system, must be passed in because this method is locked 3184 * @param updatedUserIds The ids of the users that already changed. 3185 * 3186 * @return The ids of the users that are changed 3187 */ 3188 private @NonNull int[] checkIfLegacyStorageOpsNeedToBeUpdated(@NonNull AndroidPackage pkg, 3189 boolean replace, @NonNull int[] userIds, @NonNull int[] updatedUserIds) { 3190 if (replace && pkg.isRequestLegacyExternalStorage() && ( 3191 pkg.getRequestedPermissions().contains(READ_EXTERNAL_STORAGE) 3192 || pkg.getRequestedPermissions().contains(WRITE_EXTERNAL_STORAGE))) { 3193 return userIds.clone(); 3194 } 3195 3196 return updatedUserIds; 3197 } 3198 3199 /** 3200 * Set the state of a implicit permission that is seen for the first time. 3201 * 3202 * @param origPs The permission state of the package before the split 3203 * @param ps The new permission state 3204 * @param pkg The package the permission belongs to 3205 * @param userId The user ID 3206 * @param updatedUserIds List of users for which the permission state has already been changed 3207 * 3208 * @return List of users for which the permission state has been changed 3209 */ 3210 @GuardedBy("mLock") 3211 private @NonNull int[] setInitialGrantForNewImplicitPermissionsLocked( 3212 @NonNull UidPermissionState origPs, @NonNull UidPermissionState ps, 3213 @NonNull AndroidPackage pkg, @NonNull ArraySet<String> newImplicitPermissions, 3214 @UserIdInt int userId, @NonNull int[] updatedUserIds) { 3215 String pkgName = pkg.getPackageName(); 3216 ArrayMap<String, ArraySet<String>> newToSplitPerms = new ArrayMap<>(); 3217 3218 final List<PermissionManager.SplitPermissionInfo> permissionList = 3219 getSplitPermissionInfos(); 3220 int numSplitPerms = permissionList.size(); 3221 for (int splitPermNum = 0; splitPermNum < numSplitPerms; splitPermNum++) { 3222 PermissionManager.SplitPermissionInfo spi = permissionList.get(splitPermNum); 3223 3224 List<String> newPerms = spi.getNewPermissions(); 3225 int numNewPerms = newPerms.size(); 3226 for (int newPermNum = 0; newPermNum < numNewPerms; newPermNum++) { 3227 String newPerm = newPerms.get(newPermNum); 3228 3229 ArraySet<String> splitPerms = newToSplitPerms.get(newPerm); 3230 if (splitPerms == null) { 3231 splitPerms = new ArraySet<>(); 3232 newToSplitPerms.put(newPerm, splitPerms); 3233 } 3234 3235 splitPerms.add(spi.getSplitPermission()); 3236 } 3237 } 3238 3239 int numNewImplicitPerms = newImplicitPermissions.size(); 3240 for (int newImplicitPermNum = 0; newImplicitPermNum < numNewImplicitPerms; 3241 newImplicitPermNum++) { 3242 String newPerm = newImplicitPermissions.valueAt(newImplicitPermNum); 3243 ArraySet<String> sourcePerms = newToSplitPerms.get(newPerm); 3244 3245 if (sourcePerms != null) { 3246 Permission bp = mRegistry.getPermission(newPerm); 3247 if (bp == null) { 3248 throw new IllegalStateException("Unknown new permission in split permission: " 3249 + newPerm); 3250 } 3251 if (bp.isRuntime()) { 3252 3253 if (!newPerm.equals(Manifest.permission.ACTIVITY_RECOGNITION)) { 3254 ps.updatePermissionFlags(bp, 3255 FLAG_PERMISSION_REVOKE_WHEN_REQUESTED, 3256 FLAG_PERMISSION_REVOKE_WHEN_REQUESTED); 3257 } 3258 updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId); 3259 3260 if (!origPs.hasPermissionState(sourcePerms)) { 3261 boolean inheritsFromInstallPerm = false; 3262 for (int sourcePermNum = 0; sourcePermNum < sourcePerms.size(); 3263 sourcePermNum++) { 3264 final String sourcePerm = sourcePerms.valueAt(sourcePermNum); 3265 Permission sourceBp = mRegistry.getPermission(sourcePerm); 3266 if (sourceBp == null) { 3267 throw new IllegalStateException("Unknown source permission in split" 3268 + " permission: " + sourcePerm); 3269 } 3270 if (!sourceBp.isRuntime()) { 3271 inheritsFromInstallPerm = true; 3272 break; 3273 } 3274 } 3275 3276 if (!inheritsFromInstallPerm) { 3277 // Both permissions are new so nothing to inherit. 3278 if (DEBUG_PERMISSIONS) { 3279 Slog.i(TAG, newPerm + " does not inherit from " + sourcePerms 3280 + " for " + pkgName + " as split permission is also new"); 3281 } 3282 continue; 3283 } 3284 } 3285 3286 // Inherit from new install or existing runtime permissions 3287 inheritPermissionStateToNewImplicitPermissionLocked(sourcePerms, newPerm, ps, 3288 pkg); 3289 } 3290 } 3291 } 3292 3293 return updatedUserIds; 3294 } 3295 3296 @NonNull 3297 @Override 3298 public List<SplitPermissionInfoParcelable> getSplitPermissions() { 3299 return PermissionManager.splitPermissionInfoListToParcelableList(getSplitPermissionInfos()); 3300 } 3301 3302 @NonNull 3303 private List<PermissionManager.SplitPermissionInfo> getSplitPermissionInfos() { 3304 return SystemConfig.getInstance().getSplitPermissions(); 3305 } 3306 3307 @NonNull 3308 private OneTimePermissionUserManager getOneTimePermissionUserManager(@UserIdInt int userId) { 3309 OneTimePermissionUserManager oneTimePermissionUserManager; 3310 synchronized (mLock) { 3311 oneTimePermissionUserManager = mOneTimePermissionUserManagers.get(userId); 3312 if (oneTimePermissionUserManager != null) { 3313 return oneTimePermissionUserManager; 3314 } 3315 } 3316 // We cannot create a new instance of OneTimePermissionUserManager while holding our own 3317 // lock, which may lead to a deadlock with the package manager lock. So we do it in a 3318 // retry-like way, and just discard the newly created instance if someone else managed to be 3319 // a little bit faster than us when we dropped our own lock. 3320 final OneTimePermissionUserManager newOneTimePermissionUserManager = 3321 new OneTimePermissionUserManager(mContext.createContextAsUser(UserHandle.of(userId), 3322 /*flags*/ 0)); 3323 synchronized (mLock) { 3324 oneTimePermissionUserManager = mOneTimePermissionUserManagers.get(userId); 3325 if (oneTimePermissionUserManager != null) { 3326 return oneTimePermissionUserManager; 3327 } 3328 oneTimePermissionUserManager = newOneTimePermissionUserManager; 3329 mOneTimePermissionUserManagers.put(userId, oneTimePermissionUserManager); 3330 } 3331 oneTimePermissionUserManager.registerUninstallListener(); 3332 return oneTimePermissionUserManager; 3333 } 3334 3335 @Override 3336 public void startOneTimePermissionSession(String packageName, @UserIdInt int userId, 3337 long timeoutMillis, int importanceToResetTimer, int importanceToKeepSessionAlive) { 3338 mContext.enforceCallingPermission(Manifest.permission.MANAGE_ONE_TIME_PERMISSION_SESSIONS, 3339 "Must hold " + Manifest.permission.MANAGE_ONE_TIME_PERMISSION_SESSIONS 3340 + " to register permissions as one time."); 3341 Objects.requireNonNull(packageName); 3342 3343 final long token = Binder.clearCallingIdentity(); 3344 try { 3345 getOneTimePermissionUserManager(userId).startPackageOneTimeSession(packageName, 3346 timeoutMillis, importanceToResetTimer, importanceToKeepSessionAlive); 3347 } finally { 3348 Binder.restoreCallingIdentity(token); 3349 } 3350 } 3351 3352 @Override 3353 public void stopOneTimePermissionSession(String packageName, @UserIdInt int userId) { 3354 mContext.enforceCallingPermission(Manifest.permission.MANAGE_ONE_TIME_PERMISSION_SESSIONS, 3355 "Must hold " + Manifest.permission.MANAGE_ONE_TIME_PERMISSION_SESSIONS 3356 + " to remove permissions as one time."); 3357 Objects.requireNonNull(packageName); 3358 3359 final long token = Binder.clearCallingIdentity(); 3360 try { 3361 getOneTimePermissionUserManager(userId).stopPackageOneTimeSession(packageName); 3362 } finally { 3363 Binder.restoreCallingIdentity(token); 3364 } 3365 } 3366 3367 @Override 3368 public void registerAttributionSource(@NonNull AttributionSourceState source) { 3369 mAttributionSourceRegistry 3370 .registerAttributionSource(new AttributionSource(source)); 3371 } 3372 3373 @Override 3374 public boolean isRegisteredAttributionSource(@NonNull AttributionSourceState source) { 3375 return mAttributionSourceRegistry 3376 .isRegisteredAttributionSource(new AttributionSource(source)); 3377 } 3378 3379 @Override 3380 public List<String> getAutoRevokeExemptionRequestedPackages(int userId) { 3381 return getPackagesWithAutoRevokePolicy(AUTO_REVOKE_DISCOURAGED, userId); 3382 } 3383 3384 @Override 3385 public List<String> getAutoRevokeExemptionGrantedPackages(int userId) { 3386 return getPackagesWithAutoRevokePolicy(AUTO_REVOKE_DISALLOWED, userId); 3387 } 3388 3389 @NonNull 3390 private List<String> getPackagesWithAutoRevokePolicy(int autoRevokePolicy, int userId) { 3391 mContext.enforceCallingPermission(Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY, 3392 "Must hold " + Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY); 3393 3394 List<String> result = new ArrayList<>(); 3395 mPackageManagerInt.forEachInstalledPackage(pkg -> { 3396 if (pkg.getAutoRevokePermissions() == autoRevokePolicy) { 3397 result.add(pkg.getPackageName()); 3398 } 3399 }, userId); 3400 return result; 3401 } 3402 3403 private static boolean isNewPlatformPermissionForPackage(String perm, AndroidPackage pkg) { 3404 boolean allowed = false; 3405 final int NP = PackageParser.NEW_PERMISSIONS.length; 3406 for (int ip=0; ip<NP; ip++) { 3407 final PackageParser.NewPermissionInfo npi 3408 = PackageParser.NEW_PERMISSIONS[ip]; 3409 if (npi.name.equals(perm) 3410 && pkg.getTargetSdkVersion() < npi.sdkVersion) { 3411 allowed = true; 3412 Log.i(TAG, "Auto-granting " + perm + " to old pkg " 3413 + pkg.getPackageName()); 3414 break; 3415 } 3416 } 3417 return allowed; 3418 } 3419 3420 private boolean checkPrivilegedPermissionAllowlist(@NonNull AndroidPackage pkg, 3421 @NonNull PackageSetting packageSetting, @NonNull Permission permission) { 3422 if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_DISABLE) { 3423 return true; 3424 } 3425 final String packageName = pkg.getPackageName(); 3426 if (Objects.equals(packageName, PLATFORM_PACKAGE_NAME)) { 3427 return true; 3428 } 3429 if (!pkg.isPrivileged()) { 3430 return true; 3431 } 3432 if (!mPrivilegedPermissionAllowlistSourcePackageNames 3433 .contains(permission.getPackageName())) { 3434 return true; 3435 } 3436 final String permissionName = permission.getName(); 3437 if (isInSystemConfigPrivAppPermissions(pkg, permissionName)) { 3438 return true; 3439 } 3440 if (isInSystemConfigPrivAppDenyPermissions(pkg, permissionName)) { 3441 return false; 3442 } 3443 // Updated system apps do not need to be allowlisted 3444 if (packageSetting.getPkgState().isUpdatedSystemApp()) { 3445 // Let shouldGrantPermissionByProtectionFlags() decide whether the privileged permission 3446 // can be granted, because an updated system app may be in a shared UID, and in case a 3447 // new privileged permission is requested by the updated system app but not the factory 3448 // app, although this app and permission combination isn't in the allowlist and can't 3449 // get the permission this way, other apps in the shared UID may still get it. A proper 3450 // fix for this would be to perform the reconciliation by UID, but for now let's keep 3451 // the old workaround working, which is to keep granted privileged permissions still 3452 // granted. 3453 return true; 3454 } 3455 // Only enforce the allowlist on boot 3456 if (!mSystemReady) { 3457 final ApexManager apexManager = ApexManager.getInstance(); 3458 final String containingApexPackageName = 3459 apexManager.getActiveApexPackageNameContainingPackage(packageName); 3460 final boolean isInUpdatedApex = containingApexPackageName != null 3461 && !apexManager.isFactory(apexManager.getPackageInfo(containingApexPackageName, 3462 MATCH_ACTIVE_PACKAGE)); 3463 // Apps that are in updated apexs' do not need to be allowlisted 3464 if (!isInUpdatedApex) { 3465 Slog.w(TAG, "Privileged permission " + permissionName + " for package " 3466 + packageName + " (" + pkg.getPath() 3467 + ") not in privapp-permissions allowlist"); 3468 if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) { 3469 synchronized (mLock) { 3470 if (mPrivappPermissionsViolations == null) { 3471 mPrivappPermissionsViolations = new ArraySet<>(); 3472 } 3473 mPrivappPermissionsViolations.add(packageName + " (" + pkg.getPath() + "): " 3474 + permissionName); 3475 } 3476 } 3477 } 3478 } 3479 return !RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE; 3480 } 3481 3482 private boolean isInSystemConfigPrivAppPermissions(@NonNull AndroidPackage pkg, 3483 @NonNull String permission) { 3484 final SystemConfig systemConfig = SystemConfig.getInstance(); 3485 final Set<String> permissions; 3486 if (pkg.isVendor()) { 3487 permissions = systemConfig.getVendorPrivAppPermissions(pkg.getPackageName()); 3488 } else if (pkg.isProduct()) { 3489 permissions = systemConfig.getProductPrivAppPermissions(pkg.getPackageName()); 3490 } else if (pkg.isSystemExt()) { 3491 permissions = systemConfig.getSystemExtPrivAppPermissions(pkg.getPackageName()); 3492 } else { 3493 permissions = systemConfig.getPrivAppPermissions(pkg.getPackageName()); 3494 } 3495 return CollectionUtils.contains(permissions, permission); 3496 } 3497 3498 private boolean isInSystemConfigPrivAppDenyPermissions(@NonNull AndroidPackage pkg, 3499 @NonNull String permission) { 3500 final SystemConfig systemConfig = SystemConfig.getInstance(); 3501 final Set<String> permissions; 3502 if (pkg.isVendor()) { 3503 permissions = systemConfig.getVendorPrivAppDenyPermissions(pkg.getPackageName()); 3504 } else if (pkg.isProduct()) { 3505 permissions = systemConfig.getProductPrivAppDenyPermissions(pkg.getPackageName()); 3506 } else if (pkg.isSystemExt()) { 3507 permissions = systemConfig.getSystemExtPrivAppDenyPermissions(pkg.getPackageName()); 3508 } else { 3509 permissions = systemConfig.getPrivAppDenyPermissions(pkg.getPackageName()); 3510 } 3511 return CollectionUtils.contains(permissions, permission); 3512 } 3513 3514 private boolean shouldGrantPermissionBySignature(@NonNull AndroidPackage pkg, 3515 @NonNull Permission bp) { 3516 // expect single system package 3517 String systemPackageName = ArrayUtils.firstOrNull(mPackageManagerInt.getKnownPackageNames( 3518 PackageManagerInternal.PACKAGE_SYSTEM, UserHandle.USER_SYSTEM)); 3519 final AndroidPackage systemPackage = 3520 mPackageManagerInt.getPackage(systemPackageName); 3521 // check if the package is allow to use this signature permission. A package is allowed to 3522 // use a signature permission if: 3523 // - it has the same set of signing certificates as the source package 3524 // - or its signing certificate was rotated from the source package's certificate 3525 // - or its signing certificate is a previous signing certificate of the defining 3526 // package, and the defining package still trusts the old certificate for permissions 3527 // - or it shares a common signing certificate in its lineage with the defining package, 3528 // and the defining package still trusts the old certificate for permissions 3529 // - or it shares the above relationships with the system package 3530 final PackageParser.SigningDetails sourceSigningDetails = 3531 getSourcePackageSigningDetails(bp); 3532 return sourceSigningDetails.hasCommonSignerWithCapability( 3533 pkg.getSigningDetails(), 3534 PackageParser.SigningDetails.CertCapabilities.PERMISSION) 3535 || pkg.getSigningDetails().hasAncestorOrSelf(systemPackage.getSigningDetails()) 3536 || systemPackage.getSigningDetails().checkCapability( 3537 pkg.getSigningDetails(), 3538 PackageParser.SigningDetails.CertCapabilities.PERMISSION); 3539 } 3540 3541 private boolean shouldGrantPermissionByProtectionFlags(@NonNull AndroidPackage pkg, 3542 @NonNull PackageSetting pkgSetting, @NonNull Permission bp, 3543 @NonNull ArraySet<String> shouldGrantPrivilegedPermissionIfWasGranted) { 3544 boolean allowed = false; 3545 final boolean isPrivilegedPermission = bp.isPrivileged(); 3546 final boolean isOemPermission = bp.isOem(); 3547 if (!allowed && (isPrivilegedPermission || isOemPermission) && pkg.isSystem()) { 3548 final String permissionName = bp.getName(); 3549 // For updated system applications, a privileged/oem permission 3550 // is granted only if it had been defined by the original application. 3551 if (pkgSetting.getPkgState().isUpdatedSystemApp()) { 3552 final PackageSetting disabledPs = mPackageManagerInt 3553 .getDisabledSystemPackage(pkg.getPackageName()); 3554 final AndroidPackage disabledPkg = disabledPs == null ? null : disabledPs.pkg; 3555 if (disabledPkg != null 3556 && ((isPrivilegedPermission && disabledPkg.isPrivileged()) 3557 || (isOemPermission && canGrantOemPermission(disabledPkg, 3558 permissionName)))) { 3559 if (disabledPkg.getRequestedPermissions().contains(permissionName)) { 3560 allowed = true; 3561 } else { 3562 // If the original was granted this permission, we take 3563 // that grant decision as read and propagate it to the 3564 // update. 3565 shouldGrantPrivilegedPermissionIfWasGranted.add(permissionName); 3566 } 3567 } 3568 } else { 3569 allowed = (isPrivilegedPermission && pkg.isPrivileged()) 3570 || (isOemPermission && canGrantOemPermission(pkg, permissionName)); 3571 } 3572 // In any case, don't grant a privileged permission to privileged vendor apps, if 3573 // the permission's protectionLevel does not have the extra 'vendorPrivileged' 3574 // flag. 3575 if (allowed && isPrivilegedPermission && !bp.isVendorPrivileged() && pkg.isVendor()) { 3576 Slog.w(TAG, "Permission " + permissionName 3577 + " cannot be granted to privileged vendor apk " + pkg.getPackageName() 3578 + " because it isn't a 'vendorPrivileged' permission."); 3579 allowed = false; 3580 } 3581 } 3582 if (!allowed && bp.isPre23() && pkg.getTargetSdkVersion() < Build.VERSION_CODES.M) { 3583 // If this was a previously normal/dangerous permission that got moved 3584 // to a system permission as part of the runtime permission redesign, then 3585 // we still want to blindly grant it to old apps. 3586 allowed = true; 3587 } 3588 // TODO (moltmann): The installer now shares the platforms signature. Hence it does not 3589 // need a separate flag anymore. Hence we need to check which 3590 // permissions are needed by the permission controller 3591 if (!allowed && bp.isInstaller() 3592 && (ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames( 3593 PackageManagerInternal.PACKAGE_INSTALLER, UserHandle.USER_SYSTEM), 3594 pkg.getPackageName()) || ArrayUtils.contains( 3595 mPackageManagerInt.getKnownPackageNames( 3596 PackageManagerInternal.PACKAGE_PERMISSION_CONTROLLER, 3597 UserHandle.USER_SYSTEM), pkg.getPackageName()))) { 3598 // If this permission is to be granted to the system installer and 3599 // this app is an installer, then it gets the permission. 3600 allowed = true; 3601 } 3602 if (!allowed && bp.isVerifier() 3603 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames( 3604 PackageManagerInternal.PACKAGE_VERIFIER, UserHandle.USER_SYSTEM), 3605 pkg.getPackageName())) { 3606 // If this permission is to be granted to the system verifier and 3607 // this app is a verifier, then it gets the permission. 3608 allowed = true; 3609 } 3610 if (!allowed && bp.isPreInstalled() 3611 && pkg.isSystem()) { 3612 // Any pre-installed system app is allowed to get this permission. 3613 allowed = true; 3614 } 3615 if (!allowed && bp.isKnownSigner()) { 3616 // If the permission is to be granted to a known signer then check if any of this 3617 // app's signing certificates are in the trusted certificate digest Set. 3618 allowed = pkg.getSigningDetails().hasAncestorOrSelfWithDigest(bp.getKnownCerts()); 3619 } 3620 // Deferred to be checked under permission data lock inside restorePermissionState(). 3621 //if (!allowed && bp.isDevelopment()) { 3622 // // For development permissions, a development permission 3623 // // is granted only if it was already granted. 3624 // allowed = origPermissions.isPermissionGranted(permissionName); 3625 //} 3626 if (!allowed && bp.isSetup() 3627 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames( 3628 PackageManagerInternal.PACKAGE_SETUP_WIZARD, UserHandle.USER_SYSTEM), 3629 pkg.getPackageName())) { 3630 // If this permission is to be granted to the system setup wizard and 3631 // this app is a setup wizard, then it gets the permission. 3632 allowed = true; 3633 } 3634 if (!allowed && bp.isSystemTextClassifier() 3635 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames( 3636 PackageManagerInternal.PACKAGE_SYSTEM_TEXT_CLASSIFIER, 3637 UserHandle.USER_SYSTEM), pkg.getPackageName())) { 3638 // Special permissions for the system default text classifier. 3639 allowed = true; 3640 } 3641 if (!allowed && bp.isConfigurator() 3642 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames( 3643 PackageManagerInternal.PACKAGE_CONFIGURATOR, 3644 UserHandle.USER_SYSTEM), pkg.getPackageName())) { 3645 // Special permissions for the device configurator. 3646 allowed = true; 3647 } 3648 if (!allowed && bp.isDocumenter() 3649 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames( 3650 PackageManagerInternal.PACKAGE_DOCUMENTER, UserHandle.USER_SYSTEM), 3651 pkg.getPackageName())) { 3652 // If this permission is to be granted to the documenter and 3653 // this app is the documenter, then it gets the permission. 3654 allowed = true; 3655 } 3656 if (!allowed && bp.isIncidentReportApprover() 3657 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames( 3658 PackageManagerInternal.PACKAGE_INCIDENT_REPORT_APPROVER, 3659 UserHandle.USER_SYSTEM), pkg.getPackageName())) { 3660 // If this permission is to be granted to the incident report approver and 3661 // this app is the incident report approver, then it gets the permission. 3662 allowed = true; 3663 } 3664 if (!allowed && bp.isAppPredictor() 3665 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames( 3666 PackageManagerInternal.PACKAGE_APP_PREDICTOR, UserHandle.USER_SYSTEM), 3667 pkg.getPackageName())) { 3668 // Special permissions for the system app predictor. 3669 allowed = true; 3670 } 3671 if (!allowed && bp.isCompanion() 3672 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames( 3673 PackageManagerInternal.PACKAGE_COMPANION, UserHandle.USER_SYSTEM), 3674 pkg.getPackageName())) { 3675 // Special permissions for the system companion device manager. 3676 allowed = true; 3677 } 3678 if (!allowed && bp.isRetailDemo() 3679 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames( 3680 PackageManagerInternal.PACKAGE_RETAIL_DEMO, UserHandle.USER_SYSTEM), 3681 pkg.getPackageName()) && isProfileOwner(pkg.getUid())) { 3682 // Special permission granted only to the OEM specified retail demo app 3683 allowed = true; 3684 } 3685 if (!allowed && bp.isRecents() 3686 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames( 3687 PackageManagerInternal.PACKAGE_RECENTS, UserHandle.USER_SYSTEM), 3688 pkg.getPackageName())) { 3689 // Special permission for the recents app. 3690 allowed = true; 3691 } 3692 return allowed; 3693 } 3694 3695 @NonNull 3696 private PackageParser.SigningDetails getSourcePackageSigningDetails( 3697 @NonNull Permission bp) { 3698 final PackageSetting ps = getSourcePackageSetting(bp); 3699 if (ps == null) { 3700 return PackageParser.SigningDetails.UNKNOWN; 3701 } 3702 return ps.getSigningDetails(); 3703 } 3704 3705 @Nullable 3706 private PackageSetting getSourcePackageSetting(@NonNull Permission bp) { 3707 final String sourcePackageName = bp.getPackageName(); 3708 return mPackageManagerInt.getPackageSetting(sourcePackageName); 3709 } 3710 3711 private static boolean canGrantOemPermission(AndroidPackage pkg, String permission) { 3712 if (!pkg.isOem()) { 3713 return false; 3714 } 3715 // all oem permissions must explicitly be granted or denied 3716 final Boolean granted = 3717 SystemConfig.getInstance().getOemPermissions(pkg.getPackageName()).get(permission); 3718 if (granted == null) { 3719 throw new IllegalStateException("OEM permission" + permission + " requested by package " 3720 + pkg.getPackageName() + " must be explicitly declared granted or not"); 3721 } 3722 return Boolean.TRUE == granted; 3723 } 3724 3725 private static boolean isProfileOwner(int uid) { 3726 DevicePolicyManagerInternal dpmInternal = 3727 LocalServices.getService(DevicePolicyManagerInternal.class); 3728 //TODO(b/169395065) Figure out if this flow makes sense in Device Owner mode. 3729 if (dpmInternal != null) { 3730 return dpmInternal.isActiveProfileOwner(uid) || dpmInternal.isActiveDeviceOwner(uid); 3731 } 3732 return false; 3733 } 3734 3735 private boolean isPermissionsReviewRequiredInternal(@NonNull String packageName, 3736 @UserIdInt int userId) { 3737 final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName); 3738 if (pkg == null) { 3739 return false; 3740 } 3741 3742 // Permission review applies only to apps not supporting the new permission model. 3743 if (pkg.getTargetSdkVersion() >= Build.VERSION_CODES.M) { 3744 return false; 3745 } 3746 3747 // Legacy apps have the permission and get user consent on launch. 3748 synchronized (mLock) { 3749 final UidPermissionState uidState = getUidStateLocked(pkg, userId); 3750 if (uidState == null) { 3751 Slog.e(TAG, "Missing permissions state for " + pkg.getPackageName() + " and user " 3752 + userId); 3753 return false; 3754 } 3755 return uidState.isPermissionsReviewRequired(); 3756 } 3757 } 3758 3759 private void grantRequestedRuntimePermissionsInternal(@NonNull AndroidPackage pkg, 3760 @Nullable List<String> permissions, int userId) { 3761 final int immutableFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED 3762 | PackageManager.FLAG_PERMISSION_POLICY_FIXED; 3763 3764 final int compatFlags = PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED 3765 | PackageManager.FLAG_PERMISSION_REVOKED_COMPAT; 3766 3767 final boolean supportsRuntimePermissions = pkg.getTargetSdkVersion() 3768 >= Build.VERSION_CODES.M; 3769 3770 final boolean instantApp = mPackageManagerInt.isInstantApp(pkg.getPackageName(), userId); 3771 3772 final int myUid = Process.myUid(); 3773 3774 for (String permission : pkg.getRequestedPermissions()) { 3775 final boolean shouldGrantPermission; 3776 synchronized (mLock) { 3777 final Permission bp = mRegistry.getPermission(permission); 3778 shouldGrantPermission = bp != null && (bp.isRuntime() || bp.isDevelopment()) 3779 && (!instantApp || bp.isInstant()) 3780 && (supportsRuntimePermissions || !bp.isRuntimeOnly()) 3781 && (permissions == null || permissions.contains(permission)); 3782 } 3783 if (shouldGrantPermission) { 3784 final int flags = getPermissionFlagsInternal(pkg.getPackageName(), permission, 3785 myUid, userId); 3786 if (supportsRuntimePermissions) { 3787 // Installer cannot change immutable permissions. 3788 if ((flags & immutableFlags) == 0) { 3789 grantRuntimePermissionInternal(pkg.getPackageName(), permission, false, 3790 myUid, userId, mDefaultPermissionCallback); 3791 } 3792 } else { 3793 // In permission review mode we clear the review flag and the revoked compat 3794 // flag when we are asked to install the app with all permissions granted. 3795 if ((flags & compatFlags) != 0) { 3796 updatePermissionFlagsInternal(pkg.getPackageName(), permission, compatFlags, 3797 0, myUid, userId, false, mDefaultPermissionCallback); 3798 } 3799 } 3800 } 3801 } 3802 } 3803 3804 private void setAllowlistedRestrictedPermissionsInternal(@NonNull AndroidPackage pkg, 3805 @Nullable List<String> permissions, @PermissionWhitelistFlags int allowlistFlags, 3806 @UserIdInt int userId) { 3807 ArraySet<String> oldGrantedRestrictedPermissions = null; 3808 boolean updatePermissions = false; 3809 final int permissionCount = pkg.getRequestedPermissions().size(); 3810 final int myUid = Process.myUid(); 3811 3812 for (int j = 0; j < permissionCount; j++) { 3813 final String permissionName = pkg.getRequestedPermissions().get(j); 3814 3815 final boolean isGranted; 3816 synchronized (mLock) { 3817 final Permission bp = mRegistry.getPermission(permissionName); 3818 if (bp == null || !bp.isHardOrSoftRestricted()) { 3819 continue; 3820 } 3821 3822 final UidPermissionState uidState = getUidStateLocked(pkg, userId); 3823 if (uidState == null) { 3824 Slog.e(TAG, "Missing permissions state for " + pkg.getPackageName() 3825 + " and user " + userId); 3826 continue; 3827 } 3828 isGranted = uidState.isPermissionGranted(permissionName); 3829 } 3830 3831 if (isGranted) { 3832 if (oldGrantedRestrictedPermissions == null) { 3833 oldGrantedRestrictedPermissions = new ArraySet<>(); 3834 } 3835 oldGrantedRestrictedPermissions.add(permissionName); 3836 } 3837 3838 final int oldFlags = getPermissionFlagsInternal(pkg.getPackageName(), permissionName, 3839 myUid, userId); 3840 3841 int newFlags = oldFlags; 3842 int mask = 0; 3843 int allowlistFlagsCopy = allowlistFlags; 3844 while (allowlistFlagsCopy != 0) { 3845 final int flag = 1 << Integer.numberOfTrailingZeros(allowlistFlagsCopy); 3846 allowlistFlagsCopy &= ~flag; 3847 switch (flag) { 3848 case FLAG_PERMISSION_WHITELIST_SYSTEM: { 3849 mask |= FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT; 3850 if (permissions != null && permissions.contains(permissionName)) { 3851 newFlags |= FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT; 3852 } else { 3853 newFlags &= ~FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT; 3854 } 3855 } 3856 break; 3857 case FLAG_PERMISSION_WHITELIST_UPGRADE: { 3858 mask |= FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT; 3859 if (permissions != null && permissions.contains(permissionName)) { 3860 newFlags |= FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT; 3861 } else { 3862 newFlags &= ~FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT; 3863 } 3864 } 3865 break; 3866 case FLAG_PERMISSION_WHITELIST_INSTALLER: { 3867 mask |= FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT; 3868 if (permissions != null && permissions.contains(permissionName)) { 3869 newFlags |= FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT; 3870 } else { 3871 newFlags &= ~FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT; 3872 } 3873 } 3874 break; 3875 } 3876 } 3877 3878 if (oldFlags == newFlags) { 3879 continue; 3880 } 3881 3882 updatePermissions = true; 3883 3884 final boolean wasAllowlisted = (oldFlags 3885 & (PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT)) != 0; 3886 final boolean isAllowlisted = (newFlags 3887 & (PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT)) != 0; 3888 3889 // If the permission is policy fixed as granted but it is no longer 3890 // on any of the allowlists we need to clear the policy fixed flag 3891 // as allowlisting trumps policy i.e. policy cannot grant a non 3892 // grantable permission. 3893 if ((oldFlags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) { 3894 if (!isAllowlisted && isGranted) { 3895 mask |= PackageManager.FLAG_PERMISSION_POLICY_FIXED; 3896 newFlags &= ~PackageManager.FLAG_PERMISSION_POLICY_FIXED; 3897 } 3898 } 3899 3900 // If we are allowlisting an app that does not support runtime permissions 3901 // we need to make sure it goes through the permission review UI at launch. 3902 if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.M 3903 && !wasAllowlisted && isAllowlisted) { 3904 mask |= PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED; 3905 newFlags |= PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED; 3906 } 3907 3908 updatePermissionFlagsInternal(pkg.getPackageName(), permissionName, mask, newFlags, 3909 myUid, userId, false, null /*callback*/); 3910 } 3911 3912 if (updatePermissions) { 3913 // Update permission of this app to take into account the new allowlist state. 3914 restorePermissionState(pkg, false, pkg.getPackageName(), mDefaultPermissionCallback, 3915 userId); 3916 3917 // If this resulted in losing a permission we need to kill the app. 3918 if (oldGrantedRestrictedPermissions == null) { 3919 return; 3920 } 3921 3922 final int oldGrantedCount = oldGrantedRestrictedPermissions.size(); 3923 for (int j = 0; j < oldGrantedCount; j++) { 3924 final String permissionName = oldGrantedRestrictedPermissions.valueAt(j); 3925 // Sometimes we create a new permission state instance during update. 3926 final boolean isGranted; 3927 synchronized (mLock) { 3928 final UidPermissionState uidState = getUidStateLocked(pkg, userId); 3929 if (uidState == null) { 3930 Slog.e(TAG, "Missing permissions state for " + pkg.getPackageName() 3931 + " and user " + userId); 3932 continue; 3933 } 3934 isGranted = uidState.isPermissionGranted(permissionName); 3935 } 3936 if (!isGranted) { 3937 mDefaultPermissionCallback.onPermissionRevoked(pkg.getUid(), userId, null); 3938 break; 3939 } 3940 } 3941 } 3942 } 3943 3944 @UserIdInt 3945 private int revokeSharedUserPermissionsForDeletedPackageInternal( 3946 @Nullable AndroidPackage pkg, @NonNull List<AndroidPackage> sharedUserPkgs, 3947 @UserIdInt int userId) { 3948 if (pkg == null) { 3949 Slog.i(TAG, "Trying to update info for null package. Just ignoring"); 3950 return UserHandle.USER_NULL; 3951 } 3952 3953 // No shared user packages 3954 if (sharedUserPkgs.isEmpty()) { 3955 return UserHandle.USER_NULL; 3956 } 3957 3958 int affectedUserId = UserHandle.USER_NULL; 3959 // Update permissions 3960 for (String eachPerm : pkg.getRequestedPermissions()) { 3961 // Check if another package in the shared user needs the permission. 3962 boolean used = false; 3963 for (AndroidPackage sharedUserpkg : sharedUserPkgs) { 3964 if (sharedUserpkg != null 3965 && !sharedUserpkg.getPackageName().equals(pkg.getPackageName()) 3966 && sharedUserpkg.getRequestedPermissions().contains(eachPerm)) { 3967 used = true; 3968 break; 3969 } 3970 } 3971 if (used) { 3972 continue; 3973 } 3974 3975 PackageSetting disabledPs = mPackageManagerInt.getDisabledSystemPackage( 3976 pkg.getPackageName()); 3977 3978 // If the package is shadowing is a disabled system package, 3979 // do not drop permissions that the shadowed package requests. 3980 if (disabledPs != null) { 3981 boolean reqByDisabledSysPkg = false; 3982 for (String permission : disabledPs.pkg.getRequestedPermissions()) { 3983 if (permission.equals(eachPerm)) { 3984 reqByDisabledSysPkg = true; 3985 break; 3986 } 3987 } 3988 if (reqByDisabledSysPkg) { 3989 continue; 3990 } 3991 } 3992 3993 synchronized (mLock) { 3994 UidPermissionState uidState = getUidStateLocked(pkg, userId); 3995 if (uidState == null) { 3996 Slog.e(TAG, "Missing permissions state for " + pkg.getPackageName() 3997 + " and user " + userId); 3998 continue; 3999 } 4000 4001 Permission bp = mRegistry.getPermission(eachPerm); 4002 if (bp == null) { 4003 continue; 4004 } 4005 4006 // TODO(zhanghai): Why are we only killing the UID when GIDs changed, instead of any 4007 // permission change? 4008 if (uidState.removePermissionState(bp.getName()) && bp.hasGids()) { 4009 affectedUserId = userId; 4010 } 4011 } 4012 } 4013 4014 return affectedUserId; 4015 } 4016 4017 @GuardedBy("mLock") 4018 private boolean revokeUnusedSharedUserPermissionsLocked( 4019 List<AndroidPackage> pkgList, UidPermissionState uidState) { 4020 // Collect all used permissions in the UID 4021 final ArraySet<String> usedPermissions = new ArraySet<>(); 4022 if (pkgList == null || pkgList.size() == 0) { 4023 return false; 4024 } 4025 for (AndroidPackage pkg : pkgList) { 4026 if (pkg.getRequestedPermissions().isEmpty()) { 4027 continue; 4028 } 4029 final int requestedPermCount = pkg.getRequestedPermissions().size(); 4030 for (int j = 0; j < requestedPermCount; j++) { 4031 String permission = pkg.getRequestedPermissions().get(j); 4032 Permission bp = mRegistry.getPermission(permission); 4033 if (bp != null) { 4034 usedPermissions.add(permission); 4035 } 4036 } 4037 } 4038 4039 boolean runtimePermissionChanged = false; 4040 4041 // Prune permissions 4042 final List<PermissionState> permissionStates = uidState.getPermissionStates(); 4043 final int permissionStatesSize = permissionStates.size(); 4044 for (int i = permissionStatesSize - 1; i >= 0; i--) { 4045 PermissionState permissionState = permissionStates.get(i); 4046 if (!usedPermissions.contains(permissionState.getName())) { 4047 Permission bp = mRegistry.getPermission(permissionState.getName()); 4048 if (bp != null) { 4049 if (uidState.removePermissionState(bp.getName()) && bp.isRuntime()) { 4050 runtimePermissionChanged = true; 4051 } 4052 } 4053 } 4054 } 4055 4056 return runtimePermissionChanged; 4057 } 4058 4059 /** 4060 * Update permissions when a package changed. 4061 * 4062 * <p><ol> 4063 * <li>Reconsider the ownership of permission</li> 4064 * <li>Update the state (grant, flags) of the permissions</li> 4065 * </ol> 4066 * 4067 * @param packageName The package that is updated 4068 * @param pkg The package that is updated, or {@code null} if package is deleted 4069 */ 4070 private void updatePermissions(@NonNull String packageName, @Nullable AndroidPackage pkg) { 4071 // If the package is being deleted, update the permissions of all the apps 4072 final int flags = 4073 (pkg == null ? UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG 4074 : UPDATE_PERMISSIONS_REPLACE_PKG); 4075 updatePermissions( 4076 packageName, pkg, getVolumeUuidForPackage(pkg), flags, mDefaultPermissionCallback); 4077 } 4078 4079 /** 4080 * Update all permissions for all apps. 4081 * 4082 * <p><ol> 4083 * <li>Reconsider the ownership of permission</li> 4084 * <li>Update the state (grant, flags) of the permissions</li> 4085 * </ol> 4086 * 4087 * @param volumeUuid The volume UUID of the packages to be updated 4088 * @param fingerprintChanged whether the current build fingerprint is different from what it was 4089 * when this volume was last mounted 4090 */ 4091 private void updateAllPermissions(@NonNull String volumeUuid, boolean fingerprintChanged) { 4092 PackageManager.corkPackageInfoCache(); // Prevent invalidation storm 4093 try { 4094 final int flags = UPDATE_PERMISSIONS_ALL | 4095 (fingerprintChanged 4096 ? UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL 4097 : 0); 4098 updatePermissions(null, null, volumeUuid, flags, mDefaultPermissionCallback); 4099 } finally { 4100 PackageManager.uncorkPackageInfoCache(); 4101 } 4102 } 4103 4104 /** 4105 * Update all packages on the volume, <u>beside</u> the changing package. If the changing 4106 * package is set too, all packages are updated. 4107 */ 4108 private static final int UPDATE_PERMISSIONS_ALL = 1 << 0; 4109 /** The changing package is replaced. Requires the changing package to be set */ 4110 private static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1 << 1; 4111 /** 4112 * Schedule all packages <u>beside</u> the changing package for replacement. Requires 4113 * UPDATE_PERMISSIONS_ALL to be set 4114 */ 4115 private static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1 << 2; 4116 4117 @IntDef(flag = true, prefix = { "UPDATE_PERMISSIONS_" }, value = { 4118 UPDATE_PERMISSIONS_ALL, UPDATE_PERMISSIONS_REPLACE_PKG, 4119 UPDATE_PERMISSIONS_REPLACE_ALL }) 4120 @Retention(RetentionPolicy.SOURCE) 4121 private @interface UpdatePermissionFlags {} 4122 4123 /** 4124 * Update permissions when packages changed. 4125 * 4126 * <p><ol> 4127 * <li>Reconsider the ownership of permission</li> 4128 * <li>Update the state (grant, flags) of the permissions</li> 4129 * </ol> 4130 * 4131 * <p>Meaning of combination of package parameters: 4132 * <table> 4133 * <tr><th></th><th>changingPkgName != null</th><th>changingPkgName == null</th></tr> 4134 * <tr><th>changingPkg != null</th><td>package is updated</td><td>invalid</td></tr> 4135 * <tr><th>changingPkg == null</th><td>package is deleted</td><td>all packages are 4136 * updated</td></tr> 4137 * </table> 4138 * 4139 * @param changingPkgName The package that is updated, or {@code null} if all packages should be 4140 * updated 4141 * @param changingPkg The package that is updated, or {@code null} if all packages should be 4142 * updated or package is deleted 4143 * @param replaceVolumeUuid The volume of the packages to be updated are on, {@code null} for 4144 * all volumes 4145 * @param flags Control permission for which apps should be updated 4146 * @param callback Callback to call after permission changes 4147 */ 4148 private void updatePermissions(final @Nullable String changingPkgName, 4149 final @Nullable AndroidPackage changingPkg, 4150 final @Nullable String replaceVolumeUuid, 4151 @UpdatePermissionFlags int flags, 4152 final @Nullable PermissionCallback callback) { 4153 // TODO: Most of the methods exposing BasePermission internals [source package name, 4154 // etc..] shouldn't be needed. Instead, when we've parsed a permission that doesn't 4155 // have package settings, we should make note of it elsewhere [map between 4156 // source package name and BasePermission] and cycle through that here. Then we 4157 // define a single method on BasePermission that takes a PackageSetting, changing 4158 // package name and a package. 4159 // NOTE: With this approach, we also don't need to tree trees differently than 4160 // normal permissions. Today, we need two separate loops because these BasePermission 4161 // objects are stored separately. 4162 // Make sure there are no dangling permission trees. 4163 boolean permissionTreesSourcePackageChanged = updatePermissionTreeSourcePackage( 4164 changingPkgName, changingPkg); 4165 // Make sure all dynamic permissions have been assigned to a package, 4166 // and make sure there are no dangling permissions. 4167 boolean permissionSourcePackageChanged = updatePermissionSourcePackage(changingPkgName, 4168 changingPkg, callback); 4169 4170 if (permissionTreesSourcePackageChanged | permissionSourcePackageChanged) { 4171 // Permission ownership has changed. This e.g. changes which packages can get signature 4172 // permissions 4173 Slog.i(TAG, "Permission ownership changed. Updating all permissions."); 4174 flags |= UPDATE_PERMISSIONS_ALL; 4175 } 4176 4177 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "restorePermissionState"); 4178 // Now update the permissions for all packages. 4179 if ((flags & UPDATE_PERMISSIONS_ALL) != 0) { 4180 final boolean replaceAll = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0); 4181 mPackageManagerInt.forEachPackage((AndroidPackage pkg) -> { 4182 if (pkg == changingPkg) { 4183 return; 4184 } 4185 // Only replace for packages on requested volume 4186 final String volumeUuid = getVolumeUuidForPackage(pkg); 4187 final boolean replace = replaceAll && Objects.equals(replaceVolumeUuid, volumeUuid); 4188 restorePermissionState(pkg, replace, changingPkgName, callback, 4189 UserHandle.USER_ALL); 4190 }); 4191 } 4192 4193 if (changingPkg != null) { 4194 // Only replace for packages on requested volume 4195 final String volumeUuid = getVolumeUuidForPackage(changingPkg); 4196 final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_PKG) != 0) 4197 && Objects.equals(replaceVolumeUuid, volumeUuid); 4198 restorePermissionState(changingPkg, replace, changingPkgName, callback, 4199 UserHandle.USER_ALL); 4200 } 4201 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 4202 } 4203 4204 /** 4205 * Update which app declares a permission. 4206 * 4207 * <p>Possible parameter combinations 4208 * <table> 4209 * <tr><th></th><th>packageName != null</th><th>packageName == null</th></tr> 4210 * <tr><th>pkg != null</th><td>package is updated</td><td>invalid</td></tr> 4211 * <tr><th>pkg == null</th><td>package is deleted</td><td>all packages are updated</td></tr> 4212 * </table> 4213 * 4214 * @param packageName The package that is updated, or {@code null} if all packages should be 4215 * updated 4216 * @param pkg The package that is updated, or {@code null} if all packages should be updated or 4217 * package is deleted 4218 * 4219 * @return {@code true} if a permission source package might have changed 4220 */ 4221 private boolean updatePermissionSourcePackage(@Nullable String packageName, 4222 @Nullable AndroidPackage pkg, 4223 final @Nullable PermissionCallback callback) { 4224 // Always need update if packageName is null 4225 if (packageName == null) { 4226 return true; 4227 } 4228 4229 boolean changed = false; 4230 Set<Permission> needsUpdate = null; 4231 synchronized (mLock) { 4232 for (final Permission bp : mRegistry.getPermissions()) { 4233 if (bp.isDynamic()) { 4234 bp.updateDynamicPermission(mRegistry.getPermissionTrees()); 4235 } 4236 if (!packageName.equals(bp.getPackageName())) { 4237 // Not checking sourcePackageSetting because it can be null when 4238 // the permission source package is the target package and the target package is 4239 // being uninstalled, 4240 continue; 4241 } 4242 // The target package is the source of the current permission 4243 // Set to changed for either install or uninstall 4244 changed = true; 4245 if (needsUpdate == null) { 4246 needsUpdate = new ArraySet<>(); 4247 } 4248 needsUpdate.add(bp); 4249 } 4250 } 4251 if (needsUpdate != null) { 4252 for (final Permission bp : needsUpdate) { 4253 // If the target package is being uninstalled, we need to revoke this permission 4254 // From all other packages 4255 if (pkg == null || !hasPermission(pkg, bp.getName())) { 4256 Slog.i(TAG, "Removing permission " + bp.getName() 4257 + " that used to be declared by " + bp.getPackageName()); 4258 if (bp.isRuntime()) { 4259 final int[] userIds = mUserManagerInt.getUserIds(); 4260 final int numUserIds = userIds.length; 4261 for (int userIdNum = 0; userIdNum < numUserIds; userIdNum++) { 4262 final int userId = userIds[userIdNum]; 4263 mPackageManagerInt.forEachPackage((AndroidPackage p) -> 4264 revokePermissionFromPackageForUser(p.getPackageName(), 4265 bp.getName(), true, userId, callback)); 4266 } 4267 } else { 4268 mPackageManagerInt.forEachPackage(p -> { 4269 final int[] userIds = mUserManagerInt.getUserIds(); 4270 synchronized (mLock) { 4271 for (final int userId : userIds) { 4272 final UidPermissionState uidState = getUidStateLocked(p, 4273 userId); 4274 if (uidState == null) { 4275 Slog.e(TAG, "Missing permissions state for " 4276 + p.getPackageName() + " and user " + userId); 4277 continue; 4278 } 4279 uidState.removePermissionState(bp.getName()); 4280 } 4281 } 4282 }); 4283 } 4284 synchronized (mLock) { 4285 mRegistry.removePermission(bp.getName()); 4286 } 4287 continue; 4288 } 4289 final AndroidPackage sourcePkg = 4290 mPackageManagerInt.getPackage(bp.getPackageName()); 4291 final PackageSetting sourcePs = 4292 (PackageSetting) mPackageManagerInt.getPackageSetting( 4293 bp.getPackageName()); 4294 synchronized (mLock) { 4295 if (sourcePkg != null && sourcePs != null) { 4296 continue; 4297 } 4298 Slog.w(TAG, "Removing dangling permission: " + bp.getName() 4299 + " from package " + bp.getPackageName()); 4300 mRegistry.removePermission(bp.getName()); 4301 } 4302 } 4303 } 4304 return changed; 4305 } 4306 4307 /** 4308 * Revoke a runtime permission from a package for a given user ID. 4309 */ 4310 private void revokePermissionFromPackageForUser(@NonNull String pName, 4311 @NonNull String permissionName, boolean overridePolicy, int userId, 4312 @Nullable PermissionCallback callback) { 4313 final ApplicationInfo appInfo = 4314 mPackageManagerInt.getApplicationInfo(pName, 0, 4315 Process.SYSTEM_UID, UserHandle.USER_SYSTEM); 4316 if (appInfo != null 4317 && appInfo.targetSdkVersion < Build.VERSION_CODES.M) { 4318 return; 4319 } 4320 4321 if (checkPermissionImpl(pName, permissionName, userId) 4322 == PackageManager.PERMISSION_GRANTED) { 4323 try { 4324 revokeRuntimePermissionInternal( 4325 pName, permissionName, 4326 overridePolicy, 4327 Process.SYSTEM_UID, 4328 userId, 4329 null, callback); 4330 } catch (IllegalArgumentException e) { 4331 Slog.e(TAG, 4332 "Failed to revoke " 4333 + permissionName 4334 + " from " 4335 + pName, 4336 e); 4337 } 4338 } 4339 } 4340 /** 4341 * Update which app owns a permission trees. 4342 * 4343 * <p>Possible parameter combinations 4344 * <table> 4345 * <tr><th></th><th>packageName != null</th><th>packageName == null</th></tr> 4346 * <tr><th>pkg != null</th><td>package is updated</td><td>invalid</td></tr> 4347 * <tr><th>pkg == null</th><td>package is deleted</td><td>all packages are updated</td></tr> 4348 * </table> 4349 * 4350 * @param packageName The package that is updated, or {@code null} if all packages should be 4351 * updated 4352 * @param pkg The package that is updated, or {@code null} if all packages should be updated or 4353 * package is deleted 4354 * 4355 * @return {@code true} if a permission tree ownership might have changed 4356 */ 4357 private boolean updatePermissionTreeSourcePackage(@Nullable String packageName, 4358 @Nullable AndroidPackage pkg) { 4359 // Always need update if packageName is null 4360 if (packageName == null) { 4361 return true; 4362 } 4363 boolean changed = false; 4364 4365 Set<Permission> needsUpdate = null; 4366 synchronized (mLock) { 4367 final Iterator<Permission> it = mRegistry.getPermissionTrees().iterator(); 4368 while (it.hasNext()) { 4369 final Permission bp = it.next(); 4370 if (!packageName.equals(bp.getPackageName())) { 4371 // Not checking sourcePackageSetting because it can be null when 4372 // the permission source package is the target package and the target package is 4373 // being uninstalled, 4374 continue; 4375 } 4376 // The target package is the source of the current permission tree 4377 // Set to changed for either install or uninstall 4378 changed = true; 4379 if (pkg == null || !hasPermission(pkg, bp.getName())) { 4380 Slog.i(TAG, "Removing permission tree " + bp.getName() 4381 + " that used to be declared by " + bp.getPackageName()); 4382 it.remove(); 4383 } 4384 if (needsUpdate == null) { 4385 needsUpdate = new ArraySet<>(); 4386 } 4387 needsUpdate.add(bp); 4388 } 4389 } 4390 if (needsUpdate != null) { 4391 for (final Permission bp : needsUpdate) { 4392 final AndroidPackage sourcePkg = 4393 mPackageManagerInt.getPackage(bp.getPackageName()); 4394 final PackageSetting sourcePs = 4395 (PackageSetting) mPackageManagerInt.getPackageSetting( 4396 bp.getPackageName()); 4397 synchronized (mLock) { 4398 if (sourcePkg != null && sourcePs != null) { 4399 continue; 4400 } 4401 Slog.w(TAG, "Removing dangling permission tree: " + bp.getName() 4402 + " from package " + bp.getPackageName()); 4403 mRegistry.removePermission(bp.getName()); 4404 } 4405 } 4406 } 4407 return changed; 4408 } 4409 4410 private void enforceGrantRevokeRuntimePermissionPermissions(String message) { 4411 if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS) 4412 != PackageManager.PERMISSION_GRANTED 4413 && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS) 4414 != PackageManager.PERMISSION_GRANTED) { 4415 throw new SecurityException(message + " requires " 4416 + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or " 4417 + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS); 4418 } 4419 } 4420 4421 private void enforceGrantRevokeGetRuntimePermissionPermissions(@NonNull String message) { 4422 if (mContext.checkCallingOrSelfPermission(Manifest.permission.GET_RUNTIME_PERMISSIONS) 4423 != PackageManager.PERMISSION_GRANTED 4424 && mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS) 4425 != PackageManager.PERMISSION_GRANTED 4426 && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS) 4427 != PackageManager.PERMISSION_GRANTED) { 4428 throw new SecurityException(message + " requires " 4429 + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or " 4430 + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS + " or " 4431 + Manifest.permission.GET_RUNTIME_PERMISSIONS); 4432 } 4433 } 4434 4435 /** 4436 * Enforces the request is from the system or an app that has INTERACT_ACROSS_USERS 4437 * or INTERACT_ACROSS_USERS_FULL permissions, if the {@code userId} is not for the caller. 4438 * 4439 * @param checkShell whether to prevent shell from access if there's a debugging restriction 4440 * @param message the message to log on security exception 4441 */ 4442 private void enforceCrossUserPermission(int callingUid, @UserIdInt int userId, 4443 boolean requireFullPermission, boolean checkShell, @Nullable String message) { 4444 if (userId < 0) { 4445 throw new IllegalArgumentException("Invalid userId " + userId); 4446 } 4447 if (checkShell) { 4448 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId); 4449 } 4450 final int callingUserId = UserHandle.getUserId(callingUid); 4451 if (checkCrossUserPermission(callingUid, callingUserId, userId, requireFullPermission)) { 4452 return; 4453 } 4454 String errorMessage = buildInvalidCrossUserPermissionMessage( 4455 callingUid, userId, message, requireFullPermission); 4456 Slog.w(TAG, errorMessage); 4457 throw new SecurityException(errorMessage); 4458 } 4459 4460 /** 4461 * Enforces that if the caller is shell, it does not have the provided user restriction. 4462 */ 4463 private void enforceShellRestriction(@NonNull String restriction, int callingUid, 4464 @UserIdInt int userId) { 4465 if (callingUid == Process.SHELL_UID) { 4466 if (userId >= 0 && mUserManagerInt.hasUserRestriction(restriction, userId)) { 4467 throw new SecurityException("Shell does not have permission to access user " 4468 + userId); 4469 } else if (userId < 0) { 4470 Slog.e(LOG_TAG, "Unable to check shell permission for user " 4471 + userId + "\n\t" + Debug.getCallers(3)); 4472 } 4473 } 4474 } 4475 4476 private boolean checkCrossUserPermission(int callingUid, @UserIdInt int callingUserId, 4477 @UserIdInt int userId, boolean requireFullPermission) { 4478 if (userId == callingUserId) { 4479 return true; 4480 } 4481 if (callingUid == Process.SYSTEM_UID || callingUid == Process.ROOT_UID) { 4482 return true; 4483 } 4484 if (requireFullPermission) { 4485 return checkCallingOrSelfPermission( 4486 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 4487 } 4488 return checkCallingOrSelfPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 4489 || checkCallingOrSelfPermission(android.Manifest.permission.INTERACT_ACROSS_USERS); 4490 } 4491 4492 private boolean checkCallingOrSelfPermission(String permission) { 4493 return mContext.checkCallingOrSelfPermission(permission) 4494 == PackageManager.PERMISSION_GRANTED; 4495 } 4496 4497 @NonNull 4498 private static String buildInvalidCrossUserPermissionMessage(int callingUid, 4499 @UserIdInt int userId, @Nullable String message, boolean requireFullPermission) { 4500 StringBuilder builder = new StringBuilder(); 4501 if (message != null) { 4502 builder.append(message); 4503 builder.append(": "); 4504 } 4505 builder.append("UID "); 4506 builder.append(callingUid); 4507 builder.append(" requires "); 4508 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 4509 if (!requireFullPermission) { 4510 builder.append(" or "); 4511 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 4512 } 4513 builder.append(" to access user "); 4514 builder.append(userId); 4515 builder.append("."); 4516 return builder.toString(); 4517 } 4518 4519 @GuardedBy("mLock") 4520 private int calculateCurrentPermissionFootprintLocked(@NonNull Permission permissionTree) { 4521 int size = 0; 4522 for (final Permission permission : mRegistry.getPermissions()) { 4523 size += permissionTree.calculateFootprint(permission); 4524 } 4525 return size; 4526 } 4527 4528 @GuardedBy("mLock") 4529 private void enforcePermissionCapLocked(PermissionInfo info, Permission tree) { 4530 // We calculate the max size of permissions defined by this uid and throw 4531 // if that plus the size of 'info' would exceed our stated maximum. 4532 if (tree.getUid() != Process.SYSTEM_UID) { 4533 final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree); 4534 if (curTreeSize + info.calculateFootprint() > MAX_PERMISSION_TREE_FOOTPRINT) { 4535 throw new SecurityException("Permission tree size cap exceeded"); 4536 } 4537 } 4538 } 4539 4540 private void systemReady() { 4541 // Now that we've scanned all packages, and granted any default 4542 // permissions, ensure permissions are updated. Beware of dragons if you 4543 // try optimizing this. 4544 updateAllPermissions(StorageManager.UUID_PRIVATE_INTERNAL, false); 4545 4546 final PermissionPolicyInternal permissionPolicyInternal = LocalServices.getService( 4547 PermissionPolicyInternal.class); 4548 permissionPolicyInternal.setOnInitializedCallback(userId -> 4549 // The SDK updated case is already handled when we run during the ctor. 4550 updateAllPermissions(StorageManager.UUID_PRIVATE_INTERNAL, false) 4551 ); 4552 4553 mSystemReady = true; 4554 4555 synchronized (mLock) { 4556 if (mPrivappPermissionsViolations != null) { 4557 throw new IllegalStateException("Signature|privileged permissions not in " 4558 + "privapp-permissions allowlist: " + mPrivappPermissionsViolations); 4559 } 4560 } 4561 4562 mPermissionControllerManager = mContext.getSystemService(PermissionControllerManager.class); 4563 mPermissionPolicyInternal = LocalServices.getService(PermissionPolicyInternal.class); 4564 } 4565 4566 private static String getVolumeUuidForPackage(AndroidPackage pkg) { 4567 if (pkg == null) { 4568 return StorageManager.UUID_PRIVATE_INTERNAL; 4569 } 4570 if (pkg.isExternalStorage()) { 4571 if (TextUtils.isEmpty(pkg.getVolumeUuid())) { 4572 return StorageManager.UUID_PRIMARY_PHYSICAL; 4573 } else { 4574 return pkg.getVolumeUuid(); 4575 } 4576 } else { 4577 return StorageManager.UUID_PRIVATE_INTERNAL; 4578 } 4579 } 4580 4581 private static boolean hasPermission(AndroidPackage pkg, String permName) { 4582 if (pkg.getPermissions().isEmpty()) { 4583 return false; 4584 } 4585 4586 for (int i = pkg.getPermissions().size() - 1; i >= 0; i--) { 4587 if (pkg.getPermissions().get(i).getName().equals(permName)) { 4588 return true; 4589 } 4590 } 4591 return false; 4592 } 4593 4594 /** 4595 * Log that a permission request was granted/revoked. 4596 * 4597 * @param action the action performed 4598 * @param name name of the permission 4599 * @param packageName package permission is for 4600 */ 4601 private void logPermission(int action, @NonNull String name, @NonNull String packageName) { 4602 final LogMaker log = new LogMaker(action); 4603 log.setPackageName(packageName); 4604 log.addTaggedData(MetricsEvent.FIELD_PERMISSION, name); 4605 4606 mMetricsLogger.write(log); 4607 } 4608 4609 @GuardedBy("mLock") 4610 @Nullable 4611 private UidPermissionState getUidStateLocked(@NonNull PackageSetting ps, 4612 @UserIdInt int userId) { 4613 return getUidStateLocked(ps.getAppId(), userId); 4614 } 4615 4616 @GuardedBy("mLock") 4617 @Nullable 4618 private UidPermissionState getUidStateLocked(@NonNull AndroidPackage pkg, 4619 @UserIdInt int userId) { 4620 return getUidStateLocked(pkg.getUid(), userId); 4621 } 4622 4623 @GuardedBy("mLock") 4624 @Nullable 4625 private UidPermissionState getUidStateLocked(@AppIdInt int appId, @UserIdInt int userId) { 4626 final UserPermissionState userState = mState.getUserState(userId); 4627 if (userState == null) { 4628 return null; 4629 } 4630 return userState.getUidState(appId); 4631 } 4632 4633 private void removeUidStateAndResetPackageInstallPermissionsFixed(@AppIdInt int appId, 4634 @NonNull String packageName, @UserIdInt int userId) { 4635 synchronized (mLock) { 4636 final UserPermissionState userState = mState.getUserState(userId); 4637 if (userState == null) { 4638 return; 4639 } 4640 userState.removeUidState(appId); 4641 userState.setInstallPermissionsFixed(packageName, false); 4642 } 4643 } 4644 4645 private void readLegacyPermissionState() { 4646 final int[] userIds = getAllUserIds(); 4647 mPackageManagerInt.forEachPackageSetting(ps -> { 4648 final int appId = ps.getAppId(); 4649 final LegacyPermissionState legacyState = ps.getLegacyPermissionState(); 4650 4651 synchronized (mLock) { 4652 for (final int userId : userIds) { 4653 final UserPermissionState userState = mState.getOrCreateUserState(userId); 4654 4655 userState.setInstallPermissionsFixed(ps.name, ps.areInstallPermissionsFixed()); 4656 final UidPermissionState uidState = userState.getOrCreateUidState(appId); 4657 uidState.reset(); 4658 uidState.setMissing(legacyState.isMissing(userId)); 4659 readLegacyPermissionStatesLocked(uidState, 4660 legacyState.getPermissionStates(userId)); 4661 } 4662 } 4663 }); 4664 } 4665 4666 @GuardedBy("mLock") 4667 private void readLegacyPermissionStatesLocked(@NonNull UidPermissionState uidState, 4668 @NonNull Collection<LegacyPermissionState.PermissionState> permissionStates) { 4669 for (final LegacyPermissionState.PermissionState permissionState : permissionStates) { 4670 final String permissionName = permissionState.getName(); 4671 final Permission permission = mRegistry.getPermission(permissionName); 4672 if (permission == null) { 4673 Slog.w(TAG, "Unknown permission: " + permissionName); 4674 continue; 4675 } 4676 uidState.putPermissionState(permission, permissionState.isGranted(), 4677 permissionState.getFlags()); 4678 } 4679 } 4680 4681 private void writeLegacyPermissionState() { 4682 final int[] userIds; 4683 synchronized (mLock) { 4684 userIds = mState.getUserIds(); 4685 } 4686 mPackageManagerInt.forEachPackageSetting(ps -> { 4687 ps.setInstallPermissionsFixed(false); 4688 final LegacyPermissionState legacyState = ps.getLegacyPermissionState(); 4689 legacyState.reset(); 4690 final int appId = ps.getAppId(); 4691 4692 synchronized (mLock) { 4693 for (final int userId : userIds) { 4694 final UserPermissionState userState = mState.getUserState(userId); 4695 if (userState == null) { 4696 Slog.e(TAG, "Missing user state for " + userId); 4697 continue; 4698 } 4699 4700 if (userState.areInstallPermissionsFixed(ps.name)) { 4701 ps.setInstallPermissionsFixed(true); 4702 } 4703 4704 final UidPermissionState uidState = userState.getUidState(appId); 4705 if (uidState == null) { 4706 Slog.e(TAG, "Missing permission state for " + ps.name + " and user " 4707 + userId); 4708 continue; 4709 } 4710 4711 legacyState.setMissing(uidState.isMissing(), userId); 4712 final List<PermissionState> permissionStates = uidState.getPermissionStates(); 4713 final int permissionStatesSize = permissionStates.size(); 4714 for (int i = 0; i < permissionStatesSize; i++) { 4715 final PermissionState permissionState = permissionStates.get(i); 4716 4717 final LegacyPermissionState.PermissionState legacyPermissionState = 4718 new LegacyPermissionState.PermissionState(permissionState.getName(), 4719 permissionState.getPermission().isRuntime(), 4720 permissionState.isGranted(), permissionState.getFlags()); 4721 legacyState.putPermissionState(legacyPermissionState, userId); 4722 } 4723 } 4724 } 4725 }); 4726 } 4727 4728 private void readLegacyPermissions(@NonNull LegacyPermissionSettings legacyPermissionSettings) { 4729 for (int readPermissionOrPermissionTree = 0; readPermissionOrPermissionTree < 2; 4730 readPermissionOrPermissionTree++) { 4731 final List<LegacyPermission> legacyPermissions = readPermissionOrPermissionTree == 0 4732 ? legacyPermissionSettings.getPermissions() 4733 : legacyPermissionSettings.getPermissionTrees(); 4734 synchronized (mLock) { 4735 final int legacyPermissionsSize = legacyPermissions.size(); 4736 for (int i = 0; i < legacyPermissionsSize; i++) { 4737 final LegacyPermission legacyPermission = legacyPermissions.get(i); 4738 final Permission permission = new Permission( 4739 legacyPermission.getPermissionInfo(), legacyPermission.getType()); 4740 if (readPermissionOrPermissionTree == 0) { 4741 // Config permissions are currently read in PermissionManagerService 4742 // constructor. The old behavior was to add other attributes to the config 4743 // permission in LegacyPermission.read(), so equivalently we can add the 4744 // GIDs to the new permissions here, since config permissions created in 4745 // PermissionManagerService constructor get only their names and GIDs there. 4746 final Permission configPermission = mRegistry.getPermission( 4747 permission.getName()); 4748 if (configPermission != null 4749 && configPermission.getType() == Permission.TYPE_CONFIG) { 4750 permission.setGids(configPermission.getRawGids(), 4751 configPermission.areGidsPerUser()); 4752 } 4753 mRegistry.addPermission(permission); 4754 } else { 4755 mRegistry.addPermissionTree(permission); 4756 } 4757 } 4758 } 4759 } 4760 } 4761 4762 private void writeLegacyPermissions( 4763 @NonNull LegacyPermissionSettings legacyPermissionSettings) { 4764 for (int writePermissionOrPermissionTree = 0; writePermissionOrPermissionTree < 2; 4765 writePermissionOrPermissionTree++) { 4766 final List<LegacyPermission> legacyPermissions = new ArrayList<>(); 4767 synchronized (mLock) { 4768 final Collection<Permission> permissions = writePermissionOrPermissionTree == 0 4769 ? mRegistry.getPermissions() : mRegistry.getPermissionTrees(); 4770 for (final Permission permission : permissions) { 4771 // We don't need to provide UID and GIDs, which are only retrieved when dumping. 4772 final LegacyPermission legacyPermission = new LegacyPermission( 4773 permission.getPermissionInfo(), permission.getType(), 0, 4774 EmptyArray.INT); 4775 legacyPermissions.add(legacyPermission); 4776 } 4777 } 4778 if (writePermissionOrPermissionTree == 0) { 4779 legacyPermissionSettings.replacePermissions(legacyPermissions); 4780 } else { 4781 legacyPermissionSettings.replacePermissionTrees(legacyPermissions); 4782 } 4783 } 4784 } 4785 4786 private void onPackageAddedInternal(@NonNull AndroidPackage pkg, boolean isInstantApp, 4787 @Nullable AndroidPackage oldPkg) { 4788 if (!pkg.getAdoptPermissions().isEmpty()) { 4789 // This package wants to adopt ownership of permissions from 4790 // another package. 4791 for (int i = pkg.getAdoptPermissions().size() - 1; i >= 0; i--) { 4792 final String origName = pkg.getAdoptPermissions().get(i); 4793 if (canAdoptPermissionsInternal(origName, pkg)) { 4794 Slog.i(TAG, "Adopting permissions from " + origName + " to " 4795 + pkg.getPackageName()); 4796 synchronized (mLock) { 4797 mRegistry.transferPermissions(origName, pkg.getPackageName()); 4798 } 4799 } 4800 } 4801 } 4802 4803 // Don't allow ephemeral applications to define new permissions groups. 4804 if (isInstantApp) { 4805 Slog.w(TAG, "Permission groups from package " + pkg.getPackageName() 4806 + " ignored: instant apps cannot define new permission groups."); 4807 } else { 4808 addAllPermissionGroupsInternal(pkg); 4809 } 4810 4811 // If a permission has had its defining app changed, or it has had its protection 4812 // upgraded, we need to revoke apps that hold it 4813 final List<String> permissionsWithChangedDefinition; 4814 // Don't allow ephemeral applications to define new permissions. 4815 if (isInstantApp) { 4816 permissionsWithChangedDefinition = null; 4817 Slog.w(TAG, "Permissions from package " + pkg.getPackageName() 4818 + " ignored: instant apps cannot define new permissions."); 4819 } else { 4820 permissionsWithChangedDefinition = addAllPermissionsInternal(pkg); 4821 } 4822 4823 boolean hasOldPkg = oldPkg != null; 4824 boolean hasPermissionDefinitionChanges = 4825 !CollectionUtils.isEmpty(permissionsWithChangedDefinition); 4826 if (hasOldPkg || hasPermissionDefinitionChanges) { 4827 // We need to call revokeRuntimePermissionsIfGroupChanged async as permission 4828 // revoke callbacks from this method might need to kill apps which need the 4829 // mPackages lock on a different thread. This would dead lock. 4830 AsyncTask.execute(() -> { 4831 if (hasOldPkg) { 4832 revokeRuntimePermissionsIfGroupChangedInternal(pkg, oldPkg); 4833 revokeStoragePermissionsIfScopeExpandedInternal(pkg, oldPkg); 4834 } 4835 if (hasPermissionDefinitionChanges) { 4836 revokeRuntimePermissionsIfPermissionDefinitionChangedInternal( 4837 permissionsWithChangedDefinition); 4838 } 4839 }); 4840 } 4841 } 4842 4843 private boolean canAdoptPermissionsInternal(@NonNull String oldPackageName, 4844 @NonNull AndroidPackage newPkg) { 4845 final PackageSetting oldPs = mPackageManagerInt.getPackageSetting(oldPackageName); 4846 if (oldPs == null) { 4847 return false; 4848 } 4849 if (!oldPs.isSystem()) { 4850 Slog.w(TAG, "Unable to update from " + oldPs.name 4851 + " to " + newPkg.getPackageName() 4852 + ": old package not in system partition"); 4853 return false; 4854 } 4855 if (mPackageManagerInt.getPackage(oldPs.name) != null) { 4856 Slog.w(TAG, "Unable to update from " + oldPs.name 4857 + " to " + newPkg.getPackageName() 4858 + ": old package still exists"); 4859 return false; 4860 } 4861 return true; 4862 } 4863 4864 private void onPackageInstalledInternal(@NonNull AndroidPackage pkg, 4865 @NonNull PermissionManagerServiceInternal.PackageInstalledParams params, 4866 @UserIdInt int[] userIds) { 4867 updatePermissions(pkg.getPackageName(), pkg); 4868 for (final int userId : userIds) { 4869 addAllowlistedRestrictedPermissionsInternal(pkg, 4870 params.getAllowlistedRestrictedPermissions(), 4871 FLAG_PERMISSION_WHITELIST_INSTALLER, userId); 4872 final int autoRevokePermissionsMode = params.getAutoRevokePermissionsMode(); 4873 if (autoRevokePermissionsMode == AppOpsManager.MODE_ALLOWED 4874 || autoRevokePermissionsMode == AppOpsManager.MODE_IGNORED) { 4875 setAutoRevokeExemptedInternal(pkg, 4876 autoRevokePermissionsMode == AppOpsManager.MODE_IGNORED, userId); 4877 } 4878 grantRequestedRuntimePermissionsInternal(pkg, params.getGrantedPermissions(), userId); 4879 } 4880 } 4881 4882 private void addAllowlistedRestrictedPermissionsInternal(@NonNull AndroidPackage pkg, 4883 @NonNull List<String> allowlistedRestrictedPermissions, 4884 @PermissionWhitelistFlags int flags, @UserIdInt int userId) { 4885 List<String> permissions = getAllowlistedRestrictedPermissionsInternal(pkg, flags, userId); 4886 if (permissions != null) { 4887 ArraySet<String> permissionSet = new ArraySet<>(permissions); 4888 permissionSet.addAll(allowlistedRestrictedPermissions); 4889 permissions = new ArrayList<>(permissionSet); 4890 } else { 4891 permissions = allowlistedRestrictedPermissions; 4892 } 4893 setAllowlistedRestrictedPermissionsInternal(pkg, permissions, flags, userId); 4894 } 4895 4896 private void onPackageRemovedInternal(@NonNull AndroidPackage pkg) { 4897 removeAllPermissionsInternal(pkg); 4898 } 4899 4900 private void onPackageUninstalledInternal(@NonNull String packageName, int appId, 4901 @Nullable AndroidPackage pkg, @NonNull List<AndroidPackage> sharedUserPkgs, 4902 @UserIdInt int[] userIds) { 4903 // TODO: Move these checks to check PackageState to be more reliable. 4904 // System packages should always have an available APK. 4905 if (pkg != null && pkg.isSystem() 4906 // We may be fully removing invalid system packages during boot, and in that case we 4907 // do want to remove their permission state. So make sure that the package is only 4908 // being marked as uninstalled instead of fully removed. 4909 && mPackageManagerInt.getPackage(packageName) != null) { 4910 // If we are only marking a system package as uninstalled, we need to keep its 4911 // pregranted permission state so that it still works once it gets reinstalled, thus 4912 // only reset the user modifications to its permission state. 4913 for (final int userId : userIds) { 4914 resetRuntimePermissionsInternal(pkg, userId); 4915 } 4916 return; 4917 } 4918 updatePermissions(packageName, null); 4919 for (final int userId : userIds) { 4920 if (sharedUserPkgs.isEmpty()) { 4921 removeUidStateAndResetPackageInstallPermissionsFixed(appId, packageName, userId); 4922 } else { 4923 // Remove permissions associated with package. Since runtime 4924 // permissions are per user we have to kill the removed package 4925 // or packages running under the shared user of the removed 4926 // package if revoking the permissions requested only by the removed 4927 // package is successful and this causes a change in gids. 4928 final int userIdToKill = revokeSharedUserPermissionsForDeletedPackageInternal(pkg, 4929 sharedUserPkgs, userId); 4930 final boolean shouldKill = userIdToKill != UserHandle.USER_NULL; 4931 // If gids changed, kill all affected packages. 4932 if (shouldKill) { 4933 mHandler.post(() -> { 4934 // This has to happen with no lock held. 4935 killUid(appId, UserHandle.USER_ALL, KILL_APP_REASON_GIDS_CHANGED); 4936 }); 4937 } 4938 } 4939 } 4940 } 4941 4942 @NonNull 4943 private List<LegacyPermission> getLegacyPermissions() { 4944 synchronized (mLock) { 4945 final List<LegacyPermission> legacyPermissions = new ArrayList<>(); 4946 for (final Permission permission : mRegistry.getPermissions()) { 4947 final LegacyPermission legacyPermission = new LegacyPermission( 4948 permission.getPermissionInfo(), permission.getType(), permission.getUid(), 4949 permission.getRawGids()); 4950 legacyPermissions.add(legacyPermission); 4951 } 4952 return legacyPermissions; 4953 } 4954 } 4955 4956 @NonNull 4957 private Map<String, Set<String>> getAllAppOpPermissionPackages() { 4958 synchronized (mLock) { 4959 final ArrayMap<String, ArraySet<String>> appOpPermissionPackages = 4960 mRegistry.getAllAppOpPermissionPackages(); 4961 final Map<String, Set<String>> deepClone = new ArrayMap<>(); 4962 final int appOpPermissionPackagesSize = appOpPermissionPackages.size(); 4963 for (int i = 0; i < appOpPermissionPackagesSize; i++) { 4964 final String appOpPermission = appOpPermissionPackages.keyAt(i); 4965 final ArraySet<String> packageNames = appOpPermissionPackages.valueAt(i); 4966 deepClone.put(appOpPermission, new ArraySet<>(packageNames)); 4967 } 4968 return deepClone; 4969 } 4970 } 4971 4972 @NonNull 4973 private LegacyPermissionState getLegacyPermissionState(@AppIdInt int appId) { 4974 final LegacyPermissionState legacyState = new LegacyPermissionState(); 4975 synchronized (mLock) { 4976 final int[] userIds = mState.getUserIds(); 4977 for (final int userId : userIds) { 4978 final UidPermissionState uidState = getUidStateLocked(appId, userId); 4979 if (uidState == null) { 4980 Slog.e(TAG, "Missing permissions state for app ID " + appId + " and user ID " 4981 + userId); 4982 continue; 4983 } 4984 4985 final List<PermissionState> permissionStates = uidState.getPermissionStates(); 4986 final int permissionStatesSize = permissionStates.size(); 4987 for (int i = 0; i < permissionStatesSize; i++) { 4988 final PermissionState permissionState = permissionStates.get(i); 4989 4990 final LegacyPermissionState.PermissionState legacyPermissionState = 4991 new LegacyPermissionState.PermissionState(permissionState.getName(), 4992 permissionState.getPermission().isRuntime(), 4993 permissionState.isGranted(), permissionState.getFlags()); 4994 legacyState.putPermissionState(legacyPermissionState, userId); 4995 } 4996 } 4997 } 4998 return legacyState; 4999 } 5000 5001 @NonNull 5002 private int[] getGidsForUid(int uid) { 5003 final int appId = UserHandle.getAppId(uid); 5004 final int userId = UserHandle.getUserId(uid); 5005 synchronized (mLock) { 5006 final UidPermissionState uidState = getUidStateLocked(appId, userId); 5007 if (uidState == null) { 5008 Slog.e(TAG, "Missing permissions state for app ID " + appId + " and user ID " 5009 + userId); 5010 return EMPTY_INT_ARRAY; 5011 } 5012 return uidState.computeGids(mGlobalGids, userId); 5013 } 5014 } 5015 5016 private class PermissionManagerServiceInternalImpl implements PermissionManagerServiceInternal { 5017 @Override 5018 public int checkPermission(@NonNull String packageName, @NonNull String permissionName, 5019 @UserIdInt int userId) { 5020 return PermissionManagerService.this.checkPermission(packageName, permissionName, 5021 userId); 5022 } 5023 5024 @Override 5025 public int checkUidPermission(int uid, @NonNull String permissionName) { 5026 return PermissionManagerService.this.checkUidPermission(uid, permissionName); 5027 } 5028 5029 @Override 5030 public void onSystemReady() { 5031 PermissionManagerService.this.systemReady(); 5032 } 5033 5034 @Override 5035 public boolean isPermissionsReviewRequired(@NonNull String packageName, 5036 @UserIdInt int userId) { 5037 Objects.requireNonNull(packageName, "packageName"); 5038 // TODO(b/173235285): Some caller may pass USER_ALL as userId. 5039 //Preconditions.checkArgumentNonnegative(userId, "userId"); 5040 return isPermissionsReviewRequiredInternal(packageName, userId); 5041 } 5042 5043 @Override 5044 public void readLegacyPermissionStateTEMP() { 5045 PermissionManagerService.this.readLegacyPermissionState(); 5046 } 5047 @Override 5048 public void writeLegacyPermissionStateTEMP() { 5049 PermissionManagerService.this.writeLegacyPermissionState(); 5050 } 5051 @Override 5052 public void onUserRemoved(@UserIdInt int userId) { 5053 Preconditions.checkArgumentNonNegative(userId, "userId"); 5054 PermissionManagerService.this.onUserRemoved(userId); 5055 } 5056 @NonNull 5057 @Override 5058 public Set<String> getGrantedPermissions(@NonNull String packageName, 5059 @UserIdInt int userId) { 5060 Objects.requireNonNull(packageName, "packageName"); 5061 Preconditions.checkArgumentNonNegative(userId, "userId"); 5062 return getGrantedPermissionsInternal(packageName, userId); 5063 } 5064 @NonNull 5065 @Override 5066 public int[] getPermissionGids(@NonNull String permissionName, @UserIdInt int userId) { 5067 Objects.requireNonNull(permissionName, "permissionName"); 5068 Preconditions.checkArgumentNonNegative(userId, "userId"); 5069 return getPermissionGidsInternal(permissionName, userId); 5070 } 5071 @NonNull 5072 @Override 5073 public String[] getAppOpPermissionPackages(@NonNull String permissionName) { 5074 Objects.requireNonNull(permissionName, "permissionName"); 5075 return PermissionManagerService.this.getAppOpPermissionPackagesInternal(permissionName); 5076 } 5077 @Override 5078 public void onStorageVolumeMounted(@Nullable String volumeUuid, boolean fingerprintChanged) { 5079 updateAllPermissions(volumeUuid, fingerprintChanged); 5080 } 5081 @Override 5082 public void resetRuntimePermissions(@NonNull AndroidPackage pkg, @UserIdInt int userId) { 5083 Objects.requireNonNull(pkg, "pkg"); 5084 Preconditions.checkArgumentNonNegative(userId, "userId"); 5085 resetRuntimePermissionsInternal(pkg, userId); 5086 } 5087 5088 @Override 5089 public Permission getPermissionTEMP(String permName) { 5090 synchronized (mLock) { 5091 return mRegistry.getPermission(permName); 5092 } 5093 } 5094 5095 @Override 5096 public @NonNull ArrayList<PermissionInfo> getAllPermissionsWithProtection( 5097 @PermissionInfo.Protection int protection) { 5098 ArrayList<PermissionInfo> matchingPermissions = new ArrayList<>(); 5099 5100 synchronized (mLock) { 5101 for (final Permission permission : mRegistry.getPermissions()) { 5102 if (permission.getProtection() == protection) { 5103 matchingPermissions.add(permission.generatePermissionInfo(0)); 5104 } 5105 } 5106 } 5107 5108 return matchingPermissions; 5109 } 5110 5111 @Override 5112 public @NonNull ArrayList<PermissionInfo> getAllPermissionsWithProtectionFlags( 5113 @PermissionInfo.ProtectionFlags int protectionFlags) { 5114 ArrayList<PermissionInfo> matchingPermissions = new ArrayList<>(); 5115 5116 synchronized (mLock) { 5117 for (final Permission permission : mRegistry.getPermissions()) { 5118 if ((permission.getProtectionFlags() & protectionFlags) == protectionFlags) { 5119 matchingPermissions.add(permission.generatePermissionInfo(0)); 5120 } 5121 } 5122 } 5123 5124 return matchingPermissions; 5125 } 5126 5127 @Nullable 5128 @Override 5129 public byte[] backupRuntimePermissions(@UserIdInt int userId) { 5130 Preconditions.checkArgumentNonNegative(userId, "userId"); 5131 return PermissionManagerService.this.backupRuntimePermissions(userId); 5132 } 5133 5134 @Override 5135 public void restoreRuntimePermissions(@NonNull byte[] backup, @UserIdInt int userId) { 5136 Objects.requireNonNull(backup, "backup"); 5137 Preconditions.checkArgumentNonNegative(userId, "userId"); 5138 PermissionManagerService.this.restoreRuntimePermissions(backup, userId); 5139 } 5140 5141 @Override 5142 public void restoreDelayedRuntimePermissions(@NonNull String packageName, 5143 @UserIdInt int userId) { 5144 Objects.requireNonNull(packageName, "packageName"); 5145 Preconditions.checkArgumentNonNegative(userId, "userId"); 5146 PermissionManagerService.this.restoreDelayedRuntimePermissions(packageName, userId); 5147 } 5148 5149 @Override 5150 public void addOnRuntimePermissionStateChangedListener( 5151 OnRuntimePermissionStateChangedListener listener) { 5152 PermissionManagerService.this.addOnRuntimePermissionStateChangedListener( 5153 listener); 5154 } 5155 5156 @Override 5157 public void removeOnRuntimePermissionStateChangedListener( 5158 OnRuntimePermissionStateChangedListener listener) { 5159 PermissionManagerService.this.removeOnRuntimePermissionStateChangedListener( 5160 listener); 5161 } 5162 5163 @Override 5164 public void startShellPermissionIdentityDelegation(int uid, @NonNull String packageName, 5165 @Nullable List<String> permissionNames) { 5166 Objects.requireNonNull(packageName, "packageName"); 5167 startShellPermissionIdentityDelegationInternal(uid, packageName, permissionNames); 5168 } 5169 5170 @Override 5171 public void stopShellPermissionIdentityDelegation() { 5172 stopShellPermissionIdentityDelegationInternal(); 5173 } 5174 5175 @Override 5176 @NonNull 5177 public List<String> getDelegatedShellPermissions() { 5178 return getDelegatedShellPermissionsInternal(); 5179 } 5180 5181 @Override 5182 public void onUserCreated(@UserIdInt int userId) { 5183 Preconditions.checkArgumentNonNegative(userId, "userId"); 5184 // NOTE: This adds UPDATE_PERMISSIONS_REPLACE_PKG 5185 updateAllPermissions(StorageManager.UUID_PRIVATE_INTERNAL, true); 5186 } 5187 5188 @Override 5189 public void readLegacyPermissionsTEMP( 5190 @NonNull LegacyPermissionSettings legacyPermissionSettings) { 5191 PermissionManagerService.this.readLegacyPermissions(legacyPermissionSettings); 5192 } 5193 5194 @Override 5195 public void writeLegacyPermissionsTEMP( 5196 @NonNull LegacyPermissionSettings legacyPermissionSettings) { 5197 PermissionManagerService.this.writeLegacyPermissions(legacyPermissionSettings); 5198 } 5199 5200 @Override 5201 public void onPackageAdded(@NonNull AndroidPackage pkg, boolean isInstantApp, 5202 @Nullable AndroidPackage oldPkg) { 5203 Objects.requireNonNull(pkg); 5204 onPackageAddedInternal(pkg, isInstantApp, oldPkg); 5205 } 5206 5207 @Override 5208 public void onPackageInstalled(@NonNull AndroidPackage pkg, 5209 @NonNull PackageInstalledParams params, @UserIdInt int userId) { 5210 Objects.requireNonNull(pkg, "pkg"); 5211 Objects.requireNonNull(params, "params"); 5212 Preconditions.checkArgument(userId >= UserHandle.USER_SYSTEM 5213 || userId == UserHandle.USER_ALL, "userId"); 5214 final int[] userIds = userId == UserHandle.USER_ALL ? getAllUserIds() 5215 : new int[] { userId }; 5216 onPackageInstalledInternal(pkg, params, userIds); 5217 } 5218 5219 @Override 5220 public void onPackageRemoved(@NonNull AndroidPackage pkg) { 5221 Objects.requireNonNull(pkg); 5222 onPackageRemovedInternal(pkg); 5223 } 5224 5225 @Override 5226 public void onPackageUninstalled(@NonNull String packageName, int appId, 5227 @Nullable AndroidPackage pkg, @NonNull List<AndroidPackage> sharedUserPkgs, 5228 @UserIdInt int userId) { 5229 Objects.requireNonNull(packageName, "packageName"); 5230 Objects.requireNonNull(sharedUserPkgs, "sharedUserPkgs"); 5231 Preconditions.checkArgument(userId >= UserHandle.USER_SYSTEM 5232 || userId == UserHandle.USER_ALL, "userId"); 5233 final int[] userIds = userId == UserHandle.USER_ALL ? getAllUserIds() 5234 : new int[] { userId }; 5235 onPackageUninstalledInternal(packageName, appId, pkg, sharedUserPkgs, userIds); 5236 } 5237 5238 @NonNull 5239 @Override 5240 public List<LegacyPermission> getLegacyPermissions() { 5241 return PermissionManagerService.this.getLegacyPermissions(); 5242 } 5243 5244 @NonNull 5245 @Override 5246 public Map<String, Set<String>> getAllAppOpPermissionPackages() { 5247 return PermissionManagerService.this.getAllAppOpPermissionPackages(); 5248 } 5249 5250 @NonNull 5251 @Override 5252 public LegacyPermissionState getLegacyPermissionState(@AppIdInt int appId) { 5253 return PermissionManagerService.this.getLegacyPermissionState(appId); 5254 } 5255 5256 @NonNull 5257 @Override 5258 public int[] getGidsForUid(int uid) { 5259 return PermissionManagerService.this.getGidsForUid(uid); 5260 } 5261 5262 @Override 5263 public void setHotwordDetectionServiceProvider(HotwordDetectionServiceProvider provider) { 5264 mHotwordDetectionServiceProvider = provider; 5265 } 5266 5267 @Override 5268 public HotwordDetectionServiceProvider getHotwordDetectionServiceProvider() { 5269 return mHotwordDetectionServiceProvider; 5270 } 5271 } 5272 5273 /** 5274 * Callbacks invoked when interesting actions have been taken on a permission. 5275 * <p> 5276 * NOTE: The current arguments are merely to support the existing use cases. This 5277 * needs to be properly thought out with appropriate arguments for each of the 5278 * callback methods. 5279 */ 5280 private static class PermissionCallback { 5281 public void onGidsChanged(@AppIdInt int appId, @UserIdInt int userId) {} 5282 public void onPermissionChanged() {} 5283 public void onPermissionGranted(int uid, @UserIdInt int userId) {} 5284 public void onInstallPermissionGranted() {} 5285 public void onPermissionRevoked(int uid, @UserIdInt int userId, String reason) {} 5286 public void onInstallPermissionRevoked() {} 5287 public void onPermissionUpdated(@UserIdInt int[] updatedUserIds, boolean sync) {} 5288 public void onPermissionUpdatedNotifyListener(@UserIdInt int[] updatedUserIds, boolean sync, 5289 int uid) { 5290 onPermissionUpdated(updatedUserIds, sync); 5291 } 5292 public void onPermissionRemoved() {} 5293 public void onInstallPermissionUpdated() {} 5294 public void onInstallPermissionUpdatedNotifyListener(int uid) { 5295 onInstallPermissionUpdated(); 5296 } 5297 } 5298 5299 private static final class OnPermissionChangeListeners extends Handler { 5300 private static final int MSG_ON_PERMISSIONS_CHANGED = 1; 5301 5302 private final RemoteCallbackList<IOnPermissionsChangeListener> mPermissionListeners = 5303 new RemoteCallbackList<>(); 5304 5305 OnPermissionChangeListeners(Looper looper) { 5306 super(looper); 5307 } 5308 5309 @Override 5310 public void handleMessage(Message msg) { 5311 switch (msg.what) { 5312 case MSG_ON_PERMISSIONS_CHANGED: { 5313 final int uid = msg.arg1; 5314 handleOnPermissionsChanged(uid); 5315 } break; 5316 } 5317 } 5318 5319 public void addListener(IOnPermissionsChangeListener listener) { 5320 mPermissionListeners.register(listener); 5321 } 5322 5323 public void removeListener(IOnPermissionsChangeListener listener) { 5324 mPermissionListeners.unregister(listener); 5325 } 5326 5327 public void onPermissionsChanged(int uid) { 5328 if (mPermissionListeners.getRegisteredCallbackCount() > 0) { 5329 obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget(); 5330 } 5331 } 5332 5333 private void handleOnPermissionsChanged(int uid) { 5334 final int count = mPermissionListeners.beginBroadcast(); 5335 try { 5336 for (int i = 0; i < count; i++) { 5337 IOnPermissionsChangeListener callback = mPermissionListeners 5338 .getBroadcastItem(i); 5339 try { 5340 callback.onPermissionsChanged(uid); 5341 } catch (RemoteException e) { 5342 Log.e(TAG, "Permission listener is dead", e); 5343 } 5344 } 5345 } finally { 5346 mPermissionListeners.finishBroadcast(); 5347 } 5348 } 5349 } 5350 5351 /** 5352 * Interface to intercept permission checks and optionally pass through to the original 5353 * implementation. 5354 */ 5355 private interface CheckPermissionDelegate { 5356 /** 5357 * Get the UID whose permission checks is being delegated. 5358 * 5359 * @return the UID 5360 */ 5361 int getDelegatedUid(); 5362 5363 /** 5364 * Check whether the given package has been granted the specified permission. 5365 * 5366 * @param packageName the name of the package to be checked 5367 * @param permissionName the name of the permission to be checked 5368 * @param userId the user ID 5369 * @param superImpl the original implementation that can be delegated to 5370 * @return {@link android.content.pm.PackageManager#PERMISSION_GRANTED} if the package has 5371 * the permission, or {@link android.content.pm.PackageManager#PERMISSION_DENIED} otherwise 5372 * 5373 * @see android.content.pm.PackageManager#checkPermission(String, String) 5374 */ 5375 int checkPermission(@NonNull String packageName, @NonNull String permissionName, 5376 @UserIdInt int userId, 5377 @NonNull TriFunction<String, String, Integer, Integer> superImpl); 5378 5379 /** 5380 * Check whether the given UID has been granted the specified permission. 5381 * 5382 * @param uid the UID to be checked 5383 * @param permissionName the name of the permission to be checked 5384 * @param superImpl the original implementation that can be delegated to 5385 * @return {@link android.content.pm.PackageManager#PERMISSION_GRANTED} if the package has 5386 * the permission, or {@link android.content.pm.PackageManager#PERMISSION_DENIED} otherwise 5387 */ 5388 int checkUidPermission(int uid, @NonNull String permissionName, 5389 BiFunction<Integer, String, Integer> superImpl); 5390 5391 /** 5392 * @return list of delegated permissions 5393 */ 5394 List<String> getDelegatedPermissionNames(); 5395 } 5396 5397 private class ShellDelegate implements CheckPermissionDelegate { 5398 private final int mDelegatedUid; 5399 @NonNull 5400 private final String mDelegatedPackageName; 5401 @Nullable 5402 private final List<String> mDelegatedPermissionNames; 5403 5404 public ShellDelegate(int delegatedUid, @NonNull String delegatedPackageName, 5405 @Nullable List<String> delegatedPermissionNames) { 5406 mDelegatedUid = delegatedUid; 5407 mDelegatedPackageName = delegatedPackageName; 5408 mDelegatedPermissionNames = delegatedPermissionNames; 5409 } 5410 5411 @Override 5412 public int getDelegatedUid() { 5413 return mDelegatedUid; 5414 } 5415 5416 @Override 5417 public int checkPermission(@NonNull String packageName, @NonNull String permissionName, 5418 int userId, @NonNull TriFunction<String, String, Integer, Integer> superImpl) { 5419 if (mDelegatedPackageName.equals(packageName) 5420 && isDelegatedPermission(permissionName)) { 5421 final long identity = Binder.clearCallingIdentity(); 5422 try { 5423 return superImpl.apply("com.android.shell", permissionName, userId); 5424 } finally { 5425 Binder.restoreCallingIdentity(identity); 5426 } 5427 } 5428 return superImpl.apply(packageName, permissionName, userId); 5429 } 5430 5431 @Override 5432 public int checkUidPermission(int uid, @NonNull String permissionName, 5433 @NonNull BiFunction<Integer, String, Integer> superImpl) { 5434 if (uid == mDelegatedUid && isDelegatedPermission(permissionName)) { 5435 final long identity = Binder.clearCallingIdentity(); 5436 try { 5437 return superImpl.apply(Process.SHELL_UID, permissionName); 5438 } finally { 5439 Binder.restoreCallingIdentity(identity); 5440 } 5441 } 5442 return superImpl.apply(uid, permissionName); 5443 } 5444 5445 @Override 5446 public List<String> getDelegatedPermissionNames() { 5447 return mDelegatedPermissionNames == null 5448 ? null 5449 : new ArrayList<>(mDelegatedPermissionNames); 5450 } 5451 5452 private boolean isDelegatedPermission(@NonNull String permissionName) { 5453 // null permissions means all permissions are targeted 5454 return mDelegatedPermissionNames == null 5455 || mDelegatedPermissionNames.contains(permissionName); 5456 } 5457 } 5458 5459 private static final class AttributionSourceRegistry { 5460 private final Object mLock = new Object(); 5461 5462 private final Context mContext; 5463 5464 AttributionSourceRegistry(@NonNull Context context) { 5465 mContext = context; 5466 } 5467 5468 private final WeakHashMap<IBinder, AttributionSource> mAttributions = new WeakHashMap<>(); 5469 5470 public void registerAttributionSource(@NonNull AttributionSource source) { 5471 // Here we keep track of attribution sources that were created by an app 5472 // from an attribution chain that called into the app and the apps's 5473 // own attribution source. An app can register an attribution chain up 5474 // to itself inclusive if and only if it is adding a node for itself which 5475 // optionally points to an attribution chain that was created by each 5476 // preceding app recursively up to the beginning of the chain. 5477 // The only special case is when the first app in the attribution chain 5478 // creates a source that points to another app (not a chain of apps). We 5479 // allow this even if the source the app points to is not registered since 5480 // in app ops we allow every app to blame every other app (untrusted if not 5481 // holding a special permission). 5482 // This technique ensures that a bad actor in the middle of the attribution 5483 // chain can neither prepend nor append an invalid attribution sequence, i.e. 5484 // a sequence that is not constructed by trusted sources up to the that bad 5485 // actor's app. 5486 // Note that passing your attribution source to another app means you allow 5487 // it to blame private data access on your app. This can be mediated by the OS 5488 // in, which case security is already enforced; by other app's code running in 5489 // your process calling into the other app, in which case it can already access 5490 // the private data in your process; or by you explicitly calling to another 5491 // app passing the source, in which case you must trust the other side; 5492 5493 final int callingUid = Binder.getCallingUid(); 5494 if (source.getUid() != callingUid && mContext.checkPermission( 5495 Manifest.permission.UPDATE_APP_OPS_STATS, /*pid*/ -1, callingUid) 5496 != PackageManager.PERMISSION_GRANTED) { 5497 throw new SecurityException("Cannot register attribution source for uid:" 5498 + source.getUid() + " from uid:" + callingUid); 5499 } 5500 5501 final PackageManagerInternal packageManagerInternal = LocalServices.getService( 5502 PackageManagerInternal.class); 5503 if (packageManagerInternal.getPackageUid(source.getPackageName(), 0, 5504 UserHandle.getUserId(callingUid)) != source.getUid()) { 5505 throw new SecurityException("Cannot register attribution source for package:" 5506 + source.getPackageName() + " from uid:" + callingUid); 5507 } 5508 5509 final AttributionSource next = source.getNext(); 5510 if (next != null && next.getNext() != null 5511 && !isRegisteredAttributionSource(next)) { 5512 throw new SecurityException("Cannot register forged attribution source:" 5513 + source); 5514 } 5515 5516 synchronized (mLock) { 5517 mAttributions.put(source.getToken(), source); 5518 } 5519 } 5520 5521 public boolean isRegisteredAttributionSource(@NonNull AttributionSource source) { 5522 synchronized (mLock) { 5523 final AttributionSource cachedSource = mAttributions.get(source.getToken()); 5524 if (cachedSource != null) { 5525 return cachedSource.equals(source); 5526 } 5527 return false; 5528 } 5529 } 5530 } 5531 5532 /** 5533 * TODO: We need to consolidate these APIs either on PermissionManager or an extension 5534 * object or a separate PermissionChecker service in context. The impartant part is to 5535 * keep a single impl that is exposed to Java and native. We are not sure about the 5536 * API shape so let is soak a bit. 5537 */ 5538 private static final class PermissionCheckerService extends IPermissionChecker.Stub { 5539 // Cache for platform defined runtime permissions to avoid multi lookup (name -> info) 5540 private static final ConcurrentHashMap<String, PermissionInfo> sPlatformPermissions 5541 = new ConcurrentHashMap<>(); 5542 5543 private static final AtomicInteger sAttributionChainIds = new AtomicInteger(0); 5544 5545 private final @NonNull Context mContext; 5546 private final @NonNull AppOpsManager mAppOpsManager; 5547 private final @NonNull PermissionManagerServiceInternal mPermissionManagerServiceInternal; 5548 5549 PermissionCheckerService(@NonNull Context context) { 5550 mContext = context; 5551 mAppOpsManager = mContext.getSystemService(AppOpsManager.class); 5552 mPermissionManagerServiceInternal = 5553 LocalServices.getService(PermissionManagerServiceInternal.class); 5554 } 5555 5556 @Override 5557 @PermissionCheckerManager.PermissionResult 5558 public int checkPermission(@NonNull String permission, 5559 @NonNull AttributionSourceState attributionSourceState, @Nullable String message, 5560 boolean forDataDelivery, boolean startDataDelivery, boolean fromDatasource, 5561 int attributedOp) { 5562 Objects.requireNonNull(permission); 5563 Objects.requireNonNull(attributionSourceState); 5564 final AttributionSource attributionSource = new AttributionSource( 5565 attributionSourceState); 5566 final int result = checkPermission(mContext, mPermissionManagerServiceInternal, 5567 permission, attributionSource, message, forDataDelivery, startDataDelivery, 5568 fromDatasource, attributedOp); 5569 // Finish any started op if some step in the attribution chain failed. 5570 if (startDataDelivery && result != PermissionChecker.PERMISSION_GRANTED 5571 && result != PermissionChecker.PERMISSION_SOFT_DENIED) { 5572 if (attributedOp == AppOpsManager.OP_NONE) { 5573 finishDataDelivery(AppOpsManager.permissionToOpCode(permission), 5574 attributionSource.asState(), fromDatasource); 5575 } else { 5576 finishDataDelivery(attributedOp, attributionSource.asState(), fromDatasource); 5577 } 5578 } 5579 return result; 5580 } 5581 5582 @Override 5583 public void finishDataDelivery(int op, 5584 @NonNull AttributionSourceState attributionSourceState, boolean fromDataSource) { 5585 finishDataDelivery(mContext, op, attributionSourceState, 5586 fromDataSource); 5587 } 5588 5589 private static void finishDataDelivery(Context context, int op, 5590 @NonNull AttributionSourceState attributionSourceState, boolean fromDatasource) { 5591 Objects.requireNonNull(attributionSourceState); 5592 AppOpsManager appOpsManager = context.getSystemService(AppOpsManager.class); 5593 5594 if (op == AppOpsManager.OP_NONE) { 5595 return; 5596 } 5597 5598 AttributionSource current = new AttributionSource(attributionSourceState); 5599 AttributionSource next = null; 5600 5601 while (true) { 5602 final boolean skipCurrentFinish = (fromDatasource || next != null); 5603 5604 next = current.getNext(); 5605 5606 // If the call is from a datasource we need to vet only the chain before it. This 5607 // way we can avoid the datasource creating an attribution context for every call. 5608 if (!(fromDatasource && current.asState() == attributionSourceState) 5609 && next != null && !current.isTrusted(context)) { 5610 return; 5611 } 5612 5613 // The access is for oneself if this is the single receiver of data 5614 // after the data source or if this is the single attribution source 5615 // in the chain if not from a datasource. 5616 final boolean singleReceiverFromDatasource = (fromDatasource 5617 && current.asState() == attributionSourceState && next != null 5618 && next.getNext() == null); 5619 final boolean selfAccess = singleReceiverFromDatasource || next == null; 5620 5621 final AttributionSource accessorSource = (!singleReceiverFromDatasource) 5622 ? current : next; 5623 5624 if (selfAccess) { 5625 final String resolvedPackageName = resolvePackageName(context, accessorSource); 5626 if (resolvedPackageName == null) { 5627 return; 5628 } 5629 appOpsManager.finishOp(accessorSource.getToken(), op, 5630 accessorSource.getUid(), resolvedPackageName, 5631 accessorSource.getAttributionTag()); 5632 } else { 5633 final AttributionSource resolvedAttributionSource = 5634 resolveAttributionSource(context, accessorSource); 5635 if (resolvedAttributionSource.getPackageName() == null) { 5636 return; 5637 } 5638 appOpsManager.finishProxyOp(AppOpsManager.opToPublicName(op), 5639 resolvedAttributionSource, skipCurrentFinish); 5640 } 5641 5642 if (next == null || next.getNext() == null) { 5643 return; 5644 } 5645 5646 RegisteredAttribution registered = 5647 sRunningAttributionSources.remove(current.getToken()); 5648 if (registered != null) { 5649 registered.unregister(); 5650 } 5651 current = next; 5652 } 5653 } 5654 5655 @Override 5656 @PermissionCheckerManager.PermissionResult 5657 public int checkOp(int op, AttributionSourceState attributionSource, 5658 String message, boolean forDataDelivery, boolean startDataDelivery) { 5659 int result = checkOp(mContext, op, mPermissionManagerServiceInternal, 5660 new AttributionSource(attributionSource), message, forDataDelivery, 5661 startDataDelivery); 5662 if (result != PermissionChecker.PERMISSION_GRANTED && startDataDelivery) { 5663 // Finish any started op if some step in the attribution chain failed. 5664 finishDataDelivery(op, attributionSource, /*fromDatasource*/ false); 5665 } 5666 return result; 5667 } 5668 5669 @PermissionCheckerManager.PermissionResult 5670 private static int checkPermission(@NonNull Context context, 5671 @NonNull PermissionManagerServiceInternal permissionManagerServiceInt, 5672 @NonNull String permission, @NonNull AttributionSource attributionSource, 5673 @Nullable String message, boolean forDataDelivery, boolean startDataDelivery, 5674 boolean fromDatasource, int attributedOp) { 5675 PermissionInfo permissionInfo = sPlatformPermissions.get(permission); 5676 5677 if (permissionInfo == null) { 5678 try { 5679 permissionInfo = context.getPackageManager().getPermissionInfo(permission, 0); 5680 if (PLATFORM_PACKAGE_NAME.equals(permissionInfo.packageName)) { 5681 // Double addition due to concurrency is fine - the backing 5682 // store is concurrent. 5683 sPlatformPermissions.put(permission, permissionInfo); 5684 } 5685 } catch (PackageManager.NameNotFoundException ignored) { 5686 return PermissionChecker.PERMISSION_HARD_DENIED; 5687 } 5688 } 5689 5690 if (permissionInfo.isAppOp()) { 5691 return checkAppOpPermission(context, permissionManagerServiceInt, permission, 5692 attributionSource, message, forDataDelivery, fromDatasource); 5693 } 5694 if (permissionInfo.isRuntime()) { 5695 return checkRuntimePermission(context, permissionManagerServiceInt, permission, 5696 attributionSource, message, forDataDelivery, startDataDelivery, 5697 fromDatasource, attributedOp); 5698 } 5699 5700 if (!fromDatasource && !checkPermission(context, permissionManagerServiceInt, 5701 permission, attributionSource.getUid(), 5702 attributionSource.getRenouncedPermissions())) { 5703 return PermissionChecker.PERMISSION_HARD_DENIED; 5704 } 5705 5706 if (attributionSource.getNext() != null) { 5707 return checkPermission(context, permissionManagerServiceInt, permission, 5708 attributionSource.getNext(), message, forDataDelivery, startDataDelivery, 5709 /*fromDatasource*/ false, attributedOp); 5710 } 5711 5712 return PermissionChecker.PERMISSION_GRANTED; 5713 } 5714 5715 @PermissionCheckerManager.PermissionResult 5716 private static int checkAppOpPermission(@NonNull Context context, 5717 @NonNull PermissionManagerServiceInternal permissionManagerServiceInt, 5718 @NonNull String permission, @NonNull AttributionSource attributionSource, 5719 @Nullable String message, boolean forDataDelivery, boolean fromDatasource) { 5720 final int op = AppOpsManager.permissionToOpCode(permission); 5721 if (op < 0) { 5722 Slog.wtf(LOG_TAG, "Appop permission " + permission + " with no app op defined!"); 5723 return PermissionChecker.PERMISSION_HARD_DENIED; 5724 } 5725 5726 AttributionSource current = attributionSource; 5727 AttributionSource next = null; 5728 5729 while (true) { 5730 final boolean skipCurrentChecks = (fromDatasource || next != null); 5731 5732 next = current.getNext(); 5733 5734 // If the call is from a datasource we need to vet only the chain before it. This 5735 // way we can avoid the datasource creating an attribution context for every call. 5736 if (!(fromDatasource && current.equals(attributionSource)) 5737 && next != null && !current.isTrusted(context)) { 5738 return PermissionChecker.PERMISSION_HARD_DENIED; 5739 } 5740 5741 // The access is for oneself if this is the single receiver of data 5742 // after the data source or if this is the single attribution source 5743 // in the chain if not from a datasource. 5744 final boolean singleReceiverFromDatasource = (fromDatasource 5745 && current.equals(attributionSource) && next != null 5746 && next.getNext() == null); 5747 final boolean selfAccess = singleReceiverFromDatasource || next == null; 5748 5749 final int opMode = performOpTransaction(context, op, current, message, 5750 forDataDelivery, /*startDataDelivery*/ false, skipCurrentChecks, 5751 selfAccess, singleReceiverFromDatasource, AppOpsManager.OP_NONE, 5752 AppOpsManager.ATTRIBUTION_FLAGS_NONE, AppOpsManager.ATTRIBUTION_FLAGS_NONE, 5753 AppOpsManager.ATTRIBUTION_CHAIN_ID_NONE); 5754 5755 switch (opMode) { 5756 case AppOpsManager.MODE_IGNORED: 5757 case AppOpsManager.MODE_ERRORED: { 5758 return PermissionChecker.PERMISSION_HARD_DENIED; 5759 } 5760 case AppOpsManager.MODE_DEFAULT: { 5761 if (!skipCurrentChecks && !checkPermission(context, 5762 permissionManagerServiceInt, permission, attributionSource.getUid(), 5763 attributionSource.getRenouncedPermissions())) { 5764 return PermissionChecker.PERMISSION_HARD_DENIED; 5765 } 5766 if (next != null && !checkPermission(context, permissionManagerServiceInt, 5767 permission, next.getUid(), next.getRenouncedPermissions())) { 5768 return PermissionChecker.PERMISSION_HARD_DENIED; 5769 } 5770 } 5771 } 5772 5773 if (next == null || next.getNext() == null) { 5774 return PermissionChecker.PERMISSION_GRANTED; 5775 } 5776 5777 current = next; 5778 } 5779 } 5780 5781 private static int checkRuntimePermission(@NonNull Context context, 5782 @NonNull PermissionManagerServiceInternal permissionManagerServiceInt, 5783 @NonNull String permission, @NonNull AttributionSource attributionSource, 5784 @Nullable String message, boolean forDataDelivery, boolean startDataDelivery, 5785 boolean fromDatasource, int attributedOp) { 5786 // Now let's check the identity chain... 5787 final int op = AppOpsManager.permissionToOpCode(permission); 5788 final int attributionChainId = 5789 getAttributionChainId(startDataDelivery, attributionSource); 5790 final boolean hasChain = attributionChainId != ATTRIBUTION_CHAIN_ID_NONE; 5791 AttributionSource current = attributionSource; 5792 AttributionSource next = null; 5793 // We consider the chain trusted if the start node has UPDATE_APP_OPS_STATS, and 5794 // every attributionSource in the chain is registered with the system. 5795 final boolean isChainStartTrusted = !hasChain || checkPermission(context, 5796 permissionManagerServiceInt, UPDATE_APP_OPS_STATS, current.getUid(), 5797 current.getRenouncedPermissions()); 5798 5799 while (true) { 5800 final boolean skipCurrentChecks = (fromDatasource || next != null); 5801 next = current.getNext(); 5802 5803 // If the call is from a datasource we need to vet only the chain before it. This 5804 // way we can avoid the datasource creating an attribution context for every call. 5805 if (!(fromDatasource && current.equals(attributionSource)) 5806 && next != null && !current.isTrusted(context)) { 5807 return PermissionChecker.PERMISSION_HARD_DENIED; 5808 } 5809 5810 // If we already checked the permission for this one, skip the work 5811 if (!skipCurrentChecks && !checkPermission(context, permissionManagerServiceInt, 5812 permission, current.getUid(), current.getRenouncedPermissions())) { 5813 return PermissionChecker.PERMISSION_HARD_DENIED; 5814 } 5815 5816 if (next != null && !checkPermission(context, permissionManagerServiceInt, 5817 permission, next.getUid(), next.getRenouncedPermissions())) { 5818 return PermissionChecker.PERMISSION_HARD_DENIED; 5819 } 5820 5821 if (op < 0) { 5822 // Bg location is one-off runtime modifier permission and has no app op 5823 if (sPlatformPermissions.contains(permission) 5824 && !Manifest.permission.ACCESS_BACKGROUND_LOCATION.equals(permission)) { 5825 Slog.wtf(LOG_TAG, "Platform runtime permission " + permission 5826 + " with no app op defined!"); 5827 } 5828 if (next == null) { 5829 return PermissionChecker.PERMISSION_GRANTED; 5830 } 5831 current = next; 5832 continue; 5833 } 5834 5835 // The access is for oneself if this is the single receiver of data 5836 // after the data source or if this is the single attribution source 5837 // in the chain if not from a datasource. 5838 final boolean singleReceiverFromDatasource = (fromDatasource 5839 && current.equals(attributionSource) 5840 && next != null && next.getNext() == null); 5841 final boolean selfAccess = singleReceiverFromDatasource || next == null; 5842 final boolean isLinkTrusted = isChainStartTrusted 5843 && (current.isTrusted(context) || current.equals(attributionSource)) 5844 && (next == null || next.isTrusted(context)); 5845 5846 final int proxyAttributionFlags = (!skipCurrentChecks && hasChain) 5847 ? resolveProxyAttributionFlags(attributionSource, current, fromDatasource, 5848 startDataDelivery, selfAccess, isLinkTrusted) 5849 : ATTRIBUTION_FLAGS_NONE; 5850 final int proxiedAttributionFlags = hasChain ? resolveProxiedAttributionFlags( 5851 attributionSource, next, fromDatasource, startDataDelivery, selfAccess, 5852 isLinkTrusted) : ATTRIBUTION_FLAGS_NONE; 5853 5854 final int opMode = performOpTransaction(context, op, current, message, 5855 forDataDelivery, startDataDelivery, skipCurrentChecks, selfAccess, 5856 singleReceiverFromDatasource, attributedOp, proxyAttributionFlags, 5857 proxiedAttributionFlags, attributionChainId); 5858 5859 switch (opMode) { 5860 case AppOpsManager.MODE_ERRORED: { 5861 return PermissionChecker.PERMISSION_HARD_DENIED; 5862 } 5863 case AppOpsManager.MODE_IGNORED: { 5864 return PermissionChecker.PERMISSION_SOFT_DENIED; 5865 } 5866 } 5867 5868 if (startDataDelivery) { 5869 RegisteredAttribution registered = new RegisteredAttribution(context, op, 5870 current, fromDatasource); 5871 sRunningAttributionSources.put(current.getToken(), registered); 5872 } 5873 5874 if (next == null || next.getNext() == null) { 5875 return PermissionChecker.PERMISSION_GRANTED; 5876 } 5877 5878 current = next; 5879 } 5880 } 5881 5882 private static boolean checkPermission(@NonNull Context context, 5883 @NonNull PermissionManagerServiceInternal permissionManagerServiceInt, 5884 @NonNull String permission, int uid, @NonNull Set<String> renouncedPermissions) { 5885 boolean permissionGranted = context.checkPermission(permission, /*pid*/ -1, 5886 uid) == PackageManager.PERMISSION_GRANTED; 5887 5888 // Override certain permissions checks for the HotwordDetectionService. This service is 5889 // an isolated service, which ordinarily cannot hold permissions. 5890 // There's probably a cleaner, more generalizable way to do this. For now, this is 5891 // the only use case for this, so simply override here. 5892 if (!permissionGranted 5893 && Process.isIsolated(uid) // simple check which fails-fast for the common case 5894 && (permission.equals(RECORD_AUDIO) 5895 || permission.equals(CAPTURE_AUDIO_HOTWORD))) { 5896 HotwordDetectionServiceProvider hotwordServiceProvider = 5897 permissionManagerServiceInt.getHotwordDetectionServiceProvider(); 5898 permissionGranted = hotwordServiceProvider != null 5899 && uid == hotwordServiceProvider.getUid(); 5900 } 5901 5902 if (permissionGranted && renouncedPermissions.contains(permission) 5903 && context.checkPermission(Manifest.permission.RENOUNCE_PERMISSIONS, 5904 /*pid*/ -1, uid) == PackageManager.PERMISSION_GRANTED) { 5905 return false; 5906 } 5907 return permissionGranted; 5908 } 5909 5910 private static @AttributionFlags int resolveProxyAttributionFlags( 5911 @NonNull AttributionSource attributionChain, 5912 @NonNull AttributionSource current, boolean fromDatasource, 5913 boolean startDataDelivery, boolean selfAccess, boolean isTrusted) { 5914 return resolveAttributionFlags(attributionChain, current, fromDatasource, 5915 startDataDelivery, selfAccess, isTrusted, /*flagsForProxy*/ true); 5916 } 5917 5918 private static @AttributionFlags int resolveProxiedAttributionFlags( 5919 @NonNull AttributionSource attributionChain, 5920 @NonNull AttributionSource current, boolean fromDatasource, 5921 boolean startDataDelivery, boolean selfAccess, boolean isTrusted) { 5922 return resolveAttributionFlags(attributionChain, current, fromDatasource, 5923 startDataDelivery, selfAccess, isTrusted, /*flagsForProxy*/ false); 5924 } 5925 5926 private static @AttributionFlags int resolveAttributionFlags( 5927 @NonNull AttributionSource attributionChain, 5928 @NonNull AttributionSource current, boolean fromDatasource, 5929 boolean startDataDelivery, boolean selfAccess, boolean isTrusted, 5930 boolean flagsForProxy) { 5931 if (current == null || !startDataDelivery) { 5932 return AppOpsManager.ATTRIBUTION_FLAGS_NONE; 5933 } 5934 int trustedFlag = isTrusted 5935 ? AppOpsManager.ATTRIBUTION_FLAG_TRUSTED : AppOpsManager.ATTRIBUTION_FLAGS_NONE; 5936 if (flagsForProxy) { 5937 if (selfAccess) { 5938 return trustedFlag | AppOpsManager.ATTRIBUTION_FLAG_ACCESSOR; 5939 } else if (!fromDatasource && current.equals(attributionChain)) { 5940 return trustedFlag | AppOpsManager.ATTRIBUTION_FLAG_ACCESSOR; 5941 } 5942 } else { 5943 if (selfAccess) { 5944 return trustedFlag | AppOpsManager.ATTRIBUTION_FLAG_RECEIVER; 5945 } else if (fromDatasource && current.equals(attributionChain.getNext())) { 5946 return trustedFlag | AppOpsManager.ATTRIBUTION_FLAG_ACCESSOR; 5947 } else if (current.getNext() == null) { 5948 return trustedFlag | AppOpsManager.ATTRIBUTION_FLAG_RECEIVER; 5949 } 5950 } 5951 if (fromDatasource && current.equals(attributionChain)) { 5952 return AppOpsManager.ATTRIBUTION_FLAGS_NONE; 5953 } 5954 return trustedFlag | AppOpsManager.ATTRIBUTION_FLAG_INTERMEDIARY; 5955 } 5956 5957 private static int checkOp(@NonNull Context context, @NonNull int op, 5958 @NonNull PermissionManagerServiceInternal permissionManagerServiceInt, 5959 @NonNull AttributionSource attributionSource, @Nullable String message, 5960 boolean forDataDelivery, boolean startDataDelivery) { 5961 if (op < 0 || attributionSource.getPackageName() == null) { 5962 return PermissionChecker.PERMISSION_HARD_DENIED; 5963 } 5964 5965 final int attributionChainId = 5966 getAttributionChainId(startDataDelivery, attributionSource); 5967 final boolean hasChain = attributionChainId != ATTRIBUTION_CHAIN_ID_NONE; 5968 5969 AttributionSource current = attributionSource; 5970 AttributionSource next = null; 5971 5972 // We consider the chain trusted if the start node has UPDATE_APP_OPS_STATS, and 5973 // every attributionSource in the chain is registered with the system. 5974 final boolean isChainStartTrusted = !hasChain || checkPermission(context, 5975 permissionManagerServiceInt, UPDATE_APP_OPS_STATS, current.getUid(), 5976 current.getRenouncedPermissions()); 5977 5978 while (true) { 5979 final boolean skipCurrentChecks = (next != null); 5980 next = current.getNext(); 5981 5982 // If the call is from a datasource we need to vet only the chain before it. This 5983 // way we can avoid the datasource creating an attribution context for every call. 5984 if (next != null && !current.isTrusted(context)) { 5985 return PermissionChecker.PERMISSION_HARD_DENIED; 5986 } 5987 5988 // The access is for oneself if this is the single attribution source in the chain. 5989 final boolean selfAccess = (next == null); 5990 final boolean isLinkTrusted = isChainStartTrusted 5991 && (current.isTrusted(context) || current.equals(attributionSource)) 5992 && (next == null || next.isTrusted(context)); 5993 5994 final int proxyAttributionFlags = (!skipCurrentChecks && hasChain) 5995 ? resolveProxyAttributionFlags(attributionSource, current, 5996 /*fromDatasource*/ false, startDataDelivery, selfAccess, 5997 isLinkTrusted) : ATTRIBUTION_FLAGS_NONE; 5998 final int proxiedAttributionFlags = hasChain ? resolveProxiedAttributionFlags( 5999 attributionSource, next, /*fromDatasource*/ false, startDataDelivery, 6000 selfAccess, isLinkTrusted) : ATTRIBUTION_FLAGS_NONE; 6001 6002 final int opMode = performOpTransaction(context, op, current, message, 6003 forDataDelivery, startDataDelivery, skipCurrentChecks, selfAccess, 6004 /*fromDatasource*/ false, AppOpsManager.OP_NONE, proxyAttributionFlags, 6005 proxiedAttributionFlags, attributionChainId); 6006 6007 switch (opMode) { 6008 case AppOpsManager.MODE_ERRORED: { 6009 return PermissionChecker.PERMISSION_HARD_DENIED; 6010 } 6011 case AppOpsManager.MODE_IGNORED: { 6012 return PermissionChecker.PERMISSION_SOFT_DENIED; 6013 } 6014 } 6015 6016 if (next == null || next.getNext() == null) { 6017 return PermissionChecker.PERMISSION_GRANTED; 6018 } 6019 6020 current = next; 6021 } 6022 } 6023 6024 @SuppressWarnings("ConstantConditions") 6025 private static int performOpTransaction(@NonNull Context context, int op, 6026 @NonNull AttributionSource attributionSource, @Nullable String message, 6027 boolean forDataDelivery, boolean startDataDelivery, boolean skipProxyOperation, 6028 boolean selfAccess, boolean singleReceiverFromDatasource, int attributedOp, 6029 @AttributionFlags int proxyAttributionFlags, 6030 @AttributionFlags int proxiedAttributionFlags, int attributionChainId) { 6031 // We cannot perform app ops transactions without a package name. In all relevant 6032 // places we pass the package name but just in case there is a bug somewhere we 6033 // do a best effort to resolve the package from the UID (pick first without a loss 6034 // of generality - they are in the same security sandbox). 6035 final AppOpsManager appOpsManager = context.getSystemService(AppOpsManager.class); 6036 final AttributionSource accessorSource = (!singleReceiverFromDatasource) 6037 ? attributionSource : attributionSource.getNext(); 6038 if (!forDataDelivery) { 6039 final String resolvedAccessorPackageName = resolvePackageName(context, 6040 accessorSource); 6041 if (resolvedAccessorPackageName == null) { 6042 return AppOpsManager.MODE_ERRORED; 6043 } 6044 final int opMode = appOpsManager.unsafeCheckOpRawNoThrow(op, 6045 accessorSource.getUid(), resolvedAccessorPackageName); 6046 final AttributionSource next = accessorSource.getNext(); 6047 if (!selfAccess && opMode == AppOpsManager.MODE_ALLOWED && next != null) { 6048 final String resolvedNextPackageName = resolvePackageName(context, next); 6049 if (resolvedNextPackageName == null) { 6050 return AppOpsManager.MODE_ERRORED; 6051 } 6052 return appOpsManager.unsafeCheckOpRawNoThrow(op, next.getUid(), 6053 resolvedNextPackageName); 6054 } 6055 return opMode; 6056 } else if (startDataDelivery) { 6057 final AttributionSource resolvedAttributionSource = resolveAttributionSource( 6058 context, accessorSource); 6059 if (resolvedAttributionSource.getPackageName() == null) { 6060 return AppOpsManager.MODE_ERRORED; 6061 } 6062 // If the datasource is not in a trusted platform component then in would not 6063 // have UPDATE_APP_OPS_STATS and the call below would fail. The problem is that 6064 // an app is exposing runtime permission protected data but cannot blame others 6065 // in a trusted way which would not properly show in permission usage UIs. 6066 // As a fallback we note a proxy op that blames the app and the datasource. 6067 int startedOp = op; 6068 int checkedOpResult = MODE_ALLOWED; 6069 int startedOpResult; 6070 6071 // If the datasource wants to attribute to another app op we need to 6072 // make sure the op for the permission and the attributed ops allow 6073 // the operation. We return the less permissive of the two and check 6074 // the permission op while start the attributed op. 6075 if (attributedOp != AppOpsManager.OP_NONE && attributedOp != op) { 6076 checkedOpResult = appOpsManager.checkOpNoThrow(op, 6077 resolvedAttributionSource.getUid(), resolvedAttributionSource 6078 .getPackageName()); 6079 if (checkedOpResult == MODE_ERRORED) { 6080 return checkedOpResult; 6081 } 6082 startedOp = attributedOp; 6083 } 6084 if (selfAccess) { 6085 try { 6086 startedOpResult = appOpsManager.startOpNoThrow( 6087 resolvedAttributionSource.getToken(), startedOp, 6088 resolvedAttributionSource.getUid(), 6089 resolvedAttributionSource.getPackageName(), 6090 /*startIfModeDefault*/ false, 6091 resolvedAttributionSource.getAttributionTag(), 6092 message, proxyAttributionFlags, attributionChainId); 6093 } catch (SecurityException e) { 6094 Slog.w(LOG_TAG, "Datasource " + attributionSource + " protecting data with" 6095 + " platform defined runtime permission " 6096 + AppOpsManager.opToPermission(op) + " while not having " 6097 + Manifest.permission.UPDATE_APP_OPS_STATS); 6098 startedOpResult = appOpsManager.startProxyOpNoThrow(attributedOp, 6099 attributionSource, message, skipProxyOperation, 6100 proxyAttributionFlags, proxiedAttributionFlags, attributionChainId); 6101 } 6102 } else { 6103 startedOpResult = appOpsManager.startProxyOpNoThrow(startedOp, 6104 resolvedAttributionSource, message, skipProxyOperation, 6105 proxyAttributionFlags, proxiedAttributionFlags, attributionChainId); 6106 } 6107 return Math.max(checkedOpResult, startedOpResult); 6108 } else { 6109 final AttributionSource resolvedAttributionSource = resolveAttributionSource( 6110 context, accessorSource); 6111 if (resolvedAttributionSource.getPackageName() == null) { 6112 return AppOpsManager.MODE_ERRORED; 6113 } 6114 int notedOp = op; 6115 int checkedOpResult = MODE_ALLOWED; 6116 int notedOpResult; 6117 6118 // If the datasource wants to attribute to another app op we need to 6119 // make sure the op for the permission and the attributed ops allow 6120 // the operation. We return the less permissive of the two and check 6121 // the permission op while start the attributed op. 6122 if (attributedOp != AppOpsManager.OP_NONE && attributedOp != op) { 6123 checkedOpResult = appOpsManager.checkOpNoThrow(op, 6124 resolvedAttributionSource.getUid(), resolvedAttributionSource 6125 .getPackageName()); 6126 if (checkedOpResult == MODE_ERRORED) { 6127 return checkedOpResult; 6128 } 6129 notedOp = attributedOp; 6130 } 6131 if (selfAccess) { 6132 // If the datasource is not in a trusted platform component then in would not 6133 // have UPDATE_APP_OPS_STATS and the call below would fail. The problem is that 6134 // an app is exposing runtime permission protected data but cannot blame others 6135 // in a trusted way which would not properly show in permission usage UIs. 6136 // As a fallback we note a proxy op that blames the app and the datasource. 6137 try { 6138 notedOpResult = appOpsManager.noteOpNoThrow(notedOp, 6139 resolvedAttributionSource.getUid(), 6140 resolvedAttributionSource.getPackageName(), 6141 resolvedAttributionSource.getAttributionTag(), 6142 message); 6143 } catch (SecurityException e) { 6144 Slog.w(LOG_TAG, "Datasource " + attributionSource + " protecting data with" 6145 + " platform defined runtime permission " 6146 + AppOpsManager.opToPermission(op) + " while not having " 6147 + Manifest.permission.UPDATE_APP_OPS_STATS); 6148 notedOpResult = appOpsManager.noteProxyOpNoThrow(notedOp, attributionSource, 6149 message, skipProxyOperation); 6150 } 6151 } else { 6152 notedOpResult = appOpsManager.noteProxyOpNoThrow(notedOp, 6153 resolvedAttributionSource, message, skipProxyOperation); 6154 } 6155 return Math.max(checkedOpResult, notedOpResult); 6156 } 6157 } 6158 6159 private static int getAttributionChainId(boolean startDataDelivery, 6160 AttributionSource source) { 6161 if (source == null || source.getNext() == null || !startDataDelivery) { 6162 return AppOpsManager.ATTRIBUTION_CHAIN_ID_NONE; 6163 } 6164 int attributionChainId = sAttributionChainIds.incrementAndGet(); 6165 6166 // handle overflow 6167 if (attributionChainId < 0) { 6168 attributionChainId = 0; 6169 sAttributionChainIds.set(0); 6170 } 6171 return attributionChainId; 6172 } 6173 6174 private static @Nullable String resolvePackageName(@NonNull Context context, 6175 @NonNull AttributionSource attributionSource) { 6176 if (attributionSource.getPackageName() != null) { 6177 return attributionSource.getPackageName(); 6178 } 6179 final String[] packageNames = context.getPackageManager().getPackagesForUid( 6180 attributionSource.getUid()); 6181 if (packageNames != null) { 6182 // This is best effort if the caller doesn't pass a package. The security 6183 // sandbox is UID, therefore we pick an arbitrary package. 6184 return packageNames[0]; 6185 } 6186 // Last resort to handle special UIDs like root, etc. 6187 return AppOpsManager.resolvePackageName(attributionSource.getUid(), 6188 attributionSource.getPackageName()); 6189 } 6190 6191 private static @NonNull AttributionSource resolveAttributionSource( 6192 @NonNull Context context, @NonNull AttributionSource attributionSource) { 6193 if (attributionSource.getPackageName() != null) { 6194 return attributionSource; 6195 } 6196 return attributionSource.withPackageName(resolvePackageName(context, 6197 attributionSource)); 6198 } 6199 } 6200 6201 private static final class RegisteredAttribution { 6202 private final DeathRecipient mDeathRecipient; 6203 private final IBinder mToken; 6204 private final AtomicBoolean mFinished; 6205 6206 RegisteredAttribution(Context context, int op, AttributionSource source, 6207 boolean fromDatasource) { 6208 mFinished = new AtomicBoolean(false); 6209 mDeathRecipient = () -> { 6210 if (unregister()) { 6211 PermissionCheckerService 6212 .finishDataDelivery(context, op, source.asState(), fromDatasource); 6213 } 6214 }; 6215 mToken = source.getToken(); 6216 if (mToken != null) { 6217 try { 6218 mToken.linkToDeath(mDeathRecipient, 0); 6219 } catch (RemoteException e) { 6220 mDeathRecipient.binderDied(); 6221 } 6222 } 6223 } 6224 6225 public boolean unregister() { 6226 if (mFinished.compareAndSet(false, true)) { 6227 try { 6228 if (mToken != null) { 6229 mToken.unlinkToDeath(mDeathRecipient, 0); 6230 } 6231 } catch (NoSuchElementException e) { 6232 // do nothing 6233 } 6234 return true; 6235 } 6236 return false; 6237 } 6238 } 6239 } 6240