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