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