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

Commit 4419a439 authored by Cintia Martins's avatar Cintia Martins Committed by Android (Google) Code Review
Browse files

Merge "Ensure setSupervisionEnabledForUser caller is SystemUid" into main

parents 57ea97e6 1472faf7
Loading
Loading
Loading
Loading
+20 −1
Original line number Diff line number Diff line
@@ -51,6 +51,7 @@ import android.os.Bundle;
import android.os.IBinder;
import android.os.IInterface;
import android.os.PersistableBundle;
import android.os.Process;
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.ShellCallback;
@@ -77,6 +78,7 @@ import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/** Service for handling system supervision. */
public class SupervisionService extends ISupervisionManager.Stub {
@@ -136,7 +138,7 @@ public class SupervisionService extends ISupervisionManager.Stub {

    @Override
    public void setSupervisionEnabledForUser(@UserIdInt int userId, boolean enabled) {
        // TODO(b/395630828): Ensure that this method can only be called by the system.
        enforceSystemCaller();
        if (UserHandle.getUserId(Binder.getCallingUid()) != userId) {
            enforcePermission(INTERACT_ACROSS_USERS);
        }
@@ -556,6 +558,13 @@ public class SupervisionService extends ISupervisionManager.Stub {
        checkCallAuthorization(authorized);
    }

    /** Enforces that the caller is the system. */
    private void enforceSystemCaller() {
        int callingUid = mInjector.getCallingUid();
        checkCallAuthorization(UserHandle.isSameApp(callingUid, Process.SYSTEM_UID),
              "Caller with UID %s is not authorized.", callingUid);
    }

    /** Provides local services in a lazy manner. */
    static class Injector {
        public Context context;
@@ -565,6 +574,7 @@ public class SupervisionService extends ISupervisionManager.Stub {
        private KeyguardManager mKeyguardManager;
        private PackageManager mPackageManager;
        private UserManagerInternal mUserManagerInternal;
        private Integer mCallingUid;

        Injector(Context context) {
            this.context = context;
@@ -606,6 +616,15 @@ public class SupervisionService extends ISupervisionManager.Stub {
            }
            return mUserManagerInternal;
        }

        int getCallingUid() {
            return Objects.requireNonNullElseGet(mCallingUid, Binder::getCallingUid);
        }

        @VisibleForTesting
        public void setCallingUid(int Uid) {
            mCallingUid = Uid;
        }
    }

    /** Publishes local and binder services and allows the service to act during initialization. */
+17 −2
Original line number Diff line number Diff line
@@ -30,7 +30,6 @@ import android.content.Context
import android.content.ContextWrapper
import android.content.Intent
import android.content.IntentFilter
import android.os.IBinder
import android.content.pm.PackageManager
import android.content.pm.UserInfo
import android.content.pm.UserInfo.FLAG_FOR_TESTING
@@ -38,7 +37,9 @@ import android.content.pm.UserInfo.FLAG_FULL
import android.content.pm.UserInfo.FLAG_MAIN
import android.content.pm.UserInfo.FLAG_SYSTEM
import android.os.Handler
import android.os.IBinder
import android.os.PersistableBundle
import android.os.Process
import android.os.UserHandle
import android.os.UserHandle.MIN_SECONDARY_USER_ID
import android.os.UserHandle.USER_SYSTEM
@@ -56,6 +57,7 @@ import com.android.server.LocalServices
import com.android.server.SystemService.TargetUser
import com.android.server.pm.UserManagerInternal
import com.android.server.supervision.SupervisionService.ACTION_CONFIRM_SUPERVISION_CREDENTIALS
import com.android.server.supervision.SupervisionService.Injector
import com.google.common.truth.Truth.assertThat
import java.nio.file.Files
import org.junit.Before
@@ -73,6 +75,7 @@ import org.mockito.kotlin.mock
import org.mockito.kotlin.never
import org.mockito.kotlin.verify
import org.mockito.kotlin.whenever
import org.testng.Assert.assertThrows

/**
 * Unit tests for [SupervisionService].
@@ -94,6 +97,7 @@ class SupervisionServiceTest {
    private lateinit var context: Context
    private lateinit var lifecycle: SupervisionService.Lifecycle
    private lateinit var service: SupervisionService
    private lateinit var injector: Injector

    @Before
    fun setUp() {
@@ -110,10 +114,12 @@ class SupervisionServiceTest {
        SupervisionSettings.getInstance()
            .changeDirForTesting(Files.createTempDirectory("tempSupervisionFolder").toFile())

        service = SupervisionService(context)
        injector = Injector(context.createAttributionContext(SupervisionLog.TAG));
        service = SupervisionService(injector)
        lifecycle = SupervisionService.Lifecycle(context, service)
        lifecycle.registerProfileOwnerListener()

        injector.callingUid = Process.SYSTEM_UID
        assertThat(service.isSupervisionEnabledForUser(USER_ID)).isFalse()
    }

@@ -270,6 +276,15 @@ class SupervisionServiceTest {
        assertThat(getSecureSetting(SEARCH_CONTENT_FILTERS_ENABLED)).isEqualTo(-1)
    }

    @Test
    fun setSupervisionEnabledForUser_callerIsNotSystemUid_throwsException() {
        injector.callingUid = Process.NOBODY_UID

        assertThrows(SecurityException::class.java) {
            service.setSupervisionEnabledForUser(USER_ID, true);
        }
    }

    @Test
    @RequiresFlagsEnabled(Flags.FLAG_ENABLE_REMOVE_POLICIES_ON_SUPERVISION_DISABLE)
    fun setSupervisionEnabledForUser_removesPoliciesWhenDisabling() {