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