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