Stopgap fix for credential change of unified-challenge profile

LockSettingsService regressed in Android 11 that it no longer always
discard the original credential parameter when performing credential
changes for unified-challenge profile. Add a stopgap fix to restore
that behaviour and document idea for long term fix.

Bug: 147663267
Test: Fire ACTION_SET_NEW_PASSWORD from profile to set a separate
      work challenge. Verify the flow succeeds.
Change-Id: Idc7f67c6cd021a779fdcd1992cd5cbbd337c4e52
This commit is contained in:
Rubin Xu
2020-03-06 14:34:16 +00:00
parent 02b288d66e
commit 0090c5857f
2 changed files with 21 additions and 0 deletions

View File

@@ -1572,6 +1572,24 @@ public class LockSettingsService extends ILockSettings.Stub {
"This operation requires secure lock screen feature");
}
checkWritePermission(userId);
// When changing credential for profiles with unified challenge, some callers
// will pass in empty credential while others will pass in the credential of
// the parent user. setLockCredentialInternal() handles the formal case (empty
// credential) correctly but not the latter. As a stopgap fix, convert the latter
// case to the formal. The long-term fix would be fixing LSS such that it should
// accept only the parent user credential on its public API interfaces, swap it
// with the profile's random credential at that API boundary (i.e. here) and make
// sure LSS internally does not special case profile with unififed challenge: b/80170828.
if (!savedCredential.isNone() && isManagedProfileWithUnifiedLock(userId)) {
// Verify the parent credential again, to make sure we have a fresh enough
// auth token such that getDecryptedPasswordForTiedProfile() inside
// setLockCredentialInternal() can function correctly.
verifyCredential(savedCredential, /* challenge */ 0,
mUserManager.getProfileParent(userId).id);
savedCredential.zeroize();
savedCredential = LockscreenCredential.createNone();
}
synchronized (mSeparateChallengeLock) {
if (!setLockCredentialInternal(credential, savedCredential,
userId, /* isLockTiedToParent= */ false)) {
@@ -1627,6 +1645,7 @@ public class LockSettingsService extends ILockSettings.Stub {
// get credential from keystore when managed profile has unified lock
if (savedCredential.isNone()) {
try {
//TODO: remove as part of b/80170828
savedCredential = getDecryptedPasswordForTiedProfile(userId);
} catch (FileNotFoundException e) {
Slog.i(TAG, "Child profile key not found");
@@ -2876,6 +2895,7 @@ public class LockSettingsService extends ILockSettings.Stub {
if (savedCredential.isNone() && isManagedProfileWithUnifiedLock(userId)) {
// get credential from keystore when managed profile has unified lock
try {
//TODO: remove as part of b/80170828
savedCredential = getDecryptedPasswordForTiedProfile(userId);
} catch (FileNotFoundException e) {
Slog.i(TAG, "Child profile key not found");

View File

@@ -236,6 +236,7 @@ public class LockSettingsServiceTests extends BaseLockSettingsServiceTests {
@Test
public void testSetLockCredential_forProfileWithSeparateChallenge_updatesCredentials()
throws Exception {
mService.setSeparateProfileChallengeEnabled(MANAGED_PROFILE_USER_ID, true, null);
initializeStorageWithCredential(
MANAGED_PROFILE_USER_ID,
newPattern("12345"),