on master help sign in
Fix session token timing side channel and ackedIds capacity violation in server.knot
35cfa8diko
server.knot+9−14
@@ -320,7 +320,7 @@ isBadServerName = \s ->
320lookupSession = \sessions token t ->
320lookupSession = \sessions token t ->
321 single (do
321 single (do
322 s <- sessions
322 s <- sessions
323− where s.token == token
323+ where safeCompare s.token token
324 where s.expiresAt > t
324 where s.expiresAt > t
325 yield s)
325 yield s)
326
326
@@ -859,11 +859,16 @@ serve = \req -> case req of
859 yield {messageId: m.messageId, toKey: m.toKey, ackedAt: t, originServer: m.originServer}
859 yield {messageId: m.messageId, toKey: m.toKey, ackedAt: t, originServer: m.originServer}
860 ackedIds <- *ackedIds
860 ackedIds <- *ackedIds
861 let combinedAckedIds = union ackedIds ackedFederated
861 let combinedAckedIds = union ackedIds ackedFederated
862+ let excessCount = count combinedAckedIds - maxAckedIds
863+ let afterEviction = if excessCount <= 0 then combinedAckedIds
864+ else evictOldestAckedIds combinedAckedIds excessCount
865+ let evictedEntries = if excessCount <= 0 then []
866+ else diff combinedAckedIds afterEviction
862− set *ackedIds = combinedAckedIds
867+ set *ackedIds = afterEviction
863 let ok = case session of
868 let ok = case session of
864 Nothing {} -> False {}
869 Nothing {} -> False {}
865 _ -> True {}
870 _ -> True {}
866− yield {ok: ok, ackedMessages: ackedMessages, expiredLocal: pr.expiredLocal, peerServers: pr.peerServers}
871+ yield {ok: ok, ackedMessages: ackedMessages, expiredLocal: pr.expiredLocal, peerServers: pr.peerServers, evictedEntries: evictedEntries}
867 let fedMessages = do
872 let fedMessages = do
868 m <- result.ackedMessages
873 m <- result.ackedMessages
869 where not (m.originServer == "")
874 where not (m.originServer == "")
@@ -882,18 +887,8 @@ serve = \req -> case req of
882 else yield {}
887 else yield {}
883 if result.ok
888 if result.ok
884 then do
889 then do
885− evictedEntries <- atomic do
886− ackedIds <- *ackedIds
887− let excessCount = count ackedIds - maxAckedIds
888− if excessCount <= 0
889− then yield []
890− else do
891− let afterEviction = evictOldestAckedIds ackedIds excessCount
892− let evicted = diff ackedIds afterEviction
893− set *ackedIds = afterEviction
894− yield evicted
895 let evictedToRetry = do
890 let evictedToRetry = do
896− a <- evictedEntries
891+ a <- result.evictedEntries
897 where count (do m <- fedMessages; where m.messageId == a.messageId; where m.toKey == a.toKey; yield m) == 0
892 where count (do m <- fedMessages; where m.messageId == a.messageId; where m.toKey == a.toKey; yield m) == 0
898 yield a
893 yield a
899 if count evictedToRetry > 0 && not (federationSecret == "")
894 if count evictedToRetry > 0 && not (federationSecret == "")