1 /* 2 * Copyright (C) 2018 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.uri; 18 19 import static android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS; 20 import static android.Manifest.permission.FORCE_PERSISTABLE_URI_PERMISSIONS; 21 import static android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS; 22 import static android.Manifest.permission.INTERACT_ACROSS_USERS; 23 import static android.app.ActivityManagerInternal.ALLOW_FULL_ONLY; 24 import static android.content.Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION; 25 import static android.content.Intent.FLAG_GRANT_PREFIX_URI_PERMISSION; 26 import static android.content.pm.ActivityInfo.CONTENT_URI_PERMISSION_NONE; 27 import static android.content.pm.ActivityInfo.CONTENT_URI_PERMISSION_READ; 28 import static android.content.pm.ActivityInfo.CONTENT_URI_PERMISSION_READ_OR_WRITE; 29 import static android.content.pm.ActivityInfo.isRequiredContentUriPermissionRead; 30 import static android.content.pm.ActivityInfo.isRequiredContentUriPermissionWrite; 31 import static android.content.pm.PackageManager.MATCH_ANY_USER; 32 import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING; 33 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AUTO; 34 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE; 35 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE; 36 import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES; 37 import static android.content.pm.PackageManager.PERMISSION_GRANTED; 38 import static android.os.Process.ROOT_UID; 39 import static android.os.Process.SYSTEM_UID; 40 import static android.os.Process.myUid; 41 42 import static com.android.internal.util.XmlUtils.writeBooleanAttribute; 43 import static com.android.internal.util.FrameworkStatsLog.CONTENT_OR_FILE_URI_EVENT_REPORTED; 44 import static com.android.internal.util.FrameworkStatsLog.CONTENT_OR_FILE_URI_EVENT_REPORTED__EVENT_TYPE__CONTENT_URI_WITHOUT_CALLER_READ_PERMISSION; 45 import static com.android.server.uri.UriGrantsManagerService.H.PERSIST_URI_GRANTS_MSG; 46 47 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 48 import static org.xmlpull.v1.XmlPullParser.START_TAG; 49 50 import android.annotation.NonNull; 51 import android.annotation.Nullable; 52 import android.annotation.RequiresPermission; 53 import android.app.ActivityManager; 54 import android.app.ActivityManagerInternal; 55 import android.app.AppGlobals; 56 import android.app.GrantedUriPermission; 57 import android.app.IUriGrantsManager; 58 import android.content.ClipData; 59 import android.content.ContentProvider; 60 import android.content.ContentResolver; 61 import android.content.Context; 62 import android.content.Intent; 63 import android.content.pm.ActivityInfo; 64 import android.content.pm.ActivityInfo.RequiredContentUriPermission; 65 import android.content.pm.PackageManager; 66 import android.content.pm.PackageManagerInternal; 67 import android.content.pm.ParceledListSlice; 68 import android.content.pm.PathPermission; 69 import android.content.pm.ProviderInfo; 70 import android.net.Uri; 71 import android.os.BadParcelableException; 72 import android.os.Binder; 73 import android.os.Handler; 74 import android.os.IBinder; 75 import android.os.Looper; 76 import android.os.Message; 77 import android.os.Process; 78 import android.os.RemoteException; 79 import android.os.SystemClock; 80 import android.os.UserHandle; 81 import android.provider.Downloads; 82 import android.text.format.DateUtils; 83 import android.util.ArrayMap; 84 import android.util.ArraySet; 85 import android.util.AtomicFile; 86 import android.util.Slog; 87 import android.util.SparseArray; 88 import android.util.Xml; 89 90 import com.android.internal.annotations.GuardedBy; 91 import com.android.internal.annotations.VisibleForTesting; 92 import com.android.internal.util.ArrayUtils; 93 import com.android.internal.util.FrameworkStatsLog; 94 import com.android.internal.util.Preconditions; 95 import com.android.modules.utils.TypedXmlPullParser; 96 import com.android.modules.utils.TypedXmlSerializer; 97 import com.android.server.IoThread; 98 import com.android.server.LocalServices; 99 import com.android.server.SystemService; 100 import com.android.server.SystemServiceManager; 101 102 import com.google.android.collect.Lists; 103 import com.google.android.collect.Maps; 104 105 import libcore.io.IoUtils; 106 107 import org.xmlpull.v1.XmlPullParserException; 108 109 import java.io.File; 110 import java.io.FileInputStream; 111 import java.io.FileNotFoundException; 112 import java.io.FileOutputStream; 113 import java.io.IOException; 114 import java.io.PrintWriter; 115 import java.util.ArrayList; 116 import java.util.Collections; 117 import java.util.Iterator; 118 import java.util.List; 119 import java.util.Objects; 120 121 /** Manages uri grants. */ 122 public class UriGrantsManagerService extends IUriGrantsManager.Stub implements 123 UriMetricsHelper.PersistentUriGrantsProvider { 124 private static final boolean DEBUG = false; 125 private static final String TAG = "UriGrantsManagerService"; 126 // Maximum number of persisted Uri grants a package is allowed 127 private static final int MAX_PERSISTED_URI_GRANTS = 512; 128 private static final boolean ENABLE_DYNAMIC_PERMISSIONS = true; 129 130 private final Object mLock = new Object(); 131 private final H mH; 132 ActivityManagerInternal mAmInternal; 133 PackageManagerInternal mPmInternal; 134 UriMetricsHelper mMetricsHelper; 135 136 /** File storing persisted {@link #mGrantedUriPermissions}. */ 137 private final AtomicFile mGrantFile; 138 139 /** XML constants used in {@link #mGrantFile} */ 140 private static final String TAG_URI_GRANTS = "uri-grants"; 141 private static final String TAG_URI_GRANT = "uri-grant"; 142 private static final String ATTR_USER_HANDLE = "userHandle"; 143 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 144 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 145 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 146 private static final String ATTR_TARGET_PKG = "targetPkg"; 147 private static final String ATTR_URI = "uri"; 148 private static final String ATTR_MODE_FLAGS = "modeFlags"; 149 private static final String ATTR_CREATED_TIME = "createdTime"; 150 private static final String ATTR_PREFIX = "prefix"; 151 152 /** 153 * Global set of specific {@link Uri} permissions that have been granted. 154 * This optimized lookup structure maps from {@link UriPermission#targetUid} 155 * to {@link UriPermission#uri} to {@link UriPermission}. 156 */ 157 @GuardedBy("mLock") 158 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 159 mGrantedUriPermissions = new SparseArray<>(); 160 161 /** 162 * Global map of activity launches to sets of passed content URIs. Specifically: 163 * - The caller didn't have read permission to them. 164 * - The callee activity's {@link android.R.attr#requireContentUriPermissionFromCaller} was set 165 * to "none". 166 * 167 * <p>This map is used for logging the ContentOrFileUriEventReported message. 168 * 169 * <p>The launch id is the ActivityStarter.Request#hashCode and has to be received from 170 * ActivityStarter to {@link #checkGrantUriPermissionFromIntentUnlocked(int, String, Intent, 171 * int, NeededUriGrants, int, Integer, Integer)}. 172 */ 173 @GuardedBy("mLaunchToContentUrisWithoutCallerReadPermission") 174 private final SparseArray<ArraySet<Uri>> mLaunchToContentUrisWithoutCallerReadPermission = 175 new SparseArray<>(); 176 UriGrantsManagerService()177 private UriGrantsManagerService() { 178 this(SystemServiceManager.ensureSystemDir(), "uri-grants"); 179 } 180 UriGrantsManagerService(File systemDir, String commitTag)181 private UriGrantsManagerService(File systemDir, String commitTag) { 182 mH = new H(IoThread.get().getLooper()); 183 final File file = new File(systemDir, "urigrants.xml"); 184 mGrantFile = (commitTag != null) ? new AtomicFile(file, commitTag) : new AtomicFile(file); 185 } 186 187 @VisibleForTesting createForTest(File systemDir)188 static UriGrantsManagerService createForTest(File systemDir) { 189 final UriGrantsManagerService service = new UriGrantsManagerService(systemDir, null) { 190 @VisibleForTesting 191 protected int checkUidPermission(String permission, int uid) { 192 // Tests have no permission granted 193 return PackageManager.PERMISSION_DENIED; 194 } 195 196 @VisibleForTesting 197 protected int checkComponentPermission(String permission, int uid, int owningUid, 198 boolean exported) { 199 // Tests have no permission granted 200 return PackageManager.PERMISSION_DENIED; 201 } 202 }; 203 service.mAmInternal = LocalServices.getService(ActivityManagerInternal.class); 204 service.mPmInternal = LocalServices.getService(PackageManagerInternal.class); 205 return service; 206 } 207 208 @VisibleForTesting getLocalService()209 UriGrantsManagerInternal getLocalService() { 210 return new LocalService(); 211 } 212 start()213 private void start() { 214 LocalServices.addService(UriGrantsManagerInternal.class, new LocalService()); 215 } 216 217 public static final class Lifecycle extends SystemService { 218 private final Context mContext; 219 private final UriGrantsManagerService mService; 220 Lifecycle(Context context)221 public Lifecycle(Context context) { 222 super(context); 223 mContext = context; 224 mService = new UriGrantsManagerService(); 225 } 226 227 @Override onStart()228 public void onStart() { 229 publishBinderService(Context.URI_GRANTS_SERVICE, mService); 230 mService.mMetricsHelper = new UriMetricsHelper(mContext, mService); 231 mService.start(); 232 } 233 234 @Override onBootPhase(int phase)235 public void onBootPhase(int phase) { 236 if (phase == PHASE_SYSTEM_SERVICES_READY) { 237 mService.mAmInternal = LocalServices.getService(ActivityManagerInternal.class); 238 mService.mPmInternal = LocalServices.getService(PackageManagerInternal.class); 239 mService.mMetricsHelper.registerPuller(); 240 } 241 } 242 } 243 244 @VisibleForTesting checkUidPermission(String permission, int uid)245 protected int checkUidPermission(String permission, int uid) { 246 try { 247 return AppGlobals.getPackageManager().checkUidPermission(permission, uid); 248 } catch (RemoteException e) { 249 throw e.rethrowFromSystemServer(); 250 } 251 } 252 253 @VisibleForTesting checkComponentPermission(String permission, int uid, int owningUid, boolean exported)254 protected int checkComponentPermission(String permission, int uid, int owningUid, 255 boolean exported) { 256 return ActivityManager.checkComponentPermission(permission, uid, owningUid, exported); 257 } 258 259 /** 260 * Grant uri permissions to the specified app. 261 * 262 * @param token An opaque owner token for tracking the permissions. See 263 * {@link UriGrantsManagerInternal#newUriPermissionOwner}. 264 * @param fromUid The uid of the grantor app that has permissions to the uri. Permissions 265 * will be granted on behalf of this app. 266 * @param targetPkg The package name of the grantor app that has permissions to the uri. 267 * Permissions will be granted on behalf of this app. 268 * @param uri The uri for which permissions should be granted. This uri must NOT contain an 269 * embedded userId; use {@link ContentProvider#getUriWithoutUserId(Uri)} if needed. 270 * @param modeFlags The modes to grant. See {@link Intent#FLAG_GRANT_READ_URI_PERMISSION}, etc. 271 * @param sourceUserId The userId in which the uri is to be resolved. 272 * @param targetUserId The userId of the target app to receive the grant. 273 */ 274 @Override grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, final int modeFlags, int sourceUserId, int targetUserId)275 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 276 Uri uri, final int modeFlags, int sourceUserId, int targetUserId) { 277 grantUriPermissionFromOwnerUnlocked(token, fromUid, targetPkg, uri, modeFlags, sourceUserId, 278 targetUserId); 279 } 280 281 /** 282 * See {@link #grantUriPermissionFromOwner(IBinder, int, String, Uri, int, int, int)}. 283 */ grantUriPermissionFromOwnerUnlocked(@onNull IBinder token, int fromUid, @NonNull String targetPkg, @NonNull Uri uri, final int modeFlags, int sourceUserId, int targetUserId)284 private void grantUriPermissionFromOwnerUnlocked(@NonNull IBinder token, int fromUid, 285 @NonNull String targetPkg, @NonNull Uri uri, final int modeFlags, 286 int sourceUserId, int targetUserId) { 287 targetUserId = mAmInternal.handleIncomingUser(Binder.getCallingPid(), 288 Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY, 289 "grantUriPermissionFromOwner", null); 290 291 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 292 if (owner == null) { 293 throw new IllegalArgumentException("Unknown owner: " + token); 294 } 295 if (fromUid != Binder.getCallingUid()) { 296 if (Binder.getCallingUid() != myUid()) { 297 // Only system code can grant URI permissions on behalf 298 // of other users. 299 throw new SecurityException("nice try"); 300 } 301 } 302 if (targetPkg == null) { 303 throw new IllegalArgumentException("null target"); 304 } 305 if (uri == null) { 306 throw new IllegalArgumentException("null uri"); 307 } 308 309 grantUriPermissionUnlocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, modeFlags), 310 modeFlags, owner, targetUserId); 311 } 312 313 @Override getUriPermissions( String packageName, boolean incoming, boolean persistedOnly)314 public ParceledListSlice<android.content.UriPermission> getUriPermissions( 315 String packageName, boolean incoming, boolean persistedOnly) { 316 enforceNotIsolatedCaller("getUriPermissions"); 317 Objects.requireNonNull(packageName, "packageName"); 318 319 final int callingUid = Binder.getCallingUid(); 320 final int callingUserId = UserHandle.getUserId(callingUid); 321 final PackageManagerInternal pm = LocalServices.getService(PackageManagerInternal.class); 322 final int packageUid = pm.getPackageUid(packageName, 323 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId); 324 if (packageUid != callingUid) { 325 throw new SecurityException( 326 "Package " + packageName + " does not belong to calling UID " + callingUid); 327 } 328 329 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 330 synchronized (mLock) { 331 if (incoming) { 332 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 333 callingUid); 334 if (perms == null) { 335 Slog.w(TAG, "No permission grants found for " + packageName); 336 } else { 337 for (int j = 0; j < perms.size(); j++) { 338 final UriPermission perm = perms.valueAt(j); 339 if (packageName.equals(perm.targetPkg) 340 && (!persistedOnly || perm.persistedModeFlags != 0)) { 341 result.add(perm.buildPersistedPublicApiObject()); 342 } 343 } 344 } 345 } else { 346 final int size = mGrantedUriPermissions.size(); 347 for (int i = 0; i < size; i++) { 348 final ArrayMap<GrantUri, UriPermission> perms = 349 mGrantedUriPermissions.valueAt(i); 350 for (int j = 0; j < perms.size(); j++) { 351 final UriPermission perm = perms.valueAt(j); 352 if (packageName.equals(perm.sourcePkg) 353 && (!persistedOnly || perm.persistedModeFlags != 0)) { 354 result.add(perm.buildPersistedPublicApiObject()); 355 } 356 } 357 } 358 } 359 } 360 return new ParceledListSlice<>(result); 361 } 362 363 @Override getGrantedUriPermissions( @ullable String packageName, int userId)364 public ParceledListSlice<GrantedUriPermission> getGrantedUriPermissions( 365 @Nullable String packageName, int userId) { 366 mAmInternal.enforceCallingPermission( 367 GET_APP_GRANTED_URI_PERMISSIONS, "getGrantedUriPermissions"); 368 369 final List<GrantedUriPermission> result = new ArrayList<>(); 370 synchronized (mLock) { 371 final int size = mGrantedUriPermissions.size(); 372 for (int i = 0; i < size; i++) { 373 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 374 for (int j = 0; j < perms.size(); j++) { 375 final UriPermission perm = perms.valueAt(j); 376 if ((packageName == null || packageName.equals(perm.targetPkg)) 377 && perm.targetUserId == userId 378 && perm.persistedModeFlags != 0) { 379 result.add(perm.buildGrantedUriPermission()); 380 } 381 } 382 } 383 } 384 return new ParceledListSlice<>(result); 385 } 386 387 /** 388 * @param uri This uri must NOT contain an embedded userId. 389 * @param toPackage Name of package whose uri is being granted to (if {@code null}, uses 390 * calling uid) 391 * @param userId The userId in which the uri is to be resolved. 392 */ 393 @Override takePersistableUriPermission(Uri uri, final int modeFlags, @Nullable String toPackage, int userId)394 public void takePersistableUriPermission(Uri uri, final int modeFlags, 395 @Nullable String toPackage, int userId) { 396 final int uid; 397 if (toPackage != null) { 398 mAmInternal.enforceCallingPermission(FORCE_PERSISTABLE_URI_PERMISSIONS, 399 "takePersistableUriPermission"); 400 uid = mPmInternal.getPackageUid(toPackage, 0 /* flags */, userId); 401 } else { 402 enforceNotIsolatedCaller("takePersistableUriPermission"); 403 uid = Binder.getCallingUid(); 404 } 405 406 Preconditions.checkFlagsArgument(modeFlags, 407 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 408 409 synchronized (mLock) { 410 boolean persistChanged = false; 411 412 UriPermission exactPerm = findUriPermissionLocked(uid, 413 new GrantUri(userId, uri, 0)); 414 UriPermission prefixPerm = findUriPermissionLocked(uid, 415 new GrantUri(userId, uri, FLAG_GRANT_PREFIX_URI_PERMISSION)); 416 417 final boolean exactValid = (exactPerm != null) 418 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 419 final boolean prefixValid = (prefixPerm != null) 420 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 421 422 if (!(exactValid || prefixValid)) { 423 throw new SecurityException("No persistable permission grants found for UID " 424 + uid + " and Uri " + uri.toSafeString()); 425 } 426 427 if (exactValid) { 428 persistChanged |= exactPerm.takePersistableModes(modeFlags); 429 } 430 if (prefixValid) { 431 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 432 } 433 434 persistChanged |= maybePrunePersistedUriGrantsLocked(uid); 435 436 if (persistChanged) { 437 schedulePersistUriGrants(); 438 } 439 } 440 } 441 442 @Override clearGrantedUriPermissions(String packageName, int userId)443 public void clearGrantedUriPermissions(String packageName, int userId) { 444 mAmInternal.enforceCallingPermission( 445 CLEAR_APP_GRANTED_URI_PERMISSIONS, "clearGrantedUriPermissions"); 446 synchronized (mLock) { 447 removeUriPermissionsForPackageLocked(packageName, userId, true, true); 448 } 449 } 450 451 /** 452 * @param uri This uri must NOT contain an embedded userId. 453 * @param toPackage Name of the target package whose uri is being released (if {@code null}, 454 * uses calling uid) 455 * @param userId The userId in which the uri is to be resolved. 456 */ 457 @Override releasePersistableUriPermission(Uri uri, final int modeFlags, @Nullable String toPackage, int userId)458 public void releasePersistableUriPermission(Uri uri, final int modeFlags, 459 @Nullable String toPackage, int userId) { 460 461 final int uid; 462 if (toPackage != null) { 463 mAmInternal.enforceCallingPermission(FORCE_PERSISTABLE_URI_PERMISSIONS, 464 "releasePersistableUriPermission"); 465 uid = mPmInternal.getPackageUid(toPackage, 0 /* flags */ , userId); 466 } else { 467 enforceNotIsolatedCaller("releasePersistableUriPermission"); 468 uid = Binder.getCallingUid(); 469 } 470 471 Preconditions.checkFlagsArgument(modeFlags, 472 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 473 474 synchronized (mLock) { 475 boolean persistChanged = false; 476 477 UriPermission exactPerm = findUriPermissionLocked(uid, 478 new GrantUri(userId, uri, 0)); 479 UriPermission prefixPerm = findUriPermissionLocked(uid, 480 new GrantUri(userId, uri, FLAG_GRANT_PREFIX_URI_PERMISSION)); 481 if (exactPerm == null && prefixPerm == null && toPackage == null) { 482 throw new SecurityException("No permission grants found for UID " + uid 483 + " and Uri " + uri.toSafeString()); 484 } 485 486 if (exactPerm != null) { 487 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 488 removeUriPermissionIfNeededLocked(exactPerm); 489 } 490 if (prefixPerm != null) { 491 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 492 removeUriPermissionIfNeededLocked(prefixPerm); 493 } 494 495 if (persistChanged) { 496 schedulePersistUriGrants(); 497 } 498 } 499 } 500 501 /** 502 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 503 * given package. 504 * 505 * @param packageName Package name to match, or {@code null} to apply to all 506 * packages. 507 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 508 * to all users. 509 * @param persistable If persistable grants should be removed. 510 * @param targetOnly When {@code true}, only remove permissions where the app is the target, 511 * not source. 512 */ 513 @GuardedBy("mLock") removeUriPermissionsForPackageLocked(String packageName, int userHandle, boolean persistable, boolean targetOnly)514 private void removeUriPermissionsForPackageLocked(String packageName, int userHandle, 515 boolean persistable, boolean targetOnly) { 516 if (userHandle == UserHandle.USER_ALL && packageName == null) { 517 throw new IllegalArgumentException("Must narrow by either package or user"); 518 } 519 520 boolean persistChanged = false; 521 522 int N = mGrantedUriPermissions.size(); 523 for (int i = 0; i < N; i++) { 524 final int targetUid = mGrantedUriPermissions.keyAt(i); 525 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 526 527 // Only inspect grants matching user 528 if (userHandle == UserHandle.USER_ALL 529 || userHandle == UserHandle.getUserId(targetUid)) { 530 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 531 final UriPermission perm = it.next(); 532 533 // Only inspect grants matching package 534 if (packageName == null || (!targetOnly && perm.sourcePkg.equals(packageName)) 535 || perm.targetPkg.equals(packageName)) { 536 // Hacky solution as part of fixing a security bug; ignore 537 // grants associated with DownloadManager so we don't have 538 // to immediately launch it to regrant the permissions 539 if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority()) 540 && !persistable) continue; 541 542 persistChanged |= perm.revokeModes(persistable 543 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 544 545 // Only remove when no modes remain; any persisted grants 546 // will keep this alive. 547 if (perm.modeFlags == 0) { 548 it.remove(); 549 } 550 } 551 } 552 553 if (perms.isEmpty()) { 554 mGrantedUriPermissions.remove(targetUid); 555 N--; 556 i--; 557 } 558 } 559 } 560 561 if (persistChanged) { 562 schedulePersistUriGrants(); 563 } 564 } 565 566 /** Returns if the ContentProvider has granted a uri to callingUid */ 567 @GuardedBy("mLock") checkAuthorityGrantsLocked(int callingUid, ProviderInfo cpi, int userId, boolean checkUser)568 private boolean checkAuthorityGrantsLocked(int callingUid, ProviderInfo cpi, int userId, 569 boolean checkUser) { 570 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 571 if (perms != null) { 572 for (int i = perms.size() - 1; i >= 0; i--) { 573 GrantUri grantUri = perms.keyAt(i); 574 if (grantUri.sourceUserId == userId || !checkUser) { 575 if (matchesProvider(grantUri.uri, cpi)) { 576 return true; 577 } 578 } 579 } 580 } 581 return false; 582 } 583 584 /** Returns true if the uri authority is one of the authorities specified in the provider. */ matchesProvider(Uri uri, ProviderInfo cpi)585 private boolean matchesProvider(Uri uri, ProviderInfo cpi) { 586 String uriAuth = uri.getAuthority(); 587 String cpiAuth = cpi.authority; 588 if (cpiAuth.indexOf(';') == -1) { 589 return cpiAuth.equals(uriAuth); 590 } 591 String[] cpiAuths = cpiAuth.split(";"); 592 int length = cpiAuths.length; 593 for (int i = 0; i < length; i++) { 594 if (cpiAuths[i].equals(uriAuth)) return true; 595 } 596 return false; 597 } 598 599 /** 600 * Prune any older {@link UriPermission} for the given UID until outstanding 601 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 602 * 603 * @return if any mutations occured that require persisting. 604 */ 605 @GuardedBy("mLock") maybePrunePersistedUriGrantsLocked(int uid)606 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 607 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 608 if (perms == null) return false; 609 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 610 611 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 612 for (UriPermission perm : perms.values()) { 613 if (perm.persistedModeFlags != 0) { 614 persisted.add(perm); 615 } 616 } 617 618 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 619 if (trimCount <= 0) return false; 620 621 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 622 for (int i = 0; i < trimCount; i++) { 623 final UriPermission perm = persisted.get(i); 624 625 if (DEBUG) Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 626 627 perm.releasePersistableModes(~0); 628 removeUriPermissionIfNeededLocked(perm); 629 } 630 631 return true; 632 } 633 634 /** Like checkGrantUriPermission, but takes an Intent. */ checkGrantUriPermissionFromIntentUnlocked(int callingUid, String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId, @RequiredContentUriPermission Integer requireContentUriPermissionFromCaller, Integer requestHashCode)635 private NeededUriGrants checkGrantUriPermissionFromIntentUnlocked(int callingUid, 636 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId, 637 @RequiredContentUriPermission Integer requireContentUriPermissionFromCaller, 638 Integer requestHashCode) { 639 if (DEBUG) Slog.v(TAG, 640 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 641 + " clip=" + (intent != null ? intent.getClipData() : null) 642 + " from " + intent + "; flags=0x" 643 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 644 645 if (targetPkg == null) { 646 throw new NullPointerException("targetPkg"); 647 } 648 649 if (intent == null) { 650 return null; 651 } 652 653 // Default userId for uris in the intent (if they don't specify it themselves) 654 int contentUserHint = intent.getContentUserHint(); 655 if (contentUserHint == UserHandle.USER_CURRENT) { 656 contentUserHint = UserHandle.getUserId(callingUid); 657 } 658 659 if (android.security.Flags.contentUriPermissionApis()) { 660 enforceRequireContentUriPermissionFromCallerOnIntentExtraStreamUnlocked(intent, 661 contentUserHint, mode, callingUid, requireContentUriPermissionFromCaller, 662 requestHashCode); 663 } 664 665 Uri data = intent.getData(); 666 ClipData clip = intent.getClipData(); 667 if (data == null && clip == null) { 668 return null; 669 } 670 671 int targetUid; 672 if (needed != null) { 673 targetUid = needed.targetUid; 674 } else { 675 targetUid = mPmInternal.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, 676 targetUserId); 677 if (targetUid < 0) { 678 if (DEBUG) Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 679 + " on user " + targetUserId); 680 return null; 681 } 682 } 683 if (data != null) { 684 GrantUri grantUri = GrantUri.resolve(contentUserHint, data, mode); 685 if (android.security.Flags.contentUriPermissionApis()) { 686 enforceRequireContentUriPermissionFromCallerUnlocked( 687 requireContentUriPermissionFromCaller, grantUri, callingUid, 688 requestHashCode); 689 } 690 targetUid = checkGrantUriPermissionUnlocked(callingUid, targetPkg, grantUri, mode, 691 targetUid); 692 if (targetUid > 0) { 693 if (needed == null) { 694 needed = new NeededUriGrants(targetPkg, targetUid, mode); 695 } 696 needed.uris.add(grantUri); 697 } 698 } 699 if (clip != null) { 700 for (int i=0; i<clip.getItemCount(); i++) { 701 Uri uri = clip.getItemAt(i).getUri(); 702 if (uri != null) { 703 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri, mode); 704 if (android.security.Flags.contentUriPermissionApis()) { 705 enforceRequireContentUriPermissionFromCallerUnlocked( 706 requireContentUriPermissionFromCaller, grantUri, callingUid, 707 requestHashCode); 708 } 709 targetUid = checkGrantUriPermissionUnlocked(callingUid, targetPkg, 710 grantUri, mode, targetUid); 711 if (targetUid > 0) { 712 if (needed == null) { 713 needed = new NeededUriGrants(targetPkg, targetUid, mode); 714 } 715 needed.uris.add(grantUri); 716 } 717 } else { 718 Intent clipIntent = clip.getItemAt(i).getIntent(); 719 if (clipIntent != null) { 720 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentUnlocked( 721 callingUid, targetPkg, clipIntent, mode, needed, targetUserId, 722 requireContentUriPermissionFromCaller, requestHashCode); 723 if (newNeeded != null) { 724 needed = newNeeded; 725 } 726 } 727 } 728 } 729 } 730 731 return needed; 732 } 733 enforceRequireContentUriPermissionFromCallerUnlocked( @equiredContentUriPermission Integer requireContentUriPermissionFromCaller, GrantUri grantUri, int callingUid, Integer requestHashCode)734 private void enforceRequireContentUriPermissionFromCallerUnlocked( 735 @RequiredContentUriPermission Integer requireContentUriPermissionFromCaller, 736 GrantUri grantUri, int callingUid, Integer requestHashCode) { 737 // Exit early if requireContentUriPermissionFromCaller hasn't been set or the URI is a 738 // non-content URI. 739 if (requireContentUriPermissionFromCaller == null 740 || requireContentUriPermissionFromCaller == CONTENT_URI_PERMISSION_NONE 741 || !ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 742 tryAddingContentUriWithoutCallerReadPermissionWhenAttributeIsNoneUnlocked( 743 requireContentUriPermissionFromCaller, grantUri, callingUid, requestHashCode); 744 return; 745 } 746 747 final boolean hasPermission = hasRequireContentUriPermissionFromCallerUnlocked( 748 requireContentUriPermissionFromCaller, grantUri, callingUid); 749 750 if (!hasPermission) { 751 throw new SecurityException("You can't launch this activity because you don't have the" 752 + " required " + ActivityInfo.requiredContentUriPermissionToShortString( 753 requireContentUriPermissionFromCaller) + " access to " + grantUri.uri); 754 } 755 } 756 hasRequireContentUriPermissionFromCallerUnlocked( @equiredContentUriPermission Integer requireContentUriPermissionFromCaller, GrantUri grantUri, int uid)757 private boolean hasRequireContentUriPermissionFromCallerUnlocked( 758 @RequiredContentUriPermission Integer requireContentUriPermissionFromCaller, 759 GrantUri grantUri, int uid) { 760 final boolean readMet = !isRequiredContentUriPermissionRead( 761 requireContentUriPermissionFromCaller) 762 || checkContentUriPermissionFullUnlocked(grantUri, uid, 763 Intent.FLAG_GRANT_READ_URI_PERMISSION); 764 765 final boolean writeMet = !isRequiredContentUriPermissionWrite( 766 requireContentUriPermissionFromCaller) 767 || checkContentUriPermissionFullUnlocked(grantUri, uid, 768 Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 769 770 return requireContentUriPermissionFromCaller == CONTENT_URI_PERMISSION_READ_OR_WRITE 771 ? (readMet || writeMet) : (readMet && writeMet); 772 } 773 tryAddingContentUriWithoutCallerReadPermissionWhenAttributeIsNoneUnlocked( @equiredContentUriPermission Integer requireContentUriPermissionFromCaller, GrantUri grantUri, int callingUid, Integer requestHashCode)774 private void tryAddingContentUriWithoutCallerReadPermissionWhenAttributeIsNoneUnlocked( 775 @RequiredContentUriPermission Integer requireContentUriPermissionFromCaller, 776 GrantUri grantUri, int callingUid, Integer requestHashCode) { 777 // We're interested in requireContentUriPermissionFromCaller that is set to 778 // CONTENT_URI_PERMISSION_NONE and content URIs. Hence, ignore if 779 // requireContentUriPermissionFromCaller is not set to CONTENT_URI_PERMISSION_NONE or the 780 // URI is a non-content URI. 781 if (requireContentUriPermissionFromCaller == null 782 || requireContentUriPermissionFromCaller != CONTENT_URI_PERMISSION_NONE 783 || !ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme()) 784 || requestHashCode == null) { 785 return; 786 } 787 788 if (!hasRequireContentUriPermissionFromCallerUnlocked(CONTENT_URI_PERMISSION_READ, grantUri, 789 callingUid)) { 790 synchronized (mLaunchToContentUrisWithoutCallerReadPermission) { 791 if (mLaunchToContentUrisWithoutCallerReadPermission.get(requestHashCode) == null) { 792 mLaunchToContentUrisWithoutCallerReadPermission 793 .put(requestHashCode, new ArraySet<>()); 794 } 795 mLaunchToContentUrisWithoutCallerReadPermission.get(requestHashCode) 796 .add(grantUri.uri); 797 } 798 } 799 } 800 enforceRequireContentUriPermissionFromCallerOnIntentExtraStreamUnlocked( Intent intent, int contentUserHint, int mode, int callingUid, @RequiredContentUriPermission Integer requireContentUriPermissionFromCaller, Integer requestHashCode)801 private void enforceRequireContentUriPermissionFromCallerOnIntentExtraStreamUnlocked( 802 Intent intent, int contentUserHint, int mode, int callingUid, 803 @RequiredContentUriPermission Integer requireContentUriPermissionFromCaller, 804 Integer requestHashCode) { 805 try { 806 final Uri uri = intent.getParcelableExtra(Intent.EXTRA_STREAM, Uri.class); 807 if (uri != null) { 808 final GrantUri grantUri = GrantUri.resolve(contentUserHint, uri, mode); 809 enforceRequireContentUriPermissionFromCallerUnlocked( 810 requireContentUriPermissionFromCaller, grantUri, callingUid, 811 requestHashCode); 812 } 813 } catch (BadParcelableException e) { 814 Slog.w(TAG, "Failed to unparcel an URI in EXTRA_STREAM, skipping" 815 + " requireContentUriPermissionFromCaller: " + e); 816 } 817 818 try { 819 final ArrayList<Uri> uris = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM, 820 Uri.class); 821 if (uris != null) { 822 for (int i = uris.size() - 1; i >= 0; i--) { 823 final GrantUri grantUri = GrantUri.resolve(contentUserHint, uris.get(i), mode); 824 enforceRequireContentUriPermissionFromCallerUnlocked( 825 requireContentUriPermissionFromCaller, grantUri, callingUid, 826 requestHashCode); 827 } 828 } 829 } catch (BadParcelableException e) { 830 Slog.w(TAG, "Failed to unparcel an ArrayList of URIs in EXTRA_STREAM, skipping" 831 + " requireContentUriPermissionFromCaller: " + e); 832 } 833 } 834 notifyActivityLaunchRequestCompletedUnlocked(Integer requestHashCode, boolean isSuccessfulLaunch, String intentAction, int callingUid, String callingActivityName, int calleeUid, String calleeActivityName, boolean isStartActivityForResult)835 private void notifyActivityLaunchRequestCompletedUnlocked(Integer requestHashCode, 836 boolean isSuccessfulLaunch, String intentAction, int callingUid, 837 String callingActivityName, int calleeUid, String calleeActivityName, 838 boolean isStartActivityForResult) { 839 ArraySet<Uri> contentUris; 840 synchronized (mLaunchToContentUrisWithoutCallerReadPermission) { 841 contentUris = mLaunchToContentUrisWithoutCallerReadPermission.get(requestHashCode); 842 mLaunchToContentUrisWithoutCallerReadPermission.remove(requestHashCode); 843 } 844 if (!isSuccessfulLaunch || contentUris == null) return; 845 846 final String[] authorities = new String[contentUris.size()]; 847 final String[] schemes = new String[contentUris.size()]; 848 for (int i = contentUris.size() - 1; i >= 0; i--) { 849 Uri uri = contentUris.valueAt(i); 850 authorities[i] = uri.getAuthority(); 851 schemes[i] = uri.getScheme(); 852 } 853 FrameworkStatsLog.write(CONTENT_OR_FILE_URI_EVENT_REPORTED, 854 CONTENT_OR_FILE_URI_EVENT_REPORTED__EVENT_TYPE__CONTENT_URI_WITHOUT_CALLER_READ_PERMISSION, 855 intentAction, 856 callingUid, 857 callingActivityName, 858 calleeUid, 859 calleeActivityName, 860 isStartActivityForResult, 861 String.join(",", authorities), 862 String.join(",", schemes), 863 /* uri_mime_type */ null); 864 } 865 866 @GuardedBy("mLock") readGrantedUriPermissionsLocked()867 private void readGrantedUriPermissionsLocked() { 868 if (DEBUG) Slog.v(TAG, "readGrantedUriPermissions()"); 869 870 final long now = System.currentTimeMillis(); 871 872 FileInputStream fis = null; 873 try { 874 fis = mGrantFile.openRead(); 875 final TypedXmlPullParser in = Xml.resolvePullParser(fis); 876 877 int type; 878 while ((type = in.next()) != END_DOCUMENT) { 879 final String tag = in.getName(); 880 if (type == START_TAG) { 881 if (TAG_URI_GRANT.equals(tag)) { 882 final int sourceUserId; 883 final int targetUserId; 884 final int userHandle = in.getAttributeInt(null, ATTR_USER_HANDLE, 885 UserHandle.USER_NULL); 886 if (userHandle != UserHandle.USER_NULL) { 887 // For backwards compatibility. 888 sourceUserId = userHandle; 889 targetUserId = userHandle; 890 } else { 891 sourceUserId = in.getAttributeInt(null, ATTR_SOURCE_USER_ID); 892 targetUserId = in.getAttributeInt(null, ATTR_TARGET_USER_ID); 893 } 894 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 895 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 896 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 897 final boolean prefix = in.getAttributeBoolean(null, ATTR_PREFIX, false); 898 final int modeFlags = in.getAttributeInt(null, ATTR_MODE_FLAGS); 899 final long createdTime = in.getAttributeLong(null, ATTR_CREATED_TIME, now); 900 901 // Validity check that provider still belongs to source package 902 // Both direct boot aware and unaware packages are fine as we 903 // will do filtering at query time to avoid multiple parsing. 904 final ProviderInfo pi = getProviderInfo(uri.getAuthority(), sourceUserId, 905 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, SYSTEM_UID); 906 if (pi != null && sourcePkg.equals(pi.packageName)) { 907 int targetUid = mPmInternal.getPackageUid( 908 targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId); 909 if (targetUid != -1) { 910 final GrantUri grantUri = new GrantUri(sourceUserId, uri, 911 prefix ? Intent.FLAG_GRANT_PREFIX_URI_PERMISSION : 0); 912 final UriPermission perm = findOrCreateUriPermissionLocked( 913 sourcePkg, targetPkg, targetUid, grantUri); 914 perm.initPersistedModes(modeFlags, createdTime); 915 mPmInternal.grantImplicitAccess( 916 targetUserId, null /* intent */, 917 UserHandle.getAppId(targetUid), 918 pi.applicationInfo.uid, 919 false /* direct */, true /* retainOnUpdate */); 920 } 921 } else { 922 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 923 + " but instead found " + pi); 924 } 925 } 926 } 927 } 928 } catch (FileNotFoundException e) { 929 // Missing grants is okay 930 } catch (IOException e) { 931 Slog.wtf(TAG, "Failed reading Uri grants", e); 932 } catch (XmlPullParserException e) { 933 Slog.wtf(TAG, "Failed reading Uri grants", e); 934 } finally { 935 IoUtils.closeQuietly(fis); 936 } 937 } 938 939 @GuardedBy("mLock") findOrCreateUriPermissionLocked(String sourcePkg, String targetPkg, int targetUid, GrantUri grantUri)940 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 941 String targetPkg, int targetUid, GrantUri grantUri) { 942 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 943 if (targetUris == null) { 944 targetUris = Maps.newArrayMap(); 945 mGrantedUriPermissions.put(targetUid, targetUris); 946 } 947 948 UriPermission perm = targetUris.get(grantUri); 949 if (perm == null) { 950 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 951 targetUris.put(grantUri, perm); 952 } 953 954 return perm; 955 } 956 grantUriPermissionUnchecked(int targetUid, String targetPkg, GrantUri grantUri, final int modeFlags, UriPermissionOwner owner)957 private void grantUriPermissionUnchecked(int targetUid, String targetPkg, GrantUri grantUri, 958 final int modeFlags, UriPermissionOwner owner) { 959 if (!Intent.isAccessUriMode(modeFlags)) { 960 return; 961 } 962 963 // So here we are: the caller has the assumed permission to the uri, and the target doesn't. 964 // Let's now give this to the target. 965 966 if (DEBUG) Slog.v(TAG, 967 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 968 969 // Unchecked call, passing the system's uid as the calling uid to the getProviderInfo 970 final String authority = grantUri.uri.getAuthority(); 971 final ProviderInfo pi = getProviderInfo(authority, grantUri.sourceUserId, 972 MATCH_DEBUG_TRIAGED_MISSING, SYSTEM_UID); 973 if (pi == null) { 974 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 975 return; 976 } 977 978 final UriPermission perm; 979 synchronized (mLock) { 980 perm = findOrCreateUriPermissionLocked(pi.packageName, targetPkg, targetUid, grantUri); 981 } 982 perm.grantModes(modeFlags, owner); 983 mPmInternal.grantImplicitAccess(UserHandle.getUserId(targetUid), null /*intent*/, 984 UserHandle.getAppId(targetUid), pi.applicationInfo.uid, false /*direct*/, 985 (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0); 986 } 987 988 /** Like grantUriPermissionUnchecked, but takes an Intent. */ grantUriPermissionUncheckedFromIntent(NeededUriGrants needed, UriPermissionOwner owner)989 private void grantUriPermissionUncheckedFromIntent(NeededUriGrants needed, 990 UriPermissionOwner owner) { 991 if (needed == null) { 992 return; 993 } 994 final int N = needed.uris.size(); 995 for (int i = 0; i < N; i++) { 996 grantUriPermissionUnchecked(needed.targetUid, needed.targetPkg, 997 needed.uris.valueAt(i), needed.flags, owner); 998 } 999 } 1000 grantUriPermissionUnlocked(int callingUid, String targetPkg, GrantUri grantUri, final int modeFlags, UriPermissionOwner owner, int targetUserId)1001 private void grantUriPermissionUnlocked(int callingUid, String targetPkg, GrantUri grantUri, 1002 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 1003 if (targetPkg == null) { 1004 throw new NullPointerException("targetPkg"); 1005 } 1006 int targetUid = mPmInternal.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, 1007 targetUserId); 1008 1009 targetUid = checkGrantUriPermissionUnlocked(callingUid, targetPkg, grantUri, modeFlags, 1010 targetUid); 1011 if (targetUid < 0) { 1012 return; 1013 } 1014 1015 grantUriPermissionUnchecked(targetUid, targetPkg, grantUri, modeFlags, owner); 1016 } 1017 revokeUriPermission(String targetPackage, int callingUid, GrantUri grantUri, final int modeFlags)1018 private void revokeUriPermission(String targetPackage, int callingUid, GrantUri grantUri, 1019 final int modeFlags) { 1020 if (DEBUG) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 1021 1022 final String authority = grantUri.uri.getAuthority(); 1023 final ProviderInfo pi = getProviderInfo(authority, grantUri.sourceUserId, 1024 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUid); 1025 if (pi == null) { 1026 Slog.w(TAG, "No content provider found for permission revoke: " 1027 + grantUri.toSafeString()); 1028 return; 1029 } 1030 1031 final boolean callerHoldsPermissions = checkHoldingPermissionsUnlocked(pi, grantUri, 1032 callingUid, modeFlags); 1033 synchronized (mLock) { 1034 revokeUriPermissionLocked(targetPackage, callingUid, grantUri, modeFlags, 1035 callerHoldsPermissions); 1036 } 1037 } 1038 1039 @GuardedBy("mLock") revokeUriPermissionLocked(String targetPackage, int callingUid, GrantUri grantUri, final int modeFlags, final boolean callerHoldsPermissions)1040 private void revokeUriPermissionLocked(String targetPackage, int callingUid, GrantUri grantUri, 1041 final int modeFlags, final boolean callerHoldsPermissions) { 1042 // Does the caller have this permission on the URI? 1043 if (!callerHoldsPermissions) { 1044 // If they don't have direct access to the URI, then revoke any 1045 // ownerless URI permissions that have been granted to them. 1046 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 1047 if (perms != null) { 1048 boolean persistChanged = false; 1049 for (int i = perms.size()-1; i >= 0; i--) { 1050 final UriPermission perm = perms.valueAt(i); 1051 if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) { 1052 continue; 1053 } 1054 if (perm.uri.sourceUserId == grantUri.sourceUserId 1055 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 1056 if (DEBUG) Slog.v(TAG, "Revoking non-owned " 1057 + perm.targetUid + " permission to " + perm.uri); 1058 persistChanged |= perm.revokeModes( 1059 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false); 1060 if (perm.modeFlags == 0) { 1061 perms.removeAt(i); 1062 } 1063 } 1064 } 1065 if (perms.isEmpty()) { 1066 mGrantedUriPermissions.remove(callingUid); 1067 } 1068 if (persistChanged) { 1069 schedulePersistUriGrants(); 1070 } 1071 } 1072 return; 1073 } 1074 1075 boolean persistChanged = false; 1076 1077 // Go through all of the permissions and remove any that match. 1078 for (int i = mGrantedUriPermissions.size()-1; i >= 0; i--) { 1079 final int targetUid = mGrantedUriPermissions.keyAt(i); 1080 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 1081 1082 for (int j = perms.size()-1; j >= 0; j--) { 1083 final UriPermission perm = perms.valueAt(j); 1084 if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) { 1085 continue; 1086 } 1087 if (perm.uri.sourceUserId == grantUri.sourceUserId 1088 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 1089 if (DEBUG) Slog.v(TAG, 1090 "Revoking " + perm.targetUid + " permission to " + perm.uri); 1091 persistChanged |= perm.revokeModes( 1092 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, 1093 targetPackage == null); 1094 if (perm.modeFlags == 0) { 1095 perms.removeAt(j); 1096 } 1097 } 1098 } 1099 1100 if (perms.isEmpty()) { 1101 mGrantedUriPermissions.removeAt(i); 1102 } 1103 } 1104 1105 if (persistChanged) { 1106 schedulePersistUriGrants(); 1107 } 1108 } 1109 1110 /** 1111 * Determine if UID is holding permissions required to access {@link Uri} in 1112 * the given {@link ProviderInfo}. Final permission checking is always done 1113 * in {@link ContentProvider}. 1114 */ checkHoldingPermissionsUnlocked( ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags)1115 private boolean checkHoldingPermissionsUnlocked( 1116 ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 1117 if (DEBUG) Slog.v(TAG, "checkHoldingPermissions: uri=" + grantUri + " uid=" + uid); 1118 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 1119 if (checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) 1120 != PERMISSION_GRANTED) { 1121 return false; 1122 } 1123 } 1124 return checkHoldingPermissionsInternalUnlocked(pi, grantUri, uid, modeFlags, true); 1125 } 1126 checkHoldingPermissionsInternalUnlocked(ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions)1127 private boolean checkHoldingPermissionsInternalUnlocked(ProviderInfo pi, 1128 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 1129 // We must never hold our local mLock in this method, since we may need 1130 // to call into ActivityManager for dynamic permission checks 1131 if (Thread.holdsLock(mLock)) { 1132 throw new IllegalStateException("Must never hold local mLock"); 1133 } 1134 1135 if (pi.applicationInfo.uid == uid) { 1136 return true; 1137 } else if (!pi.exported) { 1138 return false; 1139 } 1140 1141 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 1142 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 1143 1144 // check if target holds top-level <provider> permissions 1145 if (!readMet && pi.readPermission != null && considerUidPermissions 1146 && (checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 1147 readMet = true; 1148 } 1149 if (!writeMet && pi.writePermission != null && considerUidPermissions 1150 && (checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 1151 writeMet = true; 1152 } 1153 1154 // track if unprotected read/write is allowed; any denied 1155 // <path-permission> below removes this ability 1156 boolean allowDefaultRead = pi.readPermission == null; 1157 boolean allowDefaultWrite = pi.writePermission == null; 1158 1159 // check if target holds any <path-permission> that match uri 1160 final PathPermission[] pps = pi.pathPermissions; 1161 if (pps != null) { 1162 final String path = grantUri.uri.getPath(); 1163 int i = pps.length; 1164 while (i > 0 && (!readMet || !writeMet)) { 1165 i--; 1166 PathPermission pp = pps[i]; 1167 if (pp.match(path)) { 1168 if (!readMet) { 1169 final String pprperm = pp.getReadPermission(); 1170 if (DEBUG) Slog.v(TAG, 1171 "Checking read perm for " + pprperm + " for " + pp.getPath() 1172 + ": match=" + pp.match(path) 1173 + " check=" + checkUidPermission(pprperm, uid)); 1174 if (pprperm != null) { 1175 if (considerUidPermissions && checkUidPermission(pprperm, uid) 1176 == PERMISSION_GRANTED) { 1177 readMet = true; 1178 } else { 1179 allowDefaultRead = false; 1180 } 1181 } 1182 } 1183 if (!writeMet) { 1184 final String ppwperm = pp.getWritePermission(); 1185 if (DEBUG) Slog.v(TAG, 1186 "Checking write perm " + ppwperm + " for " + pp.getPath() 1187 + ": match=" + pp.match(path) 1188 + " check=" + checkUidPermission(ppwperm, uid)); 1189 if (ppwperm != null) { 1190 if (considerUidPermissions && checkUidPermission(ppwperm, uid) 1191 == PERMISSION_GRANTED) { 1192 writeMet = true; 1193 } else { 1194 allowDefaultWrite = false; 1195 } 1196 } 1197 } 1198 } 1199 } 1200 } 1201 1202 // grant unprotected <provider> read/write, if not blocked by 1203 // <path-permission> above 1204 if (allowDefaultRead) readMet = true; 1205 if (allowDefaultWrite) writeMet = true; 1206 1207 // If this provider says that grants are always required, we need to 1208 // consult it directly to determine if the UID has permission 1209 final boolean forceMet; 1210 if (ENABLE_DYNAMIC_PERMISSIONS && pi.forceUriPermissions) { 1211 final int providerUserId = UserHandle.getUserId(pi.applicationInfo.uid); 1212 final int clientUserId = UserHandle.getUserId(uid); 1213 if (providerUserId == clientUserId) { 1214 forceMet = (mAmInternal.checkContentProviderUriPermission(grantUri.uri, 1215 providerUserId, uid, modeFlags) == PackageManager.PERMISSION_GRANTED); 1216 } else { 1217 // The provider can't track cross-user permissions, so we have 1218 // to assume they're always denied 1219 forceMet = false; 1220 } 1221 } else { 1222 forceMet = true; 1223 } 1224 1225 return readMet && writeMet && forceMet; 1226 } 1227 1228 @GuardedBy("mLock") removeUriPermissionIfNeededLocked(UriPermission perm)1229 private void removeUriPermissionIfNeededLocked(UriPermission perm) { 1230 if (perm.modeFlags != 0) { 1231 return; 1232 } 1233 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 1234 perm.targetUid); 1235 if (perms == null) { 1236 return; 1237 } 1238 if (DEBUG) Slog.v(TAG, "Removing " + perm.targetUid + " permission to " + perm.uri); 1239 1240 perms.remove(perm.uri); 1241 if (perms.isEmpty()) { 1242 mGrantedUriPermissions.remove(perm.targetUid); 1243 } 1244 } 1245 1246 @GuardedBy("mLock") findUriPermissionLocked(int targetUid, GrantUri grantUri)1247 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 1248 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 1249 if (targetUris != null) { 1250 return targetUris.get(grantUri); 1251 } 1252 return null; 1253 } 1254 schedulePersistUriGrants()1255 private void schedulePersistUriGrants() { 1256 if (!mH.hasMessages(PERSIST_URI_GRANTS_MSG)) { 1257 mH.sendMessageDelayed(mH.obtainMessage(PERSIST_URI_GRANTS_MSG), 1258 10 * DateUtils.SECOND_IN_MILLIS); 1259 } 1260 } 1261 enforceNotIsolatedCaller(String caller)1262 private void enforceNotIsolatedCaller(String caller) { 1263 if (UserHandle.isIsolated(Binder.getCallingUid())) { 1264 throw new SecurityException("Isolated process not allowed to call " + caller); 1265 } 1266 } 1267 getProviderInfo(String authority, int userHandle, int pmFlags, int callingUid)1268 private ProviderInfo getProviderInfo(String authority, int userHandle, int pmFlags, 1269 int callingUid) { 1270 return mPmInternal.resolveContentProvider(authority, 1271 PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags, userHandle, callingUid); 1272 } 1273 1274 /** 1275 * Check if the targetPkg can be granted permission to access uri by 1276 * the callingUid using the given modeFlags. Throws a security exception 1277 * if callingUid is not allowed to do this. Returns the uid of the target 1278 * if the URI permission grant should be performed; returns -1 if it is not 1279 * needed (for example targetPkg already has permission to access the URI). 1280 * If you already know the uid of the target, you can supply it in 1281 * lastTargetUid else set that to -1. 1282 */ checkGrantUriPermissionUnlocked(int callingUid, String targetPkg, GrantUri grantUri, int modeFlags, int lastTargetUid)1283 private int checkGrantUriPermissionUnlocked(int callingUid, String targetPkg, GrantUri grantUri, 1284 int modeFlags, int lastTargetUid) { 1285 if (!isContentUriWithAccessModeFlags(grantUri, modeFlags, 1286 /* logAction */ "grant URI permission")) { 1287 return -1; 1288 } 1289 1290 if (targetPkg != null) { 1291 if (DEBUG) Slog.v(TAG, "Checking grant " + targetPkg + " permission to " + grantUri); 1292 } 1293 1294 // Bail early if system is trying to hand out permissions directly; it 1295 // must always grant permissions on behalf of someone explicit. 1296 final int callingAppId = UserHandle.getAppId(callingUid); 1297 if ((callingAppId == SYSTEM_UID) || (callingAppId == ROOT_UID)) { 1298 if ("com.android.settings.files".equals(grantUri.uri.getAuthority()) 1299 || "com.android.settings.module_licenses".equals(grantUri.uri.getAuthority())) { 1300 // Exempted authority for 1301 // 1. cropping user photos and sharing a generated license html 1302 // file in Settings app 1303 // 2. sharing a generated license html file in TvSettings app 1304 // 3. Sharing module license files from Settings app 1305 } else { 1306 Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission" 1307 + " grant to " + grantUri + "; use startActivityAsCaller() instead"); 1308 return -1; 1309 } 1310 } 1311 1312 final String authority = grantUri.uri.getAuthority(); 1313 final ProviderInfo pi = getProviderInfo(authority, grantUri.sourceUserId, 1314 MATCH_DIRECT_BOOT_AUTO, callingUid); 1315 if (pi == null) { 1316 Slog.w(TAG, "No content provider found for permission check: " + 1317 grantUri.uri.toSafeString()); 1318 return -1; 1319 } 1320 1321 int targetUid = lastTargetUid; 1322 if (targetUid < 0 && targetPkg != null) { 1323 targetUid = mPmInternal.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, 1324 UserHandle.getUserId(callingUid)); 1325 if (targetUid < 0) { 1326 if (DEBUG) Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg); 1327 return -1; 1328 } 1329 } 1330 1331 boolean targetHoldsPermission = false; 1332 if (targetUid >= 0) { 1333 // First... does the target actually need this permission? 1334 if (checkHoldingPermissionsUnlocked(pi, grantUri, targetUid, modeFlags)) { 1335 // No need to grant the target this permission. 1336 if (DEBUG) Slog.v(TAG, 1337 "Target " + targetPkg + " already has full permission to " + grantUri); 1338 targetHoldsPermission = true; 1339 } 1340 } else { 1341 // First... there is no target package, so can anyone access it? 1342 boolean allowed = pi.exported; 1343 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 1344 if (pi.readPermission != null) { 1345 allowed = false; 1346 } 1347 } 1348 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 1349 if (pi.writePermission != null) { 1350 allowed = false; 1351 } 1352 } 1353 if (pi.pathPermissions != null) { 1354 final int N = pi.pathPermissions.length; 1355 for (int i=0; i<N; i++) { 1356 if (pi.pathPermissions[i] != null 1357 && pi.pathPermissions[i].match(grantUri.uri.getPath())) { 1358 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 1359 if (pi.pathPermissions[i].getReadPermission() != null) { 1360 allowed = false; 1361 } 1362 } 1363 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 1364 if (pi.pathPermissions[i].getWritePermission() != null) { 1365 allowed = false; 1366 } 1367 } 1368 break; 1369 } 1370 } 1371 } 1372 if (allowed) { 1373 targetHoldsPermission = true; 1374 } 1375 } 1376 1377 if (pi.forceUriPermissions) { 1378 // When provider requires dynamic permission checks, the only 1379 // way to be safe is to issue permission grants for each item by 1380 // assuming no generic access 1381 targetHoldsPermission = false; 1382 } 1383 1384 final boolean basicGrant = (modeFlags 1385 & (FLAG_GRANT_PERSISTABLE_URI_PERMISSION | FLAG_GRANT_PREFIX_URI_PERMISSION)) == 0; 1386 if (basicGrant && targetHoldsPermission) { 1387 // When caller holds permission, and this is a simple permission 1388 // grant, we can skip generating any bookkeeping; when any advanced 1389 // features have been requested, we proceed below to make sure the 1390 // provider supports granting permissions 1391 mPmInternal.grantImplicitAccess( 1392 UserHandle.getUserId(targetUid), null, 1393 UserHandle.getAppId(targetUid), pi.applicationInfo.uid, false /*direct*/); 1394 return -1; 1395 } 1396 1397 /* There is a special cross user grant if: 1398 * - The target is on another user. 1399 * - Apps on the current user can access the uri without any uid permissions. 1400 * In this case, we grant a uri permission, even if the ContentProvider does not normally 1401 * grant uri permissions. 1402 */ 1403 boolean specialCrossUserGrant = targetUid >= 0 1404 && UserHandle.getUserId(targetUid) != grantUri.sourceUserId 1405 && checkHoldingPermissionsInternalUnlocked(pi, grantUri, callingUid, 1406 modeFlags, false /*without considering the uid permissions*/); 1407 1408 // Second... is the provider allowing granting of URI permissions? 1409 boolean grantAllowed = pi.grantUriPermissions; 1410 if (!ArrayUtils.isEmpty(pi.uriPermissionPatterns)) { 1411 final int N = pi.uriPermissionPatterns.length; 1412 grantAllowed = false; 1413 for (int i = 0; i < N; i++) { 1414 if (pi.uriPermissionPatterns[i] != null 1415 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 1416 grantAllowed = true; 1417 break; 1418 } 1419 } 1420 } 1421 if (!grantAllowed) { 1422 if (specialCrossUserGrant) { 1423 // We're only okay issuing basic grant access across user 1424 // boundaries; advanced flags are blocked here 1425 if (!basicGrant) { 1426 throw new SecurityException("Provider " + pi.packageName 1427 + "/" + pi.name 1428 + " does not allow granting of advanced Uri permissions (uri " 1429 + grantUri + ")"); 1430 } 1431 } else { 1432 throw new SecurityException("Provider " + pi.packageName 1433 + "/" + pi.name 1434 + " does not allow granting of Uri permissions (uri " 1435 + grantUri + ")"); 1436 } 1437 } 1438 1439 // Third... does the caller itself have permission to access this uri? 1440 if (!checkHoldingPermissionsUnlocked(pi, grantUri, callingUid, modeFlags)) { 1441 // Require they hold a strong enough Uri permission 1442 final boolean res; 1443 synchronized (mLock) { 1444 res = checkUriPermissionLocked(grantUri, callingUid, modeFlags); 1445 } 1446 if (!res) { 1447 if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(pi.readPermission)) { 1448 throw new SecurityException( 1449 "UID " + callingUid + " does not have permission to " + grantUri 1450 + "; you could obtain access using ACTION_OPEN_DOCUMENT " 1451 + "or related APIs"); 1452 } else { 1453 throw new SecurityException( 1454 "UID " + callingUid + " does not have permission to " + grantUri); 1455 } 1456 } 1457 } 1458 1459 return targetUid; 1460 } 1461 isContentUriWithAccessModeFlags(GrantUri grantUri, int modeFlags, String logAction)1462 private boolean isContentUriWithAccessModeFlags(GrantUri grantUri, int modeFlags, 1463 String logAction) { 1464 if (!Intent.isAccessUriMode(modeFlags)) { 1465 if (DEBUG) Slog.v(TAG, "Mode flags are not access URI mode flags: " + modeFlags); 1466 return false; 1467 } 1468 1469 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 1470 if (DEBUG) { 1471 Slog.v(TAG, "Can't " + logAction + " on non-content URI: " + grantUri); 1472 } 1473 return false; 1474 } 1475 1476 return true; 1477 } 1478 1479 /** Check if the uid has permission to the content URI in grantUri. */ checkContentUriPermissionFullUnlocked(GrantUri grantUri, int uid, int modeFlags)1480 private boolean checkContentUriPermissionFullUnlocked(GrantUri grantUri, int uid, 1481 int modeFlags) { 1482 if (uid < 0) { 1483 throw new IllegalArgumentException("Uid must be positive for the content URI " 1484 + "permission check of " + grantUri.uri.toSafeString()); 1485 } 1486 1487 if (!isContentUriWithAccessModeFlags(grantUri, modeFlags, 1488 /* logAction */ "check content URI permission")) { 1489 throw new IllegalArgumentException("The URI must be a content URI and the mode " 1490 + "flags must be at least read and/or write for the content URI permission " 1491 + "check of " + grantUri.uri.toSafeString()); 1492 } 1493 1494 final int appId = UserHandle.getAppId(uid); 1495 if ((appId == SYSTEM_UID) || (appId == ROOT_UID)) { 1496 return true; 1497 } 1498 1499 // Retrieve the URI's content provider 1500 final String authority = grantUri.uri.getAuthority(); 1501 ProviderInfo pi = getProviderInfo(authority, grantUri.sourceUserId, MATCH_DIRECT_BOOT_AUTO, 1502 uid); 1503 1504 if (pi == null) { 1505 Slog.w(TAG, "No content provider found for content URI permission check: " 1506 + grantUri.uri.toSafeString()); 1507 return false; 1508 } 1509 1510 // Check if it has general permission to the URI's content provider 1511 if (checkHoldingPermissionsUnlocked(pi, grantUri, uid, modeFlags)) { 1512 return true; 1513 } 1514 1515 // Check if it has explicitly granted permissions to the URI 1516 synchronized (mLock) { 1517 return checkUriPermissionLocked(grantUri, uid, modeFlags); 1518 } 1519 } 1520 1521 /** 1522 * @param userId The userId in which the uri is to be resolved. 1523 */ checkGrantUriPermissionUnlocked(int callingUid, String targetPkg, Uri uri, int modeFlags, int userId)1524 private int checkGrantUriPermissionUnlocked(int callingUid, String targetPkg, Uri uri, 1525 int modeFlags, int userId) { 1526 return checkGrantUriPermissionUnlocked(callingUid, targetPkg, 1527 new GrantUri(userId, uri, modeFlags), modeFlags, -1); 1528 } 1529 1530 @GuardedBy("mLock") checkUriPermissionLocked(GrantUri grantUri, int uid, final int modeFlags)1531 private boolean checkUriPermissionLocked(GrantUri grantUri, int uid, final int modeFlags) { 1532 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 1533 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 1534 : UriPermission.STRENGTH_OWNED; 1535 1536 // Root gets to do everything. 1537 if (uid == 0) { 1538 return true; 1539 } 1540 1541 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 1542 if (perms == null) return false; 1543 1544 // First look for exact match 1545 final UriPermission exactPerm = perms.get(grantUri); 1546 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 1547 return true; 1548 } 1549 1550 // No exact match, look for prefixes 1551 final int N = perms.size(); 1552 for (int i = 0; i < N; i++) { 1553 final UriPermission perm = perms.valueAt(i); 1554 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 1555 && perm.getStrength(modeFlags) >= minStrength) { 1556 return true; 1557 } 1558 } 1559 1560 return false; 1561 } 1562 1563 /** 1564 * Check if the targetPkg can be granted permission to access uri by 1565 * the callingUid using the given modeFlags. See {@link #checkGrantUriPermissionUnlocked}. 1566 * 1567 * @param callingUid The uid of the grantor app that has permissions to the uri. 1568 * @param targetPkg The package name of the granted app that needs permissions to the uri. 1569 * @param uri The uri for which permissions should be granted. 1570 * @param modeFlags The modes to grant. See {@link Intent#FLAG_GRANT_READ_URI_PERMISSION}, etc. 1571 * @param userId The userId in which the uri is to be resolved. 1572 * @return uid of the target or -1 if permission grant not required. Returns -1 if the caller 1573 * does not hold INTERACT_ACROSS_USERS_FULL 1574 * @throws SecurityException if the grant is not allowed. 1575 */ 1576 @Override 1577 @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) checkGrantUriPermission_ignoreNonSystem(int callingUid, String targetPkg, Uri uri, int modeFlags, int userId)1578 public int checkGrantUriPermission_ignoreNonSystem(int callingUid, String targetPkg, Uri uri, 1579 int modeFlags, int userId) { 1580 if (!isCallerIsSystemOrPrivileged()) { 1581 return Process.INVALID_UID; 1582 } 1583 final long origId = Binder.clearCallingIdentity(); 1584 try { 1585 return checkGrantUriPermissionUnlocked(callingUid, targetPkg, uri, modeFlags, 1586 userId); 1587 } finally { 1588 Binder.restoreCallingIdentity(origId); 1589 } 1590 } 1591 isCallerIsSystemOrPrivileged()1592 private boolean isCallerIsSystemOrPrivileged() { 1593 final int uid = Binder.getCallingUid(); 1594 if (uid == Process.SYSTEM_UID || uid == Process.ROOT_UID) { 1595 return true; 1596 } 1597 return checkComponentPermission( 1598 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 1599 uid, /* owningUid = */-1, /* exported = */ true) 1600 == PackageManager.PERMISSION_GRANTED; 1601 } 1602 1603 @Override providePersistentUriGrants()1604 public ArrayList<UriPermission> providePersistentUriGrants() { 1605 final ArrayList<UriPermission> result = new ArrayList<>(); 1606 1607 synchronized (mLock) { 1608 final int size = mGrantedUriPermissions.size(); 1609 for (int i = 0; i < size; i++) { 1610 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 1611 1612 final int permissionsForPackageSize = perms.size(); 1613 for (int j = 0; j < permissionsForPackageSize; j++) { 1614 final UriPermission permission = perms.valueAt(j); 1615 1616 if (permission.persistedModeFlags != 0) { 1617 result.add(permission); 1618 } 1619 } 1620 } 1621 } 1622 1623 return result; 1624 } 1625 writeGrantedUriPermissions()1626 private void writeGrantedUriPermissions() { 1627 if (DEBUG) Slog.v(TAG, "writeGrantedUriPermissions()"); 1628 1629 final long startTime = SystemClock.uptimeMillis(); 1630 1631 int persistentUriPermissionsCount = 0; 1632 1633 // Snapshot permissions so we can persist without lock 1634 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 1635 synchronized (mLock) { 1636 final int size = mGrantedUriPermissions.size(); 1637 for (int i = 0; i < size; i++) { 1638 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 1639 1640 final int permissionsForPackageSize = perms.size(); 1641 for (int j = 0; j < permissionsForPackageSize; j++) { 1642 final UriPermission permission = perms.valueAt(j); 1643 1644 if (permission.persistedModeFlags != 0) { 1645 persistentUriPermissionsCount++; 1646 persist.add(permission.snapshot()); 1647 } 1648 } 1649 } 1650 } 1651 1652 FileOutputStream fos = null; 1653 try { 1654 fos = mGrantFile.startWrite(startTime); 1655 1656 TypedXmlSerializer out = Xml.resolveSerializer(fos); 1657 out.startDocument(null, true); 1658 out.startTag(null, TAG_URI_GRANTS); 1659 for (UriPermission.Snapshot perm : persist) { 1660 out.startTag(null, TAG_URI_GRANT); 1661 out.attributeInt(null, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 1662 out.attributeInt(null, ATTR_TARGET_USER_ID, perm.targetUserId); 1663 out.attributeInterned(null, ATTR_SOURCE_PKG, perm.sourcePkg); 1664 out.attributeInterned(null, ATTR_TARGET_PKG, perm.targetPkg); 1665 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 1666 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 1667 out.attributeInt(null, ATTR_MODE_FLAGS, perm.persistedModeFlags); 1668 out.attributeLong(null, ATTR_CREATED_TIME, perm.persistedCreateTime); 1669 out.endTag(null, TAG_URI_GRANT); 1670 } 1671 out.endTag(null, TAG_URI_GRANTS); 1672 out.endDocument(); 1673 1674 mGrantFile.finishWrite(fos); 1675 } catch (IOException e) { 1676 if (fos != null) { 1677 mGrantFile.failWrite(fos); 1678 } 1679 } 1680 1681 mMetricsHelper.reportPersistentUriFlushed(persistentUriPermissionsCount); 1682 } 1683 1684 final class H extends Handler { 1685 static final int PERSIST_URI_GRANTS_MSG = 1; 1686 H(Looper looper)1687 public H(Looper looper) { 1688 super(looper, null, true); 1689 } 1690 1691 @Override handleMessage(Message msg)1692 public void handleMessage(Message msg) { 1693 switch (msg.what) { 1694 case PERSIST_URI_GRANTS_MSG: { 1695 writeGrantedUriPermissions(); 1696 break; 1697 } 1698 } 1699 } 1700 } 1701 1702 private final class LocalService implements UriGrantsManagerInternal { 1703 @Override removeUriPermissionIfNeeded(UriPermission perm)1704 public void removeUriPermissionIfNeeded(UriPermission perm) { 1705 synchronized (mLock) { 1706 UriGrantsManagerService.this.removeUriPermissionIfNeededLocked(perm); 1707 } 1708 } 1709 1710 @Override revokeUriPermission(String targetPackage, int callingUid, GrantUri grantUri, int modeFlags)1711 public void revokeUriPermission(String targetPackage, int callingUid, GrantUri grantUri, 1712 int modeFlags) { 1713 UriGrantsManagerService.this.revokeUriPermission( 1714 targetPackage, callingUid, grantUri, modeFlags); 1715 } 1716 1717 @Override checkUriPermission(GrantUri grantUri, int uid, int modeFlags, boolean isFullAccessForContentUri)1718 public boolean checkUriPermission(GrantUri grantUri, int uid, int modeFlags, 1719 boolean isFullAccessForContentUri) { 1720 if (isFullAccessForContentUri) { 1721 return UriGrantsManagerService.this.checkContentUriPermissionFullUnlocked(grantUri, 1722 uid, modeFlags); 1723 } 1724 synchronized (mLock) { 1725 return UriGrantsManagerService.this.checkUriPermissionLocked(grantUri, uid, 1726 modeFlags); 1727 } 1728 } 1729 1730 @Override checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, int modeFlags, int userId)1731 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, int modeFlags, 1732 int userId) { 1733 enforceNotIsolatedCaller("checkGrantUriPermission"); 1734 return UriGrantsManagerService.this.checkGrantUriPermissionUnlocked( 1735 callingUid, targetPkg, uri, modeFlags, userId); 1736 } 1737 1738 @Override checkGrantUriPermissionFromIntent(Intent intent, int callingUid, String targetPkg, int targetUserId)1739 public NeededUriGrants checkGrantUriPermissionFromIntent(Intent intent, int callingUid, 1740 String targetPkg, int targetUserId) { 1741 return internalCheckGrantUriPermissionFromIntent(intent, callingUid, targetPkg, 1742 targetUserId, /* requireContentUriPermissionFromCaller */ null, 1743 /* requestHashCode */ null); 1744 } 1745 1746 @Override checkGrantUriPermissionFromIntent(Intent intent, int callingUid, String targetPkg, int targetUserId, int requireContentUriPermissionFromCaller, int requestHashCode)1747 public NeededUriGrants checkGrantUriPermissionFromIntent(Intent intent, int callingUid, 1748 String targetPkg, int targetUserId, int requireContentUriPermissionFromCaller, 1749 int requestHashCode) { 1750 return internalCheckGrantUriPermissionFromIntent(intent, callingUid, targetPkg, 1751 targetUserId, requireContentUriPermissionFromCaller, requestHashCode); 1752 } 1753 1754 @Override notifyActivityLaunchRequestCompleted(int requestHashCode, boolean isSuccessfulLaunch, String intentAction, int callingUid, String callingActivityName, int calleeUid, String calleeActivityName, boolean isStartActivityForResult)1755 public void notifyActivityLaunchRequestCompleted(int requestHashCode, 1756 boolean isSuccessfulLaunch, String intentAction, int callingUid, 1757 String callingActivityName, int calleeUid, String calleeActivityName, 1758 boolean isStartActivityForResult) { 1759 UriGrantsManagerService.this.notifyActivityLaunchRequestCompletedUnlocked( 1760 requestHashCode, isSuccessfulLaunch, intentAction, callingUid, 1761 callingActivityName, calleeUid, calleeActivityName, 1762 isStartActivityForResult); 1763 } 1764 internalCheckGrantUriPermissionFromIntent(Intent intent, int callingUid, String targetPkg, int targetUserId, @Nullable Integer requireContentUriPermissionFromCaller, Integer requestHashCode)1765 private NeededUriGrants internalCheckGrantUriPermissionFromIntent(Intent intent, 1766 int callingUid, String targetPkg, int targetUserId, 1767 @Nullable Integer requireContentUriPermissionFromCaller, Integer requestHashCode) { 1768 final int mode = (intent != null) ? intent.getFlags() : 0; 1769 return UriGrantsManagerService.this.checkGrantUriPermissionFromIntentUnlocked( 1770 callingUid, targetPkg, intent, mode, null, targetUserId, 1771 requireContentUriPermissionFromCaller, requestHashCode); 1772 } 1773 1774 @Override grantUriPermissionUncheckedFromIntent(NeededUriGrants needed, UriPermissionOwner owner)1775 public void grantUriPermissionUncheckedFromIntent(NeededUriGrants needed, 1776 UriPermissionOwner owner) { 1777 UriGrantsManagerService.this.grantUriPermissionUncheckedFromIntent(needed, owner); 1778 } 1779 1780 @Override onSystemReady()1781 public void onSystemReady() { 1782 synchronized (mLock) { 1783 UriGrantsManagerService.this.readGrantedUriPermissionsLocked(); 1784 } 1785 } 1786 1787 @Override newUriPermissionOwner(String name)1788 public IBinder newUriPermissionOwner(String name) { 1789 enforceNotIsolatedCaller("newUriPermissionOwner"); 1790 UriPermissionOwner owner = new UriPermissionOwner(this, name); 1791 return owner.getExternalToken(); 1792 } 1793 1794 @Override removeUriPermissionsForPackage(String packageName, int userHandle, boolean persistable, boolean targetOnly)1795 public void removeUriPermissionsForPackage(String packageName, int userHandle, 1796 boolean persistable, boolean targetOnly) { 1797 synchronized (mLock) { 1798 UriGrantsManagerService.this.removeUriPermissionsForPackageLocked( 1799 packageName, userHandle, persistable, targetOnly); 1800 } 1801 } 1802 1803 @Override revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId)1804 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 1805 revokeUriPermissionFromOwner(token, uri, mode, userId, null, UserHandle.USER_ALL); 1806 } 1807 1808 @Override revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId, String targetPkg, int targetUserId)1809 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId, 1810 String targetPkg, int targetUserId) { 1811 final UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 1812 if (owner == null) { 1813 throw new IllegalArgumentException("Unknown owner: " + token); 1814 } 1815 GrantUri grantUri = uri == null ? null : new GrantUri(userId, uri, mode); 1816 owner.removeUriPermission(grantUri, mode, targetPkg, targetUserId); 1817 } 1818 1819 @Override checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser)1820 public boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, 1821 boolean checkUser) { 1822 synchronized (mLock) { 1823 return UriGrantsManagerService.this.checkAuthorityGrantsLocked( 1824 callingUid, cpi, userId, checkUser); 1825 } 1826 } 1827 1828 @Override dump(PrintWriter pw, boolean dumpAll, String dumpPackage)1829 public void dump(PrintWriter pw, boolean dumpAll, String dumpPackage) { 1830 synchronized (mLock) { 1831 boolean needSep = false; 1832 boolean printedAnything = false; 1833 if (mGrantedUriPermissions.size() > 0) { 1834 boolean printed = false; 1835 int dumpUid = -2; 1836 if (dumpPackage != null) { 1837 dumpUid = mPmInternal.getPackageUid(dumpPackage, 1838 MATCH_ANY_USER, 0 /* userId */); 1839 } 1840 for (int i = 0; i < mGrantedUriPermissions.size(); i++) { 1841 int uid = mGrantedUriPermissions.keyAt(i); 1842 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 1843 continue; 1844 } 1845 final ArrayMap<GrantUri, UriPermission> perms = 1846 mGrantedUriPermissions.valueAt(i); 1847 if (!printed) { 1848 if (needSep) pw.println(); 1849 needSep = true; 1850 pw.println(" Granted Uri Permissions:"); 1851 printed = true; 1852 printedAnything = true; 1853 } 1854 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 1855 for (UriPermission perm : perms.values()) { 1856 pw.print(" "); pw.println(perm); 1857 if (dumpAll) { 1858 perm.dump(pw, " "); 1859 } 1860 } 1861 } 1862 } 1863 1864 if (!printedAnything) { 1865 pw.println(" (nothing)"); 1866 } 1867 } 1868 } 1869 } 1870 } 1871