summaryrefslogtreecommitdiffhomepage
path: root/PrevActivity.hs
diff options
context:
space:
mode:
authorJoey Hess <joeyh@joeyh.name>2017-04-30 13:54:02 -0400
committerJoey Hess <joeyh@joeyh.name>2017-04-30 13:54:02 -0400
commitb47e621749257331788e82e44d1565cf4d32d04b (patch)
treed6c3445be85b05fc58675552fc1bfb4f0ceb375d /PrevActivity.hs
parent89d4e18cdb6ed1c3e7916dd66cf907bedf58a549 (diff)
downloaddebug-me-b47e621749257331788e82e44d1565cf4d32d04b.tar.gz
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.
Diffstat (limited to 'PrevActivity.hs')
-rw-r--r--PrevActivity.hs19
1 files changed, 8 insertions, 11 deletions
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) ->