Loading services/appfunctions/java/com/android/server/appfunctions/AppFunctionManagerServiceImpl.java +5 −1 Original line number Diff line number Diff line Loading @@ -75,6 +75,7 @@ import android.os.RemoteException; import android.os.ResultReceiver; import android.os.ShellCallback; import android.os.UserHandle; import android.os.UserManager; import android.permission.flags.Flags; import android.provider.DeviceConfig; import android.text.TextUtils; Loading Loading @@ -149,7 +150,10 @@ public class AppFunctionManagerServiceImpl extends IAppFunctionManager.Stub { context, new RemoteServiceCallerImpl<>( context, IAppFunctionService.Stub::asInterface, THREAD_POOL_EXECUTOR), new CallerValidatorImpl(context, appFunctionAccessServiceInterface), new CallerValidatorImpl( context, appFunctionAccessServiceInterface, Objects.requireNonNull(context.getSystemService(UserManager.class))), new ServiceHelperImpl(context), new ServiceConfigImpl(), new AppFunctionsLoggerWrapper(context), Loading services/appfunctions/java/com/android/server/appfunctions/CallerValidator.java +6 −7 Original line number Diff line number Diff line Loading @@ -52,12 +52,11 @@ public interface CallerValidator { * * @param targetUserHandle The user which the caller is requesting to execute as. * @param claimedCallingPackage The package name of the caller. * @return The user handle that the call should run as. Will always be a concrete user. * @throws IllegalArgumentException if the target user is a special user. * @throws SecurityException if caller trying to interact across users without {@link * Manifest.permission#INTERACT_ACROSS_USERS_FULL} */ UserHandle verifyTargetUserHandle( void verifyTargetUserHandle( @NonNull UserHandle targetUserHandle, @NonNull String claimedCallingPackage); /** Loading Loading @@ -103,8 +102,8 @@ public interface CallerValidator { int CAN_EXECUTE_APP_FUNCTIONS_ALLOWED_SAME_PACKAGE = 1; /** * Callers can execute app functions because they have the necessary permission. * This case also applies when a caller with the permission invokes their own app functions. * Callers can execute app functions because they have the necessary permission. This case also * applies when a caller with the permission invokes their own app functions. */ int CAN_EXECUTE_APP_FUNCTIONS_ALLOWED_HAS_PERMISSION = 2; Loading services/appfunctions/java/com/android/server/appfunctions/CallerValidatorImpl.java +28 −29 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import android.content.pm.PackageManager; import android.os.Binder; import android.os.Process; import android.os.UserHandle; import android.os.UserManager; import android.permission.flags.Flags; import com.android.internal.infra.AndroidFuture; Loading @@ -42,12 +43,16 @@ class CallerValidatorImpl implements CallerValidator { private final DeviceSettingHelper mDeviceSettingHelper; private final UserManager mUserManager; CallerValidatorImpl( @NonNull Context context, @NonNull AppFunctionAccessServiceInterface appFunctionAccessService) { @NonNull AppFunctionAccessServiceInterface appFunctionAccessService, @NonNull UserManager userManager) { mContext = Objects.requireNonNull(context); mAppFunctionAccessService = Objects.requireNonNull(appFunctionAccessService); mDeviceSettingHelper = new DeviceSettingHelperImpl(context); mUserManager = Objects.requireNonNull(userManager); } @Override Loading @@ -65,18 +70,17 @@ class CallerValidatorImpl implements CallerValidator { } @Override @NonNull @BinderThread public UserHandle verifyTargetUserHandle( public void verifyTargetUserHandle( @NonNull UserHandle targetUserHandle, @NonNull String claimedCallingPackage) { int callingPid = Binder.getCallingPid(); int callingUid = Binder.getCallingUid(); final long callingIdentityToken = Binder.clearCallingIdentity(); try { if (Flags.appFunctionAccessServiceEnabled()) { return handleIncomingUserCrossUserNotAllowed(targetUserHandle, callingUid); enforceNoCrossUserOrSecondaryProfileInteraction(targetUserHandle, callingUid); } else { return handleIncomingUser( enforceConditionalCrossUserInteraction( claimedCallingPackage, targetUserHandle, callingPid, callingUid); } } finally { Loading Loading @@ -174,29 +178,25 @@ class CallerValidatorImpl implements CallerValidator { } /** * Helper for dealing with incoming user arguments to system service calls. * * <p>Takes care of checking permissions and if the target is special user, this method will * simply throw. * Enforces that cross user interaction is only allowed when the caller has * INTERACT_ACROSS_USERS_FULL permission. * * @param callingPackageName The package name of the caller. * @param targetUserHandle The user which the caller is requesting to execute as. * @param callingPid The actual pid of the caller as determined by Binder. * @param callingUid The actual uid of the caller as determined by Binder. * @return the user handle that the call should run as. Will always be a concrete user. * @throws IllegalArgumentException if the target user is a special user. * @throws SecurityException if caller trying to interact across user without {@link * Manifest.permission#INTERACT_ACROSS_USERS_FULL} */ @NonNull private UserHandle handleIncomingUser( private void enforceConditionalCrossUserInteraction( @NonNull String callingPackageName, @NonNull UserHandle targetUserHandle, int callingPid, int callingUid) { UserHandle callingUserHandle = UserHandle.getUserHandleForUid(callingUid); if (callingUserHandle.equals(targetUserHandle)) { return targetUserHandle; return; } // Duplicates UserController#ensureNotSpecialUser Loading @@ -218,7 +218,7 @@ class CallerValidatorImpl implements CallerValidator { + " haven't installed for user " + targetUserHandle.getIdentifier()); } return targetUserHandle; return; } throw new SecurityException( "Permission denied while calling from uid " Loading @@ -230,23 +230,17 @@ class CallerValidatorImpl implements CallerValidator { } /** * Helper for dealing with incoming user arguments to system service calls. * * <p>Takes care of if interaction is cross user, this method will simply throw. * Enforce that any cross profile interaction or calling from secondary profile are not allowed. * * @param targetUserHandle The user which the caller is requesting to execute as. * @param callingUid The actual uid of the caller as determined by Binder. * @return the user handle that the call should run as. Will always be a concrete user. * @throws SecurityException if caller trying to interact across user. * @throws SecurityException if caller trying to interact across user or within secondary * profile. */ @NonNull private UserHandle handleIncomingUserCrossUserNotAllowed( private void enforceNoCrossUserOrSecondaryProfileInteraction( @NonNull UserHandle targetUserHandle, int callingUid) { UserHandle callingUserHandle = UserHandle.getUserHandleForUid(callingUid); if (callingUserHandle.equals(targetUserHandle)) { return targetUserHandle; } if (!callingUserHandle.equals(targetUserHandle)) { throw new SecurityException( "Permission denied while calling from uid " + callingUid Loading @@ -255,6 +249,11 @@ class CallerValidatorImpl implements CallerValidator { + "; Cross user interaction is not allowed"); } if (mUserManager.isProfile(targetUserHandle.getIdentifier())) { throw new SecurityException("Permission denied while calling from secondary profile"); } } /** * Checks that the caller's supposed package name matches the uid making the call. * Loading Loading
services/appfunctions/java/com/android/server/appfunctions/AppFunctionManagerServiceImpl.java +5 −1 Original line number Diff line number Diff line Loading @@ -75,6 +75,7 @@ import android.os.RemoteException; import android.os.ResultReceiver; import android.os.ShellCallback; import android.os.UserHandle; import android.os.UserManager; import android.permission.flags.Flags; import android.provider.DeviceConfig; import android.text.TextUtils; Loading Loading @@ -149,7 +150,10 @@ public class AppFunctionManagerServiceImpl extends IAppFunctionManager.Stub { context, new RemoteServiceCallerImpl<>( context, IAppFunctionService.Stub::asInterface, THREAD_POOL_EXECUTOR), new CallerValidatorImpl(context, appFunctionAccessServiceInterface), new CallerValidatorImpl( context, appFunctionAccessServiceInterface, Objects.requireNonNull(context.getSystemService(UserManager.class))), new ServiceHelperImpl(context), new ServiceConfigImpl(), new AppFunctionsLoggerWrapper(context), Loading
services/appfunctions/java/com/android/server/appfunctions/CallerValidator.java +6 −7 Original line number Diff line number Diff line Loading @@ -52,12 +52,11 @@ public interface CallerValidator { * * @param targetUserHandle The user which the caller is requesting to execute as. * @param claimedCallingPackage The package name of the caller. * @return The user handle that the call should run as. Will always be a concrete user. * @throws IllegalArgumentException if the target user is a special user. * @throws SecurityException if caller trying to interact across users without {@link * Manifest.permission#INTERACT_ACROSS_USERS_FULL} */ UserHandle verifyTargetUserHandle( void verifyTargetUserHandle( @NonNull UserHandle targetUserHandle, @NonNull String claimedCallingPackage); /** Loading Loading @@ -103,8 +102,8 @@ public interface CallerValidator { int CAN_EXECUTE_APP_FUNCTIONS_ALLOWED_SAME_PACKAGE = 1; /** * Callers can execute app functions because they have the necessary permission. * This case also applies when a caller with the permission invokes their own app functions. * Callers can execute app functions because they have the necessary permission. This case also * applies when a caller with the permission invokes their own app functions. */ int CAN_EXECUTE_APP_FUNCTIONS_ALLOWED_HAS_PERMISSION = 2; Loading
services/appfunctions/java/com/android/server/appfunctions/CallerValidatorImpl.java +28 −29 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import android.content.pm.PackageManager; import android.os.Binder; import android.os.Process; import android.os.UserHandle; import android.os.UserManager; import android.permission.flags.Flags; import com.android.internal.infra.AndroidFuture; Loading @@ -42,12 +43,16 @@ class CallerValidatorImpl implements CallerValidator { private final DeviceSettingHelper mDeviceSettingHelper; private final UserManager mUserManager; CallerValidatorImpl( @NonNull Context context, @NonNull AppFunctionAccessServiceInterface appFunctionAccessService) { @NonNull AppFunctionAccessServiceInterface appFunctionAccessService, @NonNull UserManager userManager) { mContext = Objects.requireNonNull(context); mAppFunctionAccessService = Objects.requireNonNull(appFunctionAccessService); mDeviceSettingHelper = new DeviceSettingHelperImpl(context); mUserManager = Objects.requireNonNull(userManager); } @Override Loading @@ -65,18 +70,17 @@ class CallerValidatorImpl implements CallerValidator { } @Override @NonNull @BinderThread public UserHandle verifyTargetUserHandle( public void verifyTargetUserHandle( @NonNull UserHandle targetUserHandle, @NonNull String claimedCallingPackage) { int callingPid = Binder.getCallingPid(); int callingUid = Binder.getCallingUid(); final long callingIdentityToken = Binder.clearCallingIdentity(); try { if (Flags.appFunctionAccessServiceEnabled()) { return handleIncomingUserCrossUserNotAllowed(targetUserHandle, callingUid); enforceNoCrossUserOrSecondaryProfileInteraction(targetUserHandle, callingUid); } else { return handleIncomingUser( enforceConditionalCrossUserInteraction( claimedCallingPackage, targetUserHandle, callingPid, callingUid); } } finally { Loading Loading @@ -174,29 +178,25 @@ class CallerValidatorImpl implements CallerValidator { } /** * Helper for dealing with incoming user arguments to system service calls. * * <p>Takes care of checking permissions and if the target is special user, this method will * simply throw. * Enforces that cross user interaction is only allowed when the caller has * INTERACT_ACROSS_USERS_FULL permission. * * @param callingPackageName The package name of the caller. * @param targetUserHandle The user which the caller is requesting to execute as. * @param callingPid The actual pid of the caller as determined by Binder. * @param callingUid The actual uid of the caller as determined by Binder. * @return the user handle that the call should run as. Will always be a concrete user. * @throws IllegalArgumentException if the target user is a special user. * @throws SecurityException if caller trying to interact across user without {@link * Manifest.permission#INTERACT_ACROSS_USERS_FULL} */ @NonNull private UserHandle handleIncomingUser( private void enforceConditionalCrossUserInteraction( @NonNull String callingPackageName, @NonNull UserHandle targetUserHandle, int callingPid, int callingUid) { UserHandle callingUserHandle = UserHandle.getUserHandleForUid(callingUid); if (callingUserHandle.equals(targetUserHandle)) { return targetUserHandle; return; } // Duplicates UserController#ensureNotSpecialUser Loading @@ -218,7 +218,7 @@ class CallerValidatorImpl implements CallerValidator { + " haven't installed for user " + targetUserHandle.getIdentifier()); } return targetUserHandle; return; } throw new SecurityException( "Permission denied while calling from uid " Loading @@ -230,23 +230,17 @@ class CallerValidatorImpl implements CallerValidator { } /** * Helper for dealing with incoming user arguments to system service calls. * * <p>Takes care of if interaction is cross user, this method will simply throw. * Enforce that any cross profile interaction or calling from secondary profile are not allowed. * * @param targetUserHandle The user which the caller is requesting to execute as. * @param callingUid The actual uid of the caller as determined by Binder. * @return the user handle that the call should run as. Will always be a concrete user. * @throws SecurityException if caller trying to interact across user. * @throws SecurityException if caller trying to interact across user or within secondary * profile. */ @NonNull private UserHandle handleIncomingUserCrossUserNotAllowed( private void enforceNoCrossUserOrSecondaryProfileInteraction( @NonNull UserHandle targetUserHandle, int callingUid) { UserHandle callingUserHandle = UserHandle.getUserHandleForUid(callingUid); if (callingUserHandle.equals(targetUserHandle)) { return targetUserHandle; } if (!callingUserHandle.equals(targetUserHandle)) { throw new SecurityException( "Permission denied while calling from uid " + callingUid Loading @@ -255,6 +249,11 @@ class CallerValidatorImpl implements CallerValidator { + "; Cross user interaction is not allowed"); } if (mUserManager.isProfile(targetUserHandle.getIdentifier())) { throw new SecurityException("Permission denied while calling from secondary profile"); } } /** * Checks that the caller's supposed package name matches the uid making the call. * Loading