From 2c9c50711f250ff7af20e7bc3a2dc6a96f653577 Mon Sep 17 00:00:00 2001 From: Jon Chambers <63609320+jon-signal@users.noreply.github.com> Date: Thu, 10 Nov 2022 12:41:50 -0500 Subject: [PATCH] Avoid reading from a stale `Account` after a contested reglock event --- .../textsecuregcm/controllers/AccountController.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/controllers/AccountController.java b/service/src/main/java/org/whispersystems/textsecuregcm/controllers/AccountController.java index 2a151a9aa..ec3863918 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/controllers/AccountController.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/controllers/AccountController.java @@ -808,20 +808,22 @@ public class AccountController { rateLimiters.getPinLimiter().validate(existingAccount.getNumber()); } + final String phoneNumber = existingAccount.getNumber(); + if (!existingRegistrationLock.verify(clientRegistrationLock)) { // At this point, the client verified ownership of the phone number but doesn’t have the reglock PIN. // Freezing the existing account credentials will definitively start the reglock timeout. Until the timeout, the current reglock can still be supplied, // along with phone number verification, to restore access. - accounts.update(existingAccount, Account::lockAuthenticationCredentials); - List deviceIds = existingAccount.getDevices().stream().map(Device::getId).toList(); - clientPresenceManager.disconnectAllPresences(existingAccount.getUuid(), deviceIds); + final Account updatedAccount = accounts.update(existingAccount, Account::lockAuthenticationCredentials); + List deviceIds = updatedAccount.getDevices().stream().map(Device::getId).toList(); + clientPresenceManager.disconnectAllPresences(updatedAccount.getUuid(), deviceIds); throw new WebApplicationException(Response.status(423) .entity(new RegistrationLockFailure(existingRegistrationLock.getTimeRemaining(), existingRegistrationLock.needsFailureCredentials() ? existingBackupCredentials : null)) .build()); } - rateLimiters.getPinLimiter().clear(existingAccount.getNumber()); + rateLimiters.getPinLimiter().clear(phoneNumber); } }