diff options
| -rw-r--r-- | services/core/java/com/android/server/locksettings/LockSettingsService.java | 76 |
1 files changed, 54 insertions, 22 deletions
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java index 1a8de9771451..90370ddd21dd 100644 --- a/services/core/java/com/android/server/locksettings/LockSettingsService.java +++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java @@ -1616,6 +1616,7 @@ public class LockSettingsService extends ILockSettings.Stub { synchronized (mSeparateChallengeLock) { if (!setLockCredentialInternal(credential, savedCredential, userId, /* isLockTiedToParent= */ false)) { + scheduleGc(); return false; } setSeparateProfileChallengeEnabledLocked(userId, true, /* unused */ null); @@ -1626,6 +1627,7 @@ public class LockSettingsService extends ILockSettings.Stub { setDeviceUnlockedForUser(userId); } notifySeparateProfileChallengeChanged(userId); + scheduleGc(); return true; } @@ -1965,7 +1967,11 @@ public class LockSettingsService extends ILockSettings.Stub { public VerifyCredentialResponse checkCredential(LockscreenCredential credential, int userId, ICheckCredentialProgressCallback progressCallback) { checkPasswordReadPermission(userId); - return doVerifyCredential(credential, CHALLENGE_NONE, 0, userId, progressCallback); + try { + return doVerifyCredential(credential, CHALLENGE_NONE, 0, userId, progressCallback); + } finally { + scheduleGc(); + } } @Override @@ -1978,8 +1984,12 @@ public class LockSettingsService extends ILockSettings.Stub { challengeType = CHALLENGE_NONE; } - return doVerifyCredential(credential, challengeType, challenge, userId, - null /* progressCallback */); + try { + return doVerifyCredential(credential, challengeType, challenge, userId, + null /* progressCallback */); + } finally { + scheduleGc(); + } } private VerifyCredentialResponse doVerifyCredential(LockscreenCredential credential, @@ -2070,6 +2080,8 @@ public class LockSettingsService extends ILockSettings.Stub { | BadPaddingException | CertificateException | IOException e) { Slog.e(TAG, "Failed to decrypt child profile key", e); throw new IllegalStateException("Unable to get tied profile token"); + } finally { + scheduleGc(); } } @@ -2983,27 +2995,31 @@ public class LockSettingsService extends ILockSettings.Stub { @Override public byte[] getHashFactor(LockscreenCredential currentCredential, int userId) { checkPasswordReadPermission(userId); - if (isManagedProfileWithUnifiedLock(userId)) { - try { - currentCredential = getDecryptedPasswordForTiedProfile(userId); - } catch (Exception e) { - Slog.e(TAG, "Failed to get work profile credential", e); - return null; - } - } - synchronized (mSpManager) { - if (!isSyntheticPasswordBasedCredentialLocked(userId)) { - Slog.w(TAG, "Synthetic password not enabled"); - return null; + try { + if (isManagedProfileWithUnifiedLock(userId)) { + try { + currentCredential = getDecryptedPasswordForTiedProfile(userId); + } catch (Exception e) { + Slog.e(TAG, "Failed to get work profile credential", e); + return null; + } } - long handle = getSyntheticPasswordHandleLocked(userId); - AuthenticationResult auth = mSpManager.unwrapPasswordBasedSyntheticPassword( - getGateKeeperService(), handle, currentCredential, userId, null); - if (auth.authToken == null) { - Slog.w(TAG, "Current credential is incorrect"); - return null; + synchronized (mSpManager) { + if (!isSyntheticPasswordBasedCredentialLocked(userId)) { + Slog.w(TAG, "Synthetic password not enabled"); + return null; + } + long handle = getSyntheticPasswordHandleLocked(userId); + AuthenticationResult auth = mSpManager.unwrapPasswordBasedSyntheticPassword( + getGateKeeperService(), handle, currentCredential, userId, null); + if (auth.authToken == null) { + Slog.w(TAG, "Current credential is incorrect"); + return null; + } + return auth.authToken.derivePasswordHashFactor(); } - return auth.authToken.derivePasswordHashFactor(); + } finally { + scheduleGc(); } } @@ -3287,6 +3303,22 @@ public class LockSettingsService extends ILockSettings.Stub { } } + /** + * Schedules garbage collection to sanitize lockscreen credential remnants in memory. + * + * One source of leftover lockscreen credentials is the unmarshalled binder method arguments. + * Since this method will be called within the binder implementation method, a small delay is + * added before the GC operation to allow the enclosing binder proxy code to complete and + * release references to the argument. + */ + private void scheduleGc() { + mHandler.postDelayed(() -> { + System.gc(); + System.runFinalization(); + System.gc(); + }, 2000); + } + private class DeviceProvisionedObserver extends ContentObserver { private final Uri mDeviceProvisionedUri = Settings.Global.getUriFor( Settings.Global.DEVICE_PROVISIONED); |