From b47e621749257331788e82e44d1565cf4d32d04b Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Sun, 30 Apr 2017 13:54:02 -0400 Subject: fix probable race in use of restoreHashes I think there was a race where a SessionKey message had been drained from the TChan, but not yet added to the developer state, which was resonsible for recent instability at startup. It manifested as protocol errors where the prevActivity hash was wrongly Nothing. Fixed by adding a MissingHashes type to tag things whose hashes have been stripped, and adding back the hashes when needed, which always happens inside atomically blocks, so won't have such a race. --- PrevActivity.hs | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) (limited to 'PrevActivity.hs') diff --git a/PrevActivity.hs b/PrevActivity.hs index 32e647d..7c5e808 100644 --- a/PrevActivity.hs +++ b/PrevActivity.hs @@ -5,11 +5,11 @@ import Crypto import Control.Concurrent.STM --- | Remove the prevActivity from a message. Doing this before sending +-- | Remove the hashes from a message. Doing this before sending -- it over the wire saves transmitting that data, without weakening -- security at all. -removePrevActivityHash :: AnyMessage -> AnyMessage -removePrevActivityHash msg = case msg of +removeHashes :: AnyMessage -> MissingHashes AnyMessage +removeHashes msg = MissingHashes $ case msg of User (ActivityMessage a) -> User (go a) Developer (ActivityMessage a) -> Developer (go a) _ -> msg @@ -18,15 +18,12 @@ removePrevActivityHash msg = case msg of type RecentActivity = STM (SigVerifier, [Hash]) -noRecentActivity :: RecentActivity -noRecentActivity = return (mempty, []) - --- | Restore the prevActivity to a message received without one. +-- | Restore the hashes to a message received. -- This needs a RecentActivity cache, and it tries hashes from that cache --- as the prevActivity until it finds one that makes the message's --- signature verify. -restorePrevActivityHash :: RecentActivity -> AnyMessage -> STM AnyMessage -restorePrevActivityHash ra msg = case msg of +-- to find the one that was used when the message was sent, at which +-- point the message's signature will verify. +restoreHashes :: RecentActivity -> MissingHashes AnyMessage -> STM AnyMessage +restoreHashes ra (MissingHashes msg) = case msg of User (ActivityMessage act) -> User . ActivityMessage <$> (go act =<< ra) Developer (ActivityMessage act) -> -- cgit v1.2.3