summary refs log tree commit diff
diff options
context:
space:
mode:
authorSean Quah <seanq@matrix.org>2022-08-30 18:31:57 +0100
committerSean Quah <seanq@matrix.org>2022-09-08 14:01:39 +0100
commit18e5f6075618360956db8398dd96ada9399bf5ab (patch)
treece59eae862c5e689a28d92db4aa83dc68b01ab90
parentFix a bug where Synapse fails to start if a signing key file contains an empt... (diff)
downloadsynapse-18e5f6075618360956db8398dd96ada9399bf5ab.tar.xz
Fix bug in device list caching when remote users leave rooms
When a remote user leaves the last room shared with the homeserver, we
have to mark their device list as unsubscribed, otherwise we will hold
on to a stale device list in our cache. Crucially, the device list will
remain cached even after the remote user rejoins the room, which can
lead to E2EE failures until the remote user's device list next changes.

Signed-off-by: Sean Quah <seanq@matrix.org>
-rw-r--r--synapse/storage/controllers/persist_events.py20
1 files changed, 17 insertions, 3 deletions
diff --git a/synapse/storage/controllers/persist_events.py b/synapse/storage/controllers/persist_events.py
index dad3731b9b..501dbbc990 100644
--- a/synapse/storage/controllers/persist_events.py
+++ b/synapse/storage/controllers/persist_events.py
@@ -598,9 +598,9 @@ class EventsPersistenceStorageController:
             # room
             state_delta_for_room: Dict[str, DeltaState] = {}
 
-            # Set of remote users which were in rooms the server has left. We
-            # should check if we still share any rooms and if not we mark their
-            # device lists as stale.
+            # Set of remote users which were in rooms the server has left or who may
+            # have left rooms the server is in. We should check if we still share any
+            # rooms and if not we mark their device lists as stale.
             potentially_left_users: Set[str] = set()
 
             if not backfilled:
@@ -725,6 +725,20 @@ class EventsPersistenceStorageController:
                                 current_state = {}
                                 delta.no_longer_in_room = True
 
+                            # Add all remote users that might have left rooms.
+                            potentially_left_users.update(
+                                user_id
+                                for event_type, user_id in delta.to_delete
+                                if event_type == EventTypes.Member
+                                and not self.is_mine_id(user_id)
+                            )
+                            potentially_left_users.update(
+                                user_id
+                                for event_type, user_id in delta.to_insert.keys()
+                                if event_type == EventTypes.Member
+                                and not self.is_mine_id(user_id)
+                            )
+
                             state_delta_for_room[room_id] = delta
 
             await self.persist_events_store._persist_events_and_state_updates(