diff options
author | Joey Hess <joeyh@joeyh.name> | 2017-04-30 13:54:02 -0400 |
---|---|---|
committer | Joey Hess <joeyh@joeyh.name> | 2017-04-30 13:54:02 -0400 |
commit | b47e621749257331788e82e44d1565cf4d32d04b (patch) | |
tree | d6c3445be85b05fc58675552fc1bfb4f0ceb375d /PrevActivity.hs | |
parent | 89d4e18cdb6ed1c3e7916dd66cf907bedf58a549 (diff) | |
download | debug-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.hs | 19 |
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) -> |