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