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

Commit e0c4b0b2 authored by Himanshu Gupta's avatar Himanshu Gupta
Browse files

Allowing content uris with parentUserId to be accessed by cloned user.

In ag/21547694 we added a change to allow content uris with clonedUserId
to be accessible from parentUser.
In this change we fix the reverse part of the flow, by skipping
cross-profile user checks in such cases.

Bug: 283399640
Test: Manual verification on device
Change-Id: Iddf10be61480fd2e9daaa288dca44bc64ebc4308
parent e2c13430
Loading
Loading
Loading
Loading
+33 −4
Original line number Diff line number Diff line
@@ -96,7 +96,9 @@ import com.android.server.sdksandbox.SdkSandboxManagerLocal;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
@@ -116,6 +118,8 @@ public class ContentProviderHelper {
    private final ProviderMap mProviderMap;
    private boolean mSystemProvidersInstalled;

    private final Map<String, Boolean> mCloneProfileAuthorityRedirectionCache = new HashMap<>();

    ContentProviderHelper(ActivityManagerService service, boolean createProviderMap) {
        mService = service;
        mProviderMap = createProviderMap ? new ProviderMap(mService) : null;
@@ -201,9 +205,24 @@ public class ContentProviderHelper {
            final UserProperties userProps = umInternal.getUserProperties(userId);
            final boolean isMediaSharedWithParent =
                    userProps != null && userProps.isMediaSharedWithParent();
            if (!isAuthorityRedirectedForCloneProfile(name) || !isMediaSharedWithParent) {
            if (!isAuthorityRedirectedForCloneProfileCached(name) || !isMediaSharedWithParent) {
                // First check if this content provider has been published...
                cpr = mProviderMap.getProviderByName(name, userId);
                // In case we are on media authority and callingUid is cloned app asking to access
                // the contentProvider of user 0 by specifying content as
                // content://<parent-id>@media/external/file, we skip checkUser.
                if (isAuthorityRedirectedForCloneProfileCached(name)) {
                    final int callingUserId = UserHandle.getUserId(callingUid);
                    final UserProperties userPropsCallingUser =
                            umInternal.getUserProperties(callingUserId);
                    final boolean isMediaSharedWithParentForCallingUser =
                            userPropsCallingUser != null
                                    && userPropsCallingUser.isMediaSharedWithParent();
                    if (isMediaSharedWithParentForCallingUser
                            && umInternal.getProfileParentId(callingUserId) == userId) {
                        checkCrossUser = false;
                    }
                }
            }
            // If that didn't work, check if it exists for user 0 and then
            // verify that it's a singleton provider before using it.
@@ -218,7 +237,7 @@ public class ContentProviderHelper {
                                        r == null ? callingUid : r.uid, cpi.applicationInfo.uid)) {
                        userId = UserHandle.USER_SYSTEM;
                        checkCrossUser = false;
                    } else if (isAuthorityRedirectedForCloneProfile(name)) {
                    } else if (isAuthorityRedirectedForCloneProfileCached(name)) {
                        if (isMediaSharedWithParent) {
                            userId = umInternal.getProfileParentId(userId);
                            checkCrossUser = false;
@@ -1073,7 +1092,7 @@ public class ContentProviderHelper {
            return false;
        }

        if (isAuthorityRedirectedForCloneProfile(holder.info.authority)
        if (isAuthorityRedirectedForCloneProfileCached(holder.info.authority)
                && resolveParentUserIdForCloneProfile(userId) != userId) {
            // Since clone profile shares certain providers with its parent and the access is
            // re-directed as well, the holder may not actually be installed on the clone profile.
@@ -1108,7 +1127,7 @@ public class ContentProviderHelper {
            userId = UserHandle.getCallingUserId();
        }

        if (isAuthorityRedirectedForCloneProfile(authority)) {
        if (isAuthorityRedirectedForCloneProfileCached(authority)) {
            UserManagerInternal umInternal = LocalServices.getService(UserManagerInternal.class);
            UserInfo userInfo = umInternal.getUserInfo(userId);

@@ -1954,4 +1973,14 @@ public class ContentProviderHelper {
            String[] args) {
        return mProviderMap.dumpProviderProto(fd, pw, name, args);
    }

    private Boolean isAuthorityRedirectedForCloneProfileCached(String auth) {
        if (mCloneProfileAuthorityRedirectionCache.containsKey(auth)) {
            return mCloneProfileAuthorityRedirectionCache.get(auth);
        } else {
            boolean isAuthRedirected = isAuthorityRedirectedForCloneProfile(auth);
            mCloneProfileAuthorityRedirectionCache.put(auth, isAuthRedirected);
            return isAuthRedirected;
        }
    }
}