Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 80f74b54 authored by Nicolas Prevot's avatar Nicolas Prevot
Browse files

Splitting the different authorities of a content provider

So that sharing from contacts works across user.
When getting a contentProvider, checking that read/write permissions are not null,

Change-Id: Ib4f0419aebd9ec4e742ef08c9ed9348fde62cc11
parent dd59aba6
Loading
Loading
Loading
Loading
+47 −22
Original line number Diff line number Diff line
@@ -7942,21 +7942,15 @@ public final class ActivityManagerService extends ActivityManagerNative
            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
        // Looking for cross-user grants before to enforce the typical cross-users permissions
        if (userId != UserHandle.getUserId(callingUid)) {
            if (perms != null) {
                for (GrantUri grantUri : perms.keySet()) {
                    if (grantUri.sourceUserId == userId) {
                        String authority = grantUri.uri.getAuthority();
                        if (authority.equals(cpi.authority)) {
        boolean checkedGrants = false;
        if (checkUser) {
            // Looking for cross-user grants before enforcing the typical cross-users permissions
            if (UserHandle.getUserId(callingUid) != userId) {
                if (checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
                    return null;
                }
                checkedGrants = true;
            }
                }
            }
        }
        if (checkUser) {
            userId = handleIncomingUser(callingPid, callingUid, userId,
                    false, true, "checkContentProviderPermissionLocked " + cpi.authority, null);
        }
@@ -7977,26 +7971,23 @@ public final class ActivityManagerService extends ActivityManagerNative
            while (i > 0) {
                i--;
                PathPermission pp = pps[i];
                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
                String pprperm = pp.getReadPermission();
                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
                        cpi.applicationInfo.uid, cpi.exported)
                        == PackageManager.PERMISSION_GRANTED) {
                    return null;
                }
                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
                String ppwperm = pp.getWritePermission();
                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
                        cpi.applicationInfo.uid, cpi.exported)
                        == PackageManager.PERMISSION_GRANTED) {
                    return null;
                }
            }
        }
        if (perms != null) {
            for (GrantUri grantUri : perms.keySet()) {
                if (grantUri.uri.getAuthority().equals(cpi.authority)) {
        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
            return null;
        }
            }
        }
        String msg;
        if (!cpi.exported) {
@@ -8014,6 +8005,40 @@ public final class ActivityManagerService extends ActivityManagerNative
        return msg;
    }
    /**
     * Returns if the ContentProvider has granted a uri to callingUid
     */
    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
        if (perms != null) {
            for (GrantUri grantUri : perms.keySet()) {
                if (grantUri.sourceUserId == userId || !checkUser) {
                    if (matchesProvider(grantUri.uri, cpi)) {
                        return true;
                    }
                }
            }
        }
        return false;
    }
    /**
     * Returns true if the uri authority is one of the authorities specified in the provider.
     */
    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
        String uriAuth = uri.getAuthority();
        String cpiAuth = cpi.authority;
        if (cpiAuth.indexOf(';') == -1) {
            return cpiAuth.equals(uriAuth);
        }
        String[] cpiAuths = cpiAuth.split(";");
        int length = cpiAuths.length;
        for (int i = 0; i < length; i++) {
            if (cpiAuths[i].equals(uriAuth)) return true;
        }
        return false;
    }
    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
        if (r != null) {