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

Commit 78a94767 authored by MingWei Liao's avatar MingWei Liao Committed by Android (Google) Code Review
Browse files

Merge "Block AppFunction access within secondary profiles" into main

parents e32fb053 11adb12a
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -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;
@@ -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),
+6 −7
Original line number Diff line number Diff line
@@ -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);

    /**
@@ -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;

+28 −29
Original line number Diff line number Diff line
@@ -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;
@@ -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
@@ -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 {
@@ -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
@@ -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 "
@@ -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
@@ -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.
     *