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