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

Commit e70b29e8 authored by Makoto Onuki's avatar Makoto Onuki
Browse files

Fix launcher apps reverse access

Trying to access other profiles from work profile shouldn't throw
security exception.

This is a partial revert of Ia4ddea58f66861ef760865b6d8831563584f85c9.

(Technically we should check the target user-id too, but that part isn't a
regression, so I'm not fixing that part.)

Bug: 77260666
Change-Id: I3f1f6584fcd6b879943d85ab4678b6130def0ba3
Fixes: 77260666
Test: atest /android/pi-dev/cts/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/LauncherAppsProfileTest.java#testReverseAccessNoThrow
Test: adb shell am instrument -w -e class com.android.server.pm.ShortcutManagerTest1 -w com.android.frameworks.servicestests
Test: adb shell am instrument -w -e class com.android.server.pm.ShortcutManagerTest2 -w com.android.frameworks.servicestests
Test: adb shell am instrument -w -e class com.android.server.pm.ShortcutManagerTest3 -w com.android.frameworks.servicestests
Test: adb shell am instrument -w -e class com.android.server.pm.ShortcutManagerTest4 -w com.android.frameworks.servicestests
Test: adb shell am instrument -w -e class com.android.server.pm.ShortcutManagerTest5 -w com.android.frameworks.servicestests
Test: adb shell am instrument -w -e class com.android.server.pm.ShortcutManagerTest6 -w com.android.frameworks.servicestests
Test: adb shell am instrument -w -e class com.android.server.pm.ShortcutManagerTest7 -w com.android.frameworks.servicestests
Test: adb shell am instrument -w -e class com.android.server.pm.ShortcutManagerTest8 -w com.android.frameworks.servicestests
Test: adb shell am instrument -w -e class com.android.server.pm.ShortcutManagerTest9 -w com.android.frameworks.servicestests
Test: adb shell am instrument -w -e class com.android.server.pm.ShortcutManagerTest10 -w com.android.frameworks.servicestests
parent a926126a
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ import android.content.pm.ResolveInfo;
import android.content.pm.ShortcutInfo;
import android.content.pm.ShortcutServiceInternal;
import android.content.pm.ShortcutServiceInternal.ShortcutChangeListener;
import android.content.pm.UserInfo;
import android.graphics.Rect;
import android.net.Uri;
import android.os.Binder;
@@ -49,6 +50,7 @@ import android.os.ParcelFileDescriptor;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserManager;
import android.os.UserManagerInternal;
import android.provider.Settings;
import android.util.Log;
@@ -101,6 +103,7 @@ public class LauncherAppsService extends SystemService {
        private static final boolean DEBUG = false;
        private static final String TAG = "LauncherAppsService";
        private final Context mContext;
        private final UserManager mUm;
        private final UserManagerInternal mUserManagerInternal;
        private final ActivityManagerInternal mActivityManagerInternal;
        private final ShortcutServiceInternal mShortcutServiceInternal;
@@ -113,6 +116,7 @@ public class LauncherAppsService extends SystemService {

        public LauncherAppsImpl(Context context) {
            mContext = context;
            mUm = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
            mUserManagerInternal = Preconditions.checkNotNull(
                    LocalServices.getService(UserManagerInternal.class));
            mActivityManagerInternal = Preconditions.checkNotNull(
@@ -233,6 +237,22 @@ public class LauncherAppsService extends SystemService {
         * group.
         */
        private boolean canAccessProfile(int targetUserId, String message) {
            final int callingUserId = injectCallingUserId();

            if (targetUserId == callingUserId) return true;

            long ident = injectClearCallingIdentity();
            try {
                final UserInfo callingUserInfo = mUm.getUserInfo(callingUserId);
                if (callingUserInfo != null && callingUserInfo.isManagedProfile()) {
                    Slog.w(TAG, message + " for another profile "
                            + targetUserId + " from " + callingUserId + " not allowed");
                    return false;
                }
            } finally {
                injectRestoreCallingIdentity(ident);
            }

            return mUserManagerInternal.isProfileAccessible(injectCallingUserId(), targetUserId,
                    message, true);
        }
+23 −0
Original line number Diff line number Diff line
@@ -92,6 +92,8 @@ import com.android.server.pm.ShortcutUser.PackageWithUser;

import org.junit.Assert;
import org.mockito.ArgumentCaptor;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
@@ -111,6 +113,7 @@ import java.util.Set;
import java.util.function.BiFunction;
import java.util.function.BiPredicate;
import java.util.function.Consumer;
import java.util.function.Function;

public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
    protected static final String TAG = "ShortcutManagerTest";
@@ -834,6 +837,8 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
                            + targetUserId);
                });

        when(mMockUserManager.getUserInfo(anyInt())).thenAnswer(new AnswerWithSystemCheck<>(
                inv -> mUserInfos.get((Integer) inv.getArguments()[0])));
        when(mMockActivityManagerInternal.getUidProcessState(anyInt())).thenReturn(
                ActivityManager.PROCESS_STATE_CACHED_EMPTY);

@@ -863,6 +868,24 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
        }
    }

    /**
     * Returns a boolean but also checks if the current UID is SYSTEM_UID.
     */
    protected class AnswerWithSystemCheck<T> implements Answer<T> {
        private final Function<InvocationOnMock, T> mChecker;

        public AnswerWithSystemCheck(Function<InvocationOnMock, T> checker) {
            mChecker = checker;
        }

        @Override
        public T answer(InvocationOnMock invocation) throws Throwable {
            assertEquals("Must be called on SYSTEM UID.",
                    Process.SYSTEM_UID, mInjectedCallingUid);
            return mChecker.apply(invocation);
        }
    }

    private static boolean b(Boolean value) {
        return (value != null && value);
    }