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