Loading services/core/java/com/android/server/pm/PackageInstallerService.java +6 −6 Original line number Diff line number Diff line Loading @@ -517,7 +517,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements String installerAttributionTag, int userId) throws IOException { final int callingUid = Binder.getCallingUid(); mPermissionManager.enforceCrossUserPermission( mPm.enforceCrossUserPermission( callingUid, userId, true, true, "createSession"); if (mPm.isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) { Loading Loading @@ -912,7 +912,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements @Override public ParceledListSlice<SessionInfo> getAllSessions(int userId) { final int callingUid = Binder.getCallingUid(); mPermissionManager.enforceCrossUserPermission( mPm.enforceCrossUserPermission( callingUid, userId, true, false, "getAllSessions"); final List<SessionInfo> result = new ArrayList<>(); Loading @@ -930,7 +930,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements @Override public ParceledListSlice<SessionInfo> getMySessions(String installerPackageName, int userId) { mPermissionManager.enforceCrossUserPermission( mPm.enforceCrossUserPermission( Binder.getCallingUid(), userId, true, false, "getMySessions"); mAppOps.checkPackage(Binder.getCallingUid(), installerPackageName); Loading @@ -954,7 +954,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements public void uninstall(VersionedPackage versionedPackage, String callerPackageName, int flags, IntentSender statusReceiver, int userId) { final int callingUid = Binder.getCallingUid(); mPermissionManager.enforceCrossUserPermission(callingUid, userId, true, true, "uninstall"); mPm.enforceCrossUserPermission(callingUid, userId, true, true, "uninstall"); if ((callingUid != Process.SHELL_UID) && (callingUid != Process.ROOT_UID)) { mAppOps.checkPackage(callingUid, callerPackageName); } Loading Loading @@ -1006,7 +1006,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements String callerPackageName, IntentSender statusReceiver, int userId) { final int callingUid = Binder.getCallingUid(); mContext.enforceCallingOrSelfPermission(Manifest.permission.DELETE_PACKAGES, null); mPermissionManager.enforceCrossUserPermission(callingUid, userId, true, true, "uninstall"); mPm.enforceCrossUserPermission(callingUid, userId, true, true, "uninstall"); if ((callingUid != Process.SHELL_UID) && (callingUid != Process.ROOT_UID)) { mAppOps.checkPackage(callingUid, callerPackageName); } Loading Loading @@ -1037,7 +1037,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements @Override public void registerCallback(IPackageInstallerCallback callback, int userId) { mPermissionManager.enforceCrossUserPermission( mPm.enforceCrossUserPermission( Binder.getCallingUid(), userId, true, false, "registerCallback"); registerCallback(callback, eventUserId -> userId == eventUserId); } Loading services/core/java/com/android/server/pm/PackageManagerService.java +245 −102 File changed.Preview size limit exceeded, changes collapsed. Show changes services/core/java/com/android/server/pm/permission/PermissionManagerService.java +28 −122 Original line number Diff line number Diff line Loading @@ -77,7 +77,6 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.PermissionChecker; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; Loading @@ -96,6 +95,7 @@ import android.content.pm.permission.SplitPermissionInfoParcelable; import android.metrics.LogMaker; import android.os.Binder; import android.os.Build; import android.os.Debug; import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; Loading Loading @@ -754,7 +754,6 @@ public class PermissionManagerService extends IPermissionManager.Stub { enforceCrossUserPermission(callingUid, userId, true, // requireFullPermission false, // checkShell false, // requirePermissionWhenSameUser "getPermissionFlags"); final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName); Loading Loading @@ -841,7 +840,6 @@ public class PermissionManagerService extends IPermissionManager.Stub { enforceCrossUserPermission(callingUid, userId, true, // requireFullPermission true, // checkShell false, // requirePermissionWhenSameUser "updatePermissionFlags"); if ((flagMask & FLAG_PERMISSION_POLICY_FIXED) != 0 && !overridePolicy) { Loading Loading @@ -951,7 +949,6 @@ public class PermissionManagerService extends IPermissionManager.Stub { enforceCrossUserPermission(callingUid, userId, true, // requireFullPermission true, // checkShell false, // requirePermissionWhenSameUser "updatePermissionFlagsForAllApps"); // Only the system can change system fixed flags. Loading Loading @@ -1555,7 +1552,6 @@ public class PermissionManagerService extends IPermissionManager.Stub { enforceCrossUserPermission(callingUid, userId, true, // requireFullPermission true, // checkShell false, // requirePermissionWhenSameUser "grantRuntimePermission"); final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName); Loading Loading @@ -1722,7 +1718,6 @@ public class PermissionManagerService extends IPermissionManager.Stub { enforceCrossUserPermission(callingUid, userId, true, // requireFullPermission true, // checkShell false, // requirePermissionWhenSameUser "revokeRuntimePermission"); final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName); Loading Loading @@ -4494,25 +4489,22 @@ public class PermissionManagerService extends IPermissionManager.Stub { } /** * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller. * Enforces the request is from the system or an app that has INTERACT_ACROSS_USERS * or INTERACT_ACROSS_USERS_FULL permissions, if the {@code userId} is not for the caller. * * @param checkShell whether to prevent shell from access if there's a debugging restriction * @param message the message to log on security exception */ private void enforceCrossUserPermission(int callingUid, @UserIdInt int userId, boolean requireFullPermission, boolean checkShell, boolean requirePermissionWhenSameUser, String message) { boolean requireFullPermission, boolean checkShell, @Nullable String message) { if (userId < 0) { throw new IllegalArgumentException("Invalid userId " + userId); } if (checkShell) { PackageManagerServiceUtils.enforceShellRestriction(mUserManagerInt, UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId); enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId); } final int callingUserId = UserHandle.getUserId(callingUid); if (hasCrossUserPermission( callingUid, callingUserId, userId, requireFullPermission, requirePermissionWhenSameUser)) { if (checkCrossUserPermission(callingUid, callingUserId, userId, requireFullPermission)) { return; } String errorMessage = buildInvalidCrossUserPermissionMessage( Loading @@ -4522,82 +4514,45 @@ public class PermissionManagerService extends IPermissionManager.Stub { } /** * Checks if the request is from the system or an app that has the appropriate cross-user * permissions defined as follows: * <ul> * <li>INTERACT_ACROSS_USERS_FULL if {@code requireFullPermission} is true.</li> * <li>INTERACT_ACROSS_USERS if the given {@userId} is in a different profile group * to the caller.</li> * <li>Otherwise, INTERACT_ACROSS_PROFILES if the given {@userId} is in the same profile group * as the caller.</li> * </ul> * * @param checkShell whether to prevent shell from access if there's a debugging restriction * @param message the message to log on security exception * Enforces that if the caller is shell, it does not have the provided user restriction. */ private void enforceCrossUserOrProfilePermission(int callingUid, @UserIdInt int userId, boolean requireFullPermission, boolean checkShell, String message) { if (userId < 0) { throw new IllegalArgumentException("Invalid userId " + userId); } if (checkShell) { PackageManagerServiceUtils.enforceShellRestriction(mUserManagerInt, UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId); } final int callingUserId = UserHandle.getUserId(callingUid); if (hasCrossUserPermission(callingUid, callingUserId, userId, requireFullPermission, /*requirePermissionWhenSameUser= */ false)) { return; private void enforceShellRestriction(@NonNull String restriction, int callingUid, @UserIdInt int userId) { if (callingUid == Process.SHELL_UID) { if (userId >= 0 && mUserManagerInt.hasUserRestriction(restriction, userId)) { throw new SecurityException("Shell does not have permission to access user " + userId); } else if (userId < 0) { Slog.e(LOG_TAG, "Unable to check shell permission for user " + userId + "\n\t" + Debug.getCallers(3)); } final boolean isSameProfileGroup = isSameProfileGroup(callingUserId, userId); if (isSameProfileGroup && PermissionChecker.checkPermissionForPreflight( mContext, android.Manifest.permission.INTERACT_ACROSS_PROFILES, PermissionChecker.PID_UNKNOWN, callingUid, mPackageManagerInt.getPackage(callingUid).getPackageName()) == PermissionChecker.PERMISSION_GRANTED) { return; } String errorMessage = buildInvalidCrossUserOrProfilePermissionMessage( callingUid, userId, message, requireFullPermission, isSameProfileGroup); Slog.w(TAG, errorMessage); throw new SecurityException(errorMessage); } private boolean hasCrossUserPermission( int callingUid, int callingUserId, int userId, boolean requireFullPermission, boolean requirePermissionWhenSameUser) { if (!requirePermissionWhenSameUser && userId == callingUserId) { private boolean checkCrossUserPermission(int callingUid, @UserIdInt int callingUserId, @UserIdInt int userId, boolean requireFullPermission) { if (userId == callingUserId) { return true; } if (callingUid == Process.SYSTEM_UID || callingUid == Process.ROOT_UID) { return true; } if (requireFullPermission) { return hasPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL); return checkCallingOrSelfPermission( android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); } return hasPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) || hasPermission(Manifest.permission.INTERACT_ACROSS_USERS); return checkCallingOrSelfPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) || checkCallingOrSelfPermission(android.Manifest.permission.INTERACT_ACROSS_USERS); } private boolean hasPermission(String permission) { private boolean checkCallingOrSelfPermission(String permission) { return mContext.checkCallingOrSelfPermission(permission) == PackageManager.PERMISSION_GRANTED; } private boolean isSameProfileGroup(@UserIdInt int callerUserId, @UserIdInt int userId) { final long identity = Binder.clearCallingIdentity(); try { return UserManagerService.getInstance().isSameProfileGroup(callerUserId, userId); } finally { Binder.restoreCallingIdentity(identity); } } @NonNull private static String buildInvalidCrossUserPermissionMessage(int callingUid, @UserIdInt int userId, String message, boolean requireFullPermission) { @UserIdInt int userId, @Nullable String message, boolean requireFullPermission) { StringBuilder builder = new StringBuilder(); if (message != null) { builder.append(message); Loading @@ -4617,31 +4572,6 @@ public class PermissionManagerService extends IPermissionManager.Stub { return builder.toString(); } private static String buildInvalidCrossUserOrProfilePermissionMessage(int callingUid, @UserIdInt int userId, String message, boolean requireFullPermission, boolean isSameProfileGroup) { StringBuilder builder = new StringBuilder(); if (message != null) { builder.append(message); builder.append(": "); } builder.append("UID "); builder.append(callingUid); builder.append(" requires "); builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); if (!requireFullPermission) { builder.append(" or "); builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); if (isSameProfileGroup) { builder.append(" or "); builder.append(android.Manifest.permission.INTERACT_ACROSS_PROFILES); } } builder.append(" to access user "); builder.append("."); return builder.toString(); } @GuardedBy("mLock") private int calculateCurrentPermissionFootprintLocked(@NonNull Permission permissionTree) { int size = 0; Loading Loading @@ -5140,30 +5070,6 @@ public class PermissionManagerService extends IPermissionManager.Stub { Preconditions.checkArgumentNonNegative(userId, "userId"); mPackageManagerInt.forEachPackage(pkg -> resetRuntimePermissionsInternal(pkg, userId)); } @Override public void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission, boolean checkShell, String message) { PermissionManagerService.this.enforceCrossUserPermission(callingUid, userId, requireFullPermission, checkShell, false, message); } @Override public void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission, boolean checkShell, boolean requirePermissionWhenSameUser, String message) { PermissionManagerService.this.enforceCrossUserPermission(callingUid, userId, requireFullPermission, checkShell, requirePermissionWhenSameUser, message); } @Override public void enforceCrossUserOrProfilePermission(int callingUid, int userId, boolean requireFullPermission, boolean checkShell, String message) { PermissionManagerService.this.enforceCrossUserOrProfilePermission( callingUid, userId, requireFullPermission, checkShell, message); } @Override public Permission getPermissionTEMP(String permName) { Loading services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java +0 −26 Original line number Diff line number Diff line Loading @@ -393,32 +393,6 @@ public abstract class PermissionManagerServiceInternal extends PermissionManager @NonNull public abstract String[] getAppOpPermissionPackages(@NonNull String permissionName); /** * Enforces the request is from the system or an app that has INTERACT_ACROSS_USERS * or INTERACT_ACROSS_USERS_FULL permissions, if the {@code userid} is not for the caller. * @param checkShell whether to prevent shell from access if there's a debugging restriction * @param message the message to log on security exception */ public abstract void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission, boolean checkShell, @NonNull String message); /** * Similar to {@link #enforceCrossUserPermission(int, int, boolean, boolean, String)} * but also allows INTERACT_ACROSS_PROFILES permission if calling user and {@code userId} are * in the same profile group. */ public abstract void enforceCrossUserOrProfilePermission(int callingUid, int userId, boolean requireFullPermission, boolean checkShell, @NonNull String message); /** * @see #enforceCrossUserPermission(int, int, boolean, boolean, String) * @param requirePermissionWhenSameUser When {@code true}, still require the cross user * permission to be held even if the callingUid and userId reference the same user. */ public abstract void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission, boolean checkShell, boolean requirePermissionWhenSameUser, @NonNull String message); /** HACK HACK methods to allow for partial migration of data to the PermissionManager class */ @Nullable public abstract Permission getPermissionTEMP(@NonNull String permName); Loading services/tests/PackageManagerComponentOverrideTests/src/com/android/server/pm/test/override/PackageManagerComponentLabelIconOverrideTest.kt +7 −10 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.server.pm.test.override import android.content.ComponentName import android.content.Context import android.content.pm.PackageManager import android.content.pm.parsing.component.ParsedActivity import android.os.Binder import android.os.UserHandle Loading @@ -31,7 +32,6 @@ import com.android.server.pm.UserManagerService import com.android.server.pm.parsing.pkg.AndroidPackage import com.android.server.pm.parsing.pkg.PackageImpl import com.android.server.pm.parsing.pkg.ParsedPackage import com.android.server.pm.permission.PermissionManagerServiceInternal import com.android.server.pm.test.override.PackageManagerComponentLabelIconOverrideTest.Companion.Params.AppType import com.android.server.testutils.TestHandler import com.android.server.testutils.mock Loading @@ -45,11 +45,8 @@ import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.Parameterized import org.mockito.Mockito import org.mockito.Mockito.any import org.mockito.Mockito.anyBoolean import org.mockito.Mockito.anyInt import org.mockito.Mockito.anyString import org.mockito.Mockito.clearInvocations import org.mockito.Mockito.intThat import org.mockito.Mockito.never Loading Loading @@ -321,10 +318,6 @@ class PackageManagerComponentLabelIconOverrideTest { whenever(this.exists(intThat(matcher))) { true } whenever(this.isUserUnlockingOrUnlocked(intThat(matcher))) { true } } val mockPermissionManagerService: PermissionManagerServiceInternal = mockThrowOnUnmocked { whenever(this.enforceCrossUserPermission(anyInt(), anyInt(), anyBoolean(), anyBoolean(), anyString())) { } } val mockActivityTaskManager: ActivityTaskManagerInternal = mockThrowOnUnmocked { whenever(this.isCallerRecents(anyInt())) { false } } Loading @@ -335,15 +328,19 @@ class PackageManagerComponentLabelIconOverrideTest { val mockContext: Context = mockThrowOnUnmocked { whenever(this.getString( com.android.internal.R.string.config_overrideComponentUiPackage)) { VALID_PKG } whenever(this.checkCallingOrSelfPermission( android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)) { PackageManager.PERMISSION_GRANTED } } val mockInjector: PackageManagerService.Injector = mock { whenever(this.lock) { Object() } whenever(this.componentResolver) { mockComponentResolver } whenever(this.userManagerService) { mockUserManagerService } whenever(this.permissionManagerServiceInternal) { mockPermissionManagerService } whenever(this.settings) { mockSettings } whenever(this.getLocalService(ActivityTaskManagerInternal::class.java)) { mockActivityTaskManager} mockActivityTaskManager } whenever(this.appsFilter) { mockAppsFilter } whenever(this.context) { mockContext } } Loading Loading
services/core/java/com/android/server/pm/PackageInstallerService.java +6 −6 Original line number Diff line number Diff line Loading @@ -517,7 +517,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements String installerAttributionTag, int userId) throws IOException { final int callingUid = Binder.getCallingUid(); mPermissionManager.enforceCrossUserPermission( mPm.enforceCrossUserPermission( callingUid, userId, true, true, "createSession"); if (mPm.isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) { Loading Loading @@ -912,7 +912,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements @Override public ParceledListSlice<SessionInfo> getAllSessions(int userId) { final int callingUid = Binder.getCallingUid(); mPermissionManager.enforceCrossUserPermission( mPm.enforceCrossUserPermission( callingUid, userId, true, false, "getAllSessions"); final List<SessionInfo> result = new ArrayList<>(); Loading @@ -930,7 +930,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements @Override public ParceledListSlice<SessionInfo> getMySessions(String installerPackageName, int userId) { mPermissionManager.enforceCrossUserPermission( mPm.enforceCrossUserPermission( Binder.getCallingUid(), userId, true, false, "getMySessions"); mAppOps.checkPackage(Binder.getCallingUid(), installerPackageName); Loading @@ -954,7 +954,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements public void uninstall(VersionedPackage versionedPackage, String callerPackageName, int flags, IntentSender statusReceiver, int userId) { final int callingUid = Binder.getCallingUid(); mPermissionManager.enforceCrossUserPermission(callingUid, userId, true, true, "uninstall"); mPm.enforceCrossUserPermission(callingUid, userId, true, true, "uninstall"); if ((callingUid != Process.SHELL_UID) && (callingUid != Process.ROOT_UID)) { mAppOps.checkPackage(callingUid, callerPackageName); } Loading Loading @@ -1006,7 +1006,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements String callerPackageName, IntentSender statusReceiver, int userId) { final int callingUid = Binder.getCallingUid(); mContext.enforceCallingOrSelfPermission(Manifest.permission.DELETE_PACKAGES, null); mPermissionManager.enforceCrossUserPermission(callingUid, userId, true, true, "uninstall"); mPm.enforceCrossUserPermission(callingUid, userId, true, true, "uninstall"); if ((callingUid != Process.SHELL_UID) && (callingUid != Process.ROOT_UID)) { mAppOps.checkPackage(callingUid, callerPackageName); } Loading Loading @@ -1037,7 +1037,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements @Override public void registerCallback(IPackageInstallerCallback callback, int userId) { mPermissionManager.enforceCrossUserPermission( mPm.enforceCrossUserPermission( Binder.getCallingUid(), userId, true, false, "registerCallback"); registerCallback(callback, eventUserId -> userId == eventUserId); } Loading
services/core/java/com/android/server/pm/PackageManagerService.java +245 −102 File changed.Preview size limit exceeded, changes collapsed. Show changes
services/core/java/com/android/server/pm/permission/PermissionManagerService.java +28 −122 Original line number Diff line number Diff line Loading @@ -77,7 +77,6 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.PermissionChecker; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; Loading @@ -96,6 +95,7 @@ import android.content.pm.permission.SplitPermissionInfoParcelable; import android.metrics.LogMaker; import android.os.Binder; import android.os.Build; import android.os.Debug; import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; Loading Loading @@ -754,7 +754,6 @@ public class PermissionManagerService extends IPermissionManager.Stub { enforceCrossUserPermission(callingUid, userId, true, // requireFullPermission false, // checkShell false, // requirePermissionWhenSameUser "getPermissionFlags"); final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName); Loading Loading @@ -841,7 +840,6 @@ public class PermissionManagerService extends IPermissionManager.Stub { enforceCrossUserPermission(callingUid, userId, true, // requireFullPermission true, // checkShell false, // requirePermissionWhenSameUser "updatePermissionFlags"); if ((flagMask & FLAG_PERMISSION_POLICY_FIXED) != 0 && !overridePolicy) { Loading Loading @@ -951,7 +949,6 @@ public class PermissionManagerService extends IPermissionManager.Stub { enforceCrossUserPermission(callingUid, userId, true, // requireFullPermission true, // checkShell false, // requirePermissionWhenSameUser "updatePermissionFlagsForAllApps"); // Only the system can change system fixed flags. Loading Loading @@ -1555,7 +1552,6 @@ public class PermissionManagerService extends IPermissionManager.Stub { enforceCrossUserPermission(callingUid, userId, true, // requireFullPermission true, // checkShell false, // requirePermissionWhenSameUser "grantRuntimePermission"); final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName); Loading Loading @@ -1722,7 +1718,6 @@ public class PermissionManagerService extends IPermissionManager.Stub { enforceCrossUserPermission(callingUid, userId, true, // requireFullPermission true, // checkShell false, // requirePermissionWhenSameUser "revokeRuntimePermission"); final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName); Loading Loading @@ -4494,25 +4489,22 @@ public class PermissionManagerService extends IPermissionManager.Stub { } /** * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller. * Enforces the request is from the system or an app that has INTERACT_ACROSS_USERS * or INTERACT_ACROSS_USERS_FULL permissions, if the {@code userId} is not for the caller. * * @param checkShell whether to prevent shell from access if there's a debugging restriction * @param message the message to log on security exception */ private void enforceCrossUserPermission(int callingUid, @UserIdInt int userId, boolean requireFullPermission, boolean checkShell, boolean requirePermissionWhenSameUser, String message) { boolean requireFullPermission, boolean checkShell, @Nullable String message) { if (userId < 0) { throw new IllegalArgumentException("Invalid userId " + userId); } if (checkShell) { PackageManagerServiceUtils.enforceShellRestriction(mUserManagerInt, UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId); enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId); } final int callingUserId = UserHandle.getUserId(callingUid); if (hasCrossUserPermission( callingUid, callingUserId, userId, requireFullPermission, requirePermissionWhenSameUser)) { if (checkCrossUserPermission(callingUid, callingUserId, userId, requireFullPermission)) { return; } String errorMessage = buildInvalidCrossUserPermissionMessage( Loading @@ -4522,82 +4514,45 @@ public class PermissionManagerService extends IPermissionManager.Stub { } /** * Checks if the request is from the system or an app that has the appropriate cross-user * permissions defined as follows: * <ul> * <li>INTERACT_ACROSS_USERS_FULL if {@code requireFullPermission} is true.</li> * <li>INTERACT_ACROSS_USERS if the given {@userId} is in a different profile group * to the caller.</li> * <li>Otherwise, INTERACT_ACROSS_PROFILES if the given {@userId} is in the same profile group * as the caller.</li> * </ul> * * @param checkShell whether to prevent shell from access if there's a debugging restriction * @param message the message to log on security exception * Enforces that if the caller is shell, it does not have the provided user restriction. */ private void enforceCrossUserOrProfilePermission(int callingUid, @UserIdInt int userId, boolean requireFullPermission, boolean checkShell, String message) { if (userId < 0) { throw new IllegalArgumentException("Invalid userId " + userId); } if (checkShell) { PackageManagerServiceUtils.enforceShellRestriction(mUserManagerInt, UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId); } final int callingUserId = UserHandle.getUserId(callingUid); if (hasCrossUserPermission(callingUid, callingUserId, userId, requireFullPermission, /*requirePermissionWhenSameUser= */ false)) { return; private void enforceShellRestriction(@NonNull String restriction, int callingUid, @UserIdInt int userId) { if (callingUid == Process.SHELL_UID) { if (userId >= 0 && mUserManagerInt.hasUserRestriction(restriction, userId)) { throw new SecurityException("Shell does not have permission to access user " + userId); } else if (userId < 0) { Slog.e(LOG_TAG, "Unable to check shell permission for user " + userId + "\n\t" + Debug.getCallers(3)); } final boolean isSameProfileGroup = isSameProfileGroup(callingUserId, userId); if (isSameProfileGroup && PermissionChecker.checkPermissionForPreflight( mContext, android.Manifest.permission.INTERACT_ACROSS_PROFILES, PermissionChecker.PID_UNKNOWN, callingUid, mPackageManagerInt.getPackage(callingUid).getPackageName()) == PermissionChecker.PERMISSION_GRANTED) { return; } String errorMessage = buildInvalidCrossUserOrProfilePermissionMessage( callingUid, userId, message, requireFullPermission, isSameProfileGroup); Slog.w(TAG, errorMessage); throw new SecurityException(errorMessage); } private boolean hasCrossUserPermission( int callingUid, int callingUserId, int userId, boolean requireFullPermission, boolean requirePermissionWhenSameUser) { if (!requirePermissionWhenSameUser && userId == callingUserId) { private boolean checkCrossUserPermission(int callingUid, @UserIdInt int callingUserId, @UserIdInt int userId, boolean requireFullPermission) { if (userId == callingUserId) { return true; } if (callingUid == Process.SYSTEM_UID || callingUid == Process.ROOT_UID) { return true; } if (requireFullPermission) { return hasPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL); return checkCallingOrSelfPermission( android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); } return hasPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) || hasPermission(Manifest.permission.INTERACT_ACROSS_USERS); return checkCallingOrSelfPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) || checkCallingOrSelfPermission(android.Manifest.permission.INTERACT_ACROSS_USERS); } private boolean hasPermission(String permission) { private boolean checkCallingOrSelfPermission(String permission) { return mContext.checkCallingOrSelfPermission(permission) == PackageManager.PERMISSION_GRANTED; } private boolean isSameProfileGroup(@UserIdInt int callerUserId, @UserIdInt int userId) { final long identity = Binder.clearCallingIdentity(); try { return UserManagerService.getInstance().isSameProfileGroup(callerUserId, userId); } finally { Binder.restoreCallingIdentity(identity); } } @NonNull private static String buildInvalidCrossUserPermissionMessage(int callingUid, @UserIdInt int userId, String message, boolean requireFullPermission) { @UserIdInt int userId, @Nullable String message, boolean requireFullPermission) { StringBuilder builder = new StringBuilder(); if (message != null) { builder.append(message); Loading @@ -4617,31 +4572,6 @@ public class PermissionManagerService extends IPermissionManager.Stub { return builder.toString(); } private static String buildInvalidCrossUserOrProfilePermissionMessage(int callingUid, @UserIdInt int userId, String message, boolean requireFullPermission, boolean isSameProfileGroup) { StringBuilder builder = new StringBuilder(); if (message != null) { builder.append(message); builder.append(": "); } builder.append("UID "); builder.append(callingUid); builder.append(" requires "); builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); if (!requireFullPermission) { builder.append(" or "); builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); if (isSameProfileGroup) { builder.append(" or "); builder.append(android.Manifest.permission.INTERACT_ACROSS_PROFILES); } } builder.append(" to access user "); builder.append("."); return builder.toString(); } @GuardedBy("mLock") private int calculateCurrentPermissionFootprintLocked(@NonNull Permission permissionTree) { int size = 0; Loading Loading @@ -5140,30 +5070,6 @@ public class PermissionManagerService extends IPermissionManager.Stub { Preconditions.checkArgumentNonNegative(userId, "userId"); mPackageManagerInt.forEachPackage(pkg -> resetRuntimePermissionsInternal(pkg, userId)); } @Override public void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission, boolean checkShell, String message) { PermissionManagerService.this.enforceCrossUserPermission(callingUid, userId, requireFullPermission, checkShell, false, message); } @Override public void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission, boolean checkShell, boolean requirePermissionWhenSameUser, String message) { PermissionManagerService.this.enforceCrossUserPermission(callingUid, userId, requireFullPermission, checkShell, requirePermissionWhenSameUser, message); } @Override public void enforceCrossUserOrProfilePermission(int callingUid, int userId, boolean requireFullPermission, boolean checkShell, String message) { PermissionManagerService.this.enforceCrossUserOrProfilePermission( callingUid, userId, requireFullPermission, checkShell, message); } @Override public Permission getPermissionTEMP(String permName) { Loading
services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java +0 −26 Original line number Diff line number Diff line Loading @@ -393,32 +393,6 @@ public abstract class PermissionManagerServiceInternal extends PermissionManager @NonNull public abstract String[] getAppOpPermissionPackages(@NonNull String permissionName); /** * Enforces the request is from the system or an app that has INTERACT_ACROSS_USERS * or INTERACT_ACROSS_USERS_FULL permissions, if the {@code userid} is not for the caller. * @param checkShell whether to prevent shell from access if there's a debugging restriction * @param message the message to log on security exception */ public abstract void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission, boolean checkShell, @NonNull String message); /** * Similar to {@link #enforceCrossUserPermission(int, int, boolean, boolean, String)} * but also allows INTERACT_ACROSS_PROFILES permission if calling user and {@code userId} are * in the same profile group. */ public abstract void enforceCrossUserOrProfilePermission(int callingUid, int userId, boolean requireFullPermission, boolean checkShell, @NonNull String message); /** * @see #enforceCrossUserPermission(int, int, boolean, boolean, String) * @param requirePermissionWhenSameUser When {@code true}, still require the cross user * permission to be held even if the callingUid and userId reference the same user. */ public abstract void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission, boolean checkShell, boolean requirePermissionWhenSameUser, @NonNull String message); /** HACK HACK methods to allow for partial migration of data to the PermissionManager class */ @Nullable public abstract Permission getPermissionTEMP(@NonNull String permName); Loading
services/tests/PackageManagerComponentOverrideTests/src/com/android/server/pm/test/override/PackageManagerComponentLabelIconOverrideTest.kt +7 −10 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.server.pm.test.override import android.content.ComponentName import android.content.Context import android.content.pm.PackageManager import android.content.pm.parsing.component.ParsedActivity import android.os.Binder import android.os.UserHandle Loading @@ -31,7 +32,6 @@ import com.android.server.pm.UserManagerService import com.android.server.pm.parsing.pkg.AndroidPackage import com.android.server.pm.parsing.pkg.PackageImpl import com.android.server.pm.parsing.pkg.ParsedPackage import com.android.server.pm.permission.PermissionManagerServiceInternal import com.android.server.pm.test.override.PackageManagerComponentLabelIconOverrideTest.Companion.Params.AppType import com.android.server.testutils.TestHandler import com.android.server.testutils.mock Loading @@ -45,11 +45,8 @@ import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.Parameterized import org.mockito.Mockito import org.mockito.Mockito.any import org.mockito.Mockito.anyBoolean import org.mockito.Mockito.anyInt import org.mockito.Mockito.anyString import org.mockito.Mockito.clearInvocations import org.mockito.Mockito.intThat import org.mockito.Mockito.never Loading Loading @@ -321,10 +318,6 @@ class PackageManagerComponentLabelIconOverrideTest { whenever(this.exists(intThat(matcher))) { true } whenever(this.isUserUnlockingOrUnlocked(intThat(matcher))) { true } } val mockPermissionManagerService: PermissionManagerServiceInternal = mockThrowOnUnmocked { whenever(this.enforceCrossUserPermission(anyInt(), anyInt(), anyBoolean(), anyBoolean(), anyString())) { } } val mockActivityTaskManager: ActivityTaskManagerInternal = mockThrowOnUnmocked { whenever(this.isCallerRecents(anyInt())) { false } } Loading @@ -335,15 +328,19 @@ class PackageManagerComponentLabelIconOverrideTest { val mockContext: Context = mockThrowOnUnmocked { whenever(this.getString( com.android.internal.R.string.config_overrideComponentUiPackage)) { VALID_PKG } whenever(this.checkCallingOrSelfPermission( android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)) { PackageManager.PERMISSION_GRANTED } } val mockInjector: PackageManagerService.Injector = mock { whenever(this.lock) { Object() } whenever(this.componentResolver) { mockComponentResolver } whenever(this.userManagerService) { mockUserManagerService } whenever(this.permissionManagerServiceInternal) { mockPermissionManagerService } whenever(this.settings) { mockSettings } whenever(this.getLocalService(ActivityTaskManagerInternal::class.java)) { mockActivityTaskManager} mockActivityTaskManager } whenever(this.appsFilter) { mockAppsFilter } whenever(this.context) { mockContext } } Loading