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