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

Commit 145c8f80 authored by Sunny Goyal's avatar Sunny Goyal
Browse files

Using UserManagerInternal for access control instead of UserManager

Bug: 36067387
Test: for C in {1..10}; do adb shell am instrument -e class com.android.server.pm.ShortcutManagerTest$C \
      -w com.android.frameworks.servicestests/android.support.test.runner.AndroidJUnitRunner; done
      atest CtsDevicePolicyManagerTestCases:LauncherAppsSingleUserTest \
            CtsDevicePolicyManagerTestCases:LauncherAppsProfileTest \
            CtsDevicePolicyManagerTestCases:LauncherAppsMultiUserTest
      atest CtsShortcutManagerTestCases
Change-Id: Ia4ddea58f66861ef760865b6d8831563584f85c9
parent 94e5d34d
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
@@ -186,4 +186,24 @@ public abstract class UserManagerInternal {
     * @return the array of user ids.
     */
    public abstract int[] getUserIds();

    /**
     * Checks if the {@code callingUserId} and {@code targetUserId} are same or in same group
     * and that the {@code callingUserId} is not a managed profile and
     * {@code targetUserId} is enabled.
     *
     * @return TRUE if the {@code callingUserId} can access {@code targetUserId}. FALSE
     * otherwise
     *
     * @throws SecurityException if the calling user and {@code targetUser} are not in the same
     * group and {@code throwSecurityException} is true, otherwise if will simply return false.
     */
    public abstract boolean isProfileAccessible(int callingUserId, int targetUserId,
            String debugMsg, boolean throwSecurityException);

    /**
     * If {@code userId} is of a managed profile, return the parent user ID. Otherwise return
     * itself.
     */
    public abstract int getProfileParentId(int userId);
}
+31 −142

File changed.

Preview size limit exceeded, changes collapsed.

+6 −16
Original line number Diff line number Diff line
@@ -77,7 +77,7 @@ import android.os.ShellCallback;
import android.os.ShellCommand;
import android.os.SystemClock;
import android.os.UserHandle;
import android.os.UserManager;
import android.os.UserManagerInternal;
import android.text.TextUtils;
import android.text.format.Time;
import android.util.ArraySet;
@@ -315,7 +315,7 @@ public class ShortcutService extends IShortcutService.Stub {

    private final IPackageManager mIPackageManager;
    private final PackageManagerInternal mPackageManagerInternal;
    private final UserManager mUserManager;
    private final UserManagerInternal mUserManagerInternal;
    private final UsageStatsManagerInternal mUsageStatsManagerInternal;
    private final ActivityManagerInternal mActivityManagerInternal;

@@ -430,7 +430,8 @@ public class ShortcutService extends IShortcutService.Stub {
        mIPackageManager = AppGlobals.getPackageManager();
        mPackageManagerInternal = Preconditions.checkNotNull(
                LocalServices.getService(PackageManagerInternal.class));
        mUserManager = Preconditions.checkNotNull(context.getSystemService(UserManager.class));
        mUserManagerInternal = Preconditions.checkNotNull(
                LocalServices.getService(UserManagerInternal.class));
        mUsageStatsManagerInternal = Preconditions.checkNotNull(
                LocalServices.getService(UsageStatsManagerInternal.class));
        mActivityManagerInternal = Preconditions.checkNotNull(
@@ -1176,12 +1177,7 @@ public class ShortcutService extends IShortcutService.Stub {
        // the user might just have been unlocked.
        // Note we just don't use isUserUnlockingOrUnlocked() here, because it'll return false
        // when the user is STOPPING, which we still want to consider as "unlocked".
        final long token = injectClearCallingIdentity();
        try {
            return mUserManager.isUserUnlockingOrUnlocked(userId);
        } finally {
            injectRestoreCallingIdentity(token);
        }
        return mUserManagerInternal.isUserUnlockingOrUnlocked(userId);
    }

    // Requires mLock held, but "Locked" prefix would look weired so we jsut say "L".
@@ -3494,13 +3490,7 @@ public class ShortcutService extends IShortcutService.Stub {
     * itself.
     */
    int getParentOrSelfUserId(int userId) {
        final long token = injectClearCallingIdentity();
        try {
            final UserInfo parent = mUserManager.getProfileParent(userId);
            return (parent != null) ? parent.id : userId;
        } finally {
            injectRestoreCallingIdentity(token);
        }
        return mUserManagerInternal.getProfileParentId(userId);
    }

    void injectSendIntentSender(IntentSender intentSender, Intent extras) {
+51 −8
Original line number Diff line number Diff line
@@ -781,14 +781,7 @@ public class UserManagerService extends IUserManager.Stub {
    @Override
    public int getProfileParentId(int userHandle) {
        checkManageUsersPermission("get the profile parent");
        synchronized (mUsersLock) {
            UserInfo profileParent = getProfileParentLU(userHandle);
            if (profileParent == null) {
                return userHandle;
            }

            return profileParent.id;
        }
        return mLocalService.getProfileParentId(userHandle);
    }

    private UserInfo getProfileParentLU(int userHandle) {
@@ -3928,6 +3921,56 @@ public class UserManagerService extends IUserManager.Stub {
        public boolean exists(int userId) {
            return getUserInfoNoChecks(userId) != null;
        }

        @Override
        public boolean isProfileAccessible(int callingUserId, int targetUserId, String debugMsg,
                boolean throwSecurityException) {
            if (targetUserId == callingUserId) {
                return true;
            }
            synchronized (mUsersLock) {
                UserInfo callingUserInfo = getUserInfoLU(callingUserId);
                if (callingUserInfo == null || callingUserInfo.isManagedProfile()) {
                    if (throwSecurityException) {
                        throw new SecurityException(
                                debugMsg + " for another profile "
                                        + targetUserId + " from " + callingUserId);
                    }
                }

                UserInfo targetUserInfo = getUserInfoLU(targetUserId);
                if (targetUserInfo == null || !targetUserInfo.isEnabled()) {
                    // Do not throw any exception here as this could happen due to race conditions
                    // between the system updating its state and the client getting notified.
                    if (throwSecurityException) {
                        Slog.w(LOG_TAG, debugMsg + " for disabled profile "
                                + targetUserId + " from " + callingUserId);
                    }
                    return false;
                }

                if (targetUserInfo.profileGroupId == UserInfo.NO_PROFILE_GROUP_ID ||
                        targetUserInfo.profileGroupId != callingUserInfo.profileGroupId) {
                    if (throwSecurityException) {
                        throw new SecurityException(
                                debugMsg + " for unrelated profile " + targetUserId);
                    }
                    return false;
                }
            }
            return true;
        }

        @Override
        public int getProfileParentId(int userId) {
            synchronized (mUsersLock) {
                UserInfo profileParent = getProfileParentLU(userId);
                if (profileParent == null) {
                    return userId;
                }
                return profileParent.id;
            }
        }
    }

    /* Remove all the users except of the system one. */
+39 −50

File changed.

Preview size limit exceeded, changes collapsed.