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

Commit e192d4e8 authored by Eric Biggers's avatar Eric Biggers Committed by Android (Google) Code Review
Browse files

Merge changes I574d6a3f,Ic81d04b7

* changes:
  Lock down the ability to read from the locksettings database
  DPMS: add permission check to getDeviceOwnerLockScreenInfo()
parents 90cc54ec b0bcbce7
Loading
Loading
Loading
Loading
+17 −39
Original line number Diff line number Diff line
@@ -18,7 +18,6 @@ package com.android.server.locksettings;

import static android.Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE;
import static android.Manifest.permission.MANAGE_BIOMETRIC;
import static android.Manifest.permission.READ_CONTACTS;
import static android.Manifest.permission.SET_AND_VERIFY_LOCKSCREEN_CREDENTIALS;
import static android.Manifest.permission.SET_INITIAL_LOCK;
import static android.app.admin.DevicePolicyManager.DEPRECATE_USERMANAGERINTERNAL_DEVICEPOLICY_DEFAULT;
@@ -99,7 +98,6 @@ import android.os.storage.IStorageManager;
import android.os.storage.StorageManager;
import android.provider.DeviceConfig;
import android.provider.Settings;
import android.provider.Settings.Secure;
import android.security.AndroidKeyStoreMaintenance;
import android.security.Authorization;
import android.security.KeyStore;
@@ -1085,27 +1083,21 @@ public class LockSettingsService extends ILockSettings.Stub {
        mContext.enforceCallingOrSelfPermission(PERMISSION, "LockSettingsHave");
    }

    private final void checkReadPermission(String requestedKey, int userId) {
        final int callingUid = Binder.getCallingUid();

        for (int i = 0; i < READ_CONTACTS_PROTECTED_SETTINGS.length; i++) {
            String key = READ_CONTACTS_PROTECTED_SETTINGS[i];
            if (key.equals(requestedKey) && mContext.checkCallingOrSelfPermission(READ_CONTACTS)
                    != PackageManager.PERMISSION_GRANTED) {
                throw new SecurityException("uid=" + callingUid
                        + " needs permission " + READ_CONTACTS + " to read "
                        + requestedKey + " for user " + userId);
            }
        }
    private static final String[] UNPROTECTED_SETTINGS = {
        // These three LOCK_PATTERN_* settings have traditionally been readable via the public API
        // android.provider.Settings.{System,Secure}.getString() without any permission.
        Settings.Secure.LOCK_PATTERN_ENABLED,
        Settings.Secure.LOCK_PATTERN_VISIBLE,
        Settings.Secure.LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED,
    };

        for (int i = 0; i < READ_PASSWORD_PROTECTED_SETTINGS.length; i++) {
            String key = READ_PASSWORD_PROTECTED_SETTINGS[i];
            if (key.equals(requestedKey) && mContext.checkCallingOrSelfPermission(PERMISSION)
                    != PackageManager.PERMISSION_GRANTED) {
                throw new SecurityException("uid=" + callingUid
                        + " needs permission " + PERMISSION + " to read "
                        + requestedKey + " for user " + userId);
    private final void checkDatabaseReadPermission(String requestedKey, int userId) {
        if (ArrayUtils.contains(UNPROTECTED_SETTINGS, requestedKey)) {
            return;
        }
        if (!hasPermission(PERMISSION)) {
            throw new SecurityException("uid=" + getCallingUid() + " needs permission "
                    + PERMISSION + " to read " + requestedKey + " for user " + userId);
        }
    }

@@ -1134,7 +1126,7 @@ public class LockSettingsService extends ILockSettings.Stub {

    @Override
    public boolean getSeparateProfileChallengeEnabled(int userId) {
        checkReadPermission(SEPARATE_PROFILE_CHALLENGE_KEY, userId);
        checkDatabaseReadPermission(SEPARATE_PROFILE_CHALLENGE_KEY, userId);
        return getSeparateProfileChallengeEnabledInternal(userId);
    }

@@ -1215,7 +1207,7 @@ public class LockSettingsService extends ILockSettings.Stub {

    @Override
    public boolean getBoolean(String key, boolean defaultValue, int userId) {
        checkReadPermission(key, userId);
        checkDatabaseReadPermission(key, userId);
        if (Settings.Secure.LOCK_PATTERN_ENABLED.equals(key)) {
            return getCredentialTypeInternal(userId) == CREDENTIAL_TYPE_PATTERN;
        }
@@ -1224,13 +1216,13 @@ public class LockSettingsService extends ILockSettings.Stub {

    @Override
    public long getLong(String key, long defaultValue, int userId) {
        checkReadPermission(key, userId);
        checkDatabaseReadPermission(key, userId);
        return mStorage.getLong(key, defaultValue, userId);
    }

    @Override
    public String getString(String key, String defaultValue, int userId) {
        checkReadPermission(key, userId);
        checkDatabaseReadPermission(key, userId);
        return mStorage.getString(key, defaultValue, userId);
    }

@@ -2565,20 +2557,6 @@ public class LockSettingsService extends ILockSettings.Stub {
        return mRecoverableKeyStoreManager.validateRemoteLockscreen(encryptedCredential, this);
    }

    // Reading these settings needs the contacts permission
    private static final String[] READ_CONTACTS_PROTECTED_SETTINGS = new String[] {
            Secure.LOCK_SCREEN_OWNER_INFO_ENABLED,
            Secure.LOCK_SCREEN_OWNER_INFO
    };

    // Reading these settings needs the same permission as checking the password
    private static final String[] READ_PASSWORD_PROTECTED_SETTINGS = new String[] {
            LockPatternUtils.LOCK_PASSWORD_SALT_KEY,
            LockPatternUtils.PASSWORD_HISTORY_KEY,
            LockPatternUtils.PASSWORD_TYPE_KEY,
            SEPARATE_PROFILE_CHALLENGE_KEY
    };

    private class GateKeeperDiedRecipient implements IBinder.DeathRecipient {
        @Override
        public void binderDied() {
+5 −1
Original line number Diff line number Diff line
@@ -9321,7 +9321,11 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
    @Override
    public CharSequence getDeviceOwnerLockScreenInfo() {
        return mLockPatternUtils.getDeviceOwnerInfo();
        final CallerIdentity caller = getCallerIdentity();
        Preconditions.checkCallAuthorization(
                isDefaultDeviceOwner(caller) || isProfileOwnerOfOrganizationOwnedDevice(caller));
        return mInjector.binderWithCleanCallingIdentity(() ->
            mLockPatternUtils.getDeviceOwnerInfo());
    }
    private void clearUserPoliciesLocked(int userId) {