Merge commit 'e29c44340' into anoa/dinsic_release_1_18_x
* commit 'e29c44340': Fix recursion error when fetching auth chain over federation (#7817)
This commit is contained in:
1
changelog.d/7817.bugfix
Normal file
1
changelog.d/7817.bugfix
Normal file
@@ -0,0 +1 @@
|
||||
Fix bug where Synapse fails to process an incoming event over federation if the server is missing too much of the event's auth chain.
|
||||
@@ -65,14 +65,16 @@ def check(
|
||||
|
||||
room_id = event.room_id
|
||||
|
||||
# I'm not really expecting to get auth events in the wrong room, but let's
|
||||
# sanity-check it
|
||||
# We need to ensure that the auth events are actually for the same room, to
|
||||
# stop people from using powers they've been granted in other rooms for
|
||||
# example.
|
||||
for auth_event in auth_events.values():
|
||||
if auth_event.room_id != room_id:
|
||||
raise Exception(
|
||||
raise AuthError(
|
||||
403,
|
||||
"During auth for event %s in room %s, found event %s in the state "
|
||||
"which is in room %s"
|
||||
% (event.event_id, room_id, auth_event.event_id, auth_event.room_id)
|
||||
% (event.event_id, room_id, auth_event.event_id, auth_event.room_id),
|
||||
)
|
||||
|
||||
if do_sig_check:
|
||||
|
||||
@@ -621,6 +621,11 @@ class FederationHandler(BaseHandler):
|
||||
will be omitted from the result. Likewise, any events which turn out not to
|
||||
be in the given room.
|
||||
|
||||
This function *does not* automatically get missing auth events of the
|
||||
newly fetched events. Callers must include the full auth chain of
|
||||
of the missing events in the `event_ids` argument, to ensure that any
|
||||
missing auth events are correctly fetched.
|
||||
|
||||
Returns:
|
||||
map from event_id to event
|
||||
"""
|
||||
@@ -1134,12 +1139,16 @@ class FederationHandler(BaseHandler):
|
||||
):
|
||||
"""Fetch the given events from a server, and persist them as outliers.
|
||||
|
||||
This function *does not* recursively get missing auth events of the
|
||||
newly fetched events. Callers must include in the `events` argument
|
||||
any missing events from the auth chain.
|
||||
|
||||
Logs a warning if we can't find the given event.
|
||||
"""
|
||||
|
||||
room_version = await self.store.get_room_version(room_id)
|
||||
|
||||
event_infos = []
|
||||
event_map = {} # type: Dict[str, EventBase]
|
||||
|
||||
async def get_event(event_id: str):
|
||||
with nested_logging_context(event_id):
|
||||
@@ -1153,17 +1162,7 @@ class FederationHandler(BaseHandler):
|
||||
)
|
||||
return
|
||||
|
||||
# recursively fetch the auth events for this event
|
||||
auth_events = await self._get_events_from_store_or_dest(
|
||||
destination, room_id, event.auth_event_ids()
|
||||
)
|
||||
auth = {}
|
||||
for auth_event_id in event.auth_event_ids():
|
||||
ae = auth_events.get(auth_event_id)
|
||||
if ae:
|
||||
auth[(ae.type, ae.state_key)] = ae
|
||||
|
||||
event_infos.append(_NewEventInfo(event, None, auth))
|
||||
event_map[event.event_id] = event
|
||||
|
||||
except Exception as e:
|
||||
logger.warning(
|
||||
@@ -1175,6 +1174,32 @@ class FederationHandler(BaseHandler):
|
||||
|
||||
await concurrently_execute(get_event, events, 5)
|
||||
|
||||
# Make a map of auth events for each event. We do this after fetching
|
||||
# all the events as some of the events' auth events will be in the list
|
||||
# of requested events.
|
||||
|
||||
auth_events = [
|
||||
aid
|
||||
for event in event_map.values()
|
||||
for aid in event.auth_event_ids()
|
||||
if aid not in event_map
|
||||
]
|
||||
persisted_events = await self.store.get_events(
|
||||
auth_events, allow_rejected=True,
|
||||
)
|
||||
|
||||
event_infos = []
|
||||
for event in event_map.values():
|
||||
auth = {}
|
||||
for auth_event_id in event.auth_event_ids():
|
||||
ae = persisted_events.get(auth_event_id) or event_map.get(auth_event_id)
|
||||
if ae:
|
||||
auth[(ae.type, ae.state_key)] = ae
|
||||
else:
|
||||
logger.info("Missing auth event %s", auth_event_id)
|
||||
|
||||
event_infos.append(_NewEventInfo(event, None, auth))
|
||||
|
||||
await self._handle_new_events(
|
||||
destination, event_infos,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user