diff --git a/pkgs/by-name/ma/matrix-continuwuity_latest/0001-fix-backport-SEC10.patch b/pkgs/by-name/ma/matrix-continuwuity_latest/0001-fix-backport-SEC10.patch deleted file mode 100644 index 042b4b12aaf2..000000000000 --- a/pkgs/by-name/ma/matrix-continuwuity_latest/0001-fix-backport-SEC10.patch +++ /dev/null @@ -1,250 +0,0 @@ -From d25c12c343b53ea90025c11808700ad6267f4e59 Mon Sep 17 00:00:00 2001 -From: timedout -Date: Wed, 29 Jul 2026 16:38:05 +0100 -Subject: [PATCH] fix(backport): SEC10 - -Reviewed-By: Ginger -Co-Authored-By: Erwan Leboucher - -(cherry picked from commit 71016a0d7f79289f3bf8d7816c1fec3c85c43153) ---- - src/api/client/sync/v5.rs | 133 +++++++++++++++++++++++++++++++------- - 1 file changed, 111 insertions(+), 22 deletions(-) - -diff --git a/src/api/client/sync/v5.rs b/src/api/client/sync/v5.rs -index 183f3aaac..03a4c1972 100644 ---- a/src/api/client/sync/v5.rs -+++ b/src/api/client/sync/v5.rs -@@ -1,6 +1,6 @@ - use std::{ - cmp::{self, Ordering}, -- collections::{BTreeMap, BTreeSet, HashMap, HashSet, VecDeque}, -+ collections::{BTreeMap, BTreeSet, HashMap, HashSet}, - ops::Deref, - time::Duration, - }; -@@ -28,6 +28,7 @@ - use ruma::{ - DeviceId, OwnedEventId, OwnedRoomId, RoomId, UInt, UserId, - api::client::sync::sync_events::{self, DeviceLists, UnreadNotificationsCount}, -+ assign, - directory::RoomTypeFilter, - events::{ - AnyRawAccountDataEvent, AnySyncEphemeralRoomEvent, AnySyncStateEvent, StateEventType, -@@ -139,6 +140,13 @@ pub(crate) async fn sync_events_v5_route( - let (all_joined_rooms, all_invited_rooms, all_knocked_rooms) = - join3(all_joined_rooms, all_invited_rooms, all_knocked_rooms).await; - -+ let allowed_rooms: BTreeSet = all_joined_rooms -+ .iter() -+ .chain(all_invited_rooms.iter()) -+ .chain(all_knocked_rooms.iter()) -+ .cloned() -+ .collect(); -+ - let all_joined_rooms = all_joined_rooms.iter().map(AsRef::as_ref); - let all_invited_rooms = all_invited_rooms.iter().map(AsRef::as_ref); - let all_knocked_rooms = all_knocked_rooms.iter().map(AsRef::as_ref); -@@ -192,13 +200,14 @@ pub(crate) async fn sync_events_v5_route( - ) - .await; - -- fetch_subscriptions(services, sync_info, &known_rooms, &mut todo_rooms).await; -+ fetch_subscriptions(services, sync_info, &known_rooms, &allowed_rooms, &mut todo_rooms).await; - - response.rooms = process_rooms( - services, - sender_user, - next_batch, - all_invited_rooms.clone(), -+ all_knocked_rooms.clone(), - &todo_rooms, - &mut response, - &body, -@@ -208,6 +217,7 @@ pub(crate) async fn sync_events_v5_route( - if response.rooms.iter().all(|(id, r)| { - r.timeline.is_empty() - && r.required_state.is_empty() -+ && r.invite_state.is_none() - && !response.extensions.receipts.rooms.contains_key(id) - }) && response - .extensions -@@ -238,10 +248,17 @@ async fn fetch_subscriptions( - services: &Services, - (sender_user, sender_device, globalsince, body): SyncInfo<'_>, - known_rooms: &KnownRooms, -+ allowed_rooms: &BTreeSet, - todo_rooms: &mut TodoRooms, - ) { - let mut known_subscription_rooms = BTreeSet::new(); - for (room_id, room) in &body.room_subscriptions { -+ // Silently ignore subscriptions to rooms the user is not a member of -+ // (joined or invited). -+ if !allowed_rooms.contains(room_id) { -+ continue; -+ } -+ - let not_exists = services.rooms.metadata.exists(room_id).eq(&false); - - let is_disabled = services.rooms.metadata.is_disabled(room_id); -@@ -399,11 +416,13 @@ async fn handle_lists<'a, Rooms, AllRooms>( - BTreeMap::default() - } - -+#[allow(clippy::too_many_arguments)] - async fn process_rooms<'a, Rooms>( - services: &Services, - sender_user: &UserId, - next_batch: u64, - all_invited_rooms: Rooms, -+ all_knocked_rooms: Rooms, - todo_rooms: &TodoRooms, - response: &mut sync_events::v5::Response, - body: &sync_events::v5::Request, -@@ -416,38 +435,99 @@ async fn process_rooms<'a, Rooms>( - let roomsincecount = PduCount::Normal(*roomsince); - - let mut timestamp: Option<_> = None; -- let mut invite_state = None; - let (timeline_pdus, limited); - let new_room_id: &RoomId = (*room_id).as_ref(); - if all_invited_rooms.clone().any(is_equal_to!(new_room_id)) { -+ let Ok(invite_count) = services -+ .rooms -+ .state_cache -+ .get_invite_count(room_id, sender_user) -+ .await -+ else { -+ continue; -+ }; -+ -+ if *roomsince >= invite_count { -+ continue; -+ } -+ - // TODO: figure out a timestamp we can use for remote invites -- invite_state = services -+ let invite_state = services - .rooms - .state_cache - .invite_state(sender_user, room_id) - .await - .ok(); - -- (timeline_pdus, limited) = (VecDeque::new(), true); -- } else { -- TimelinePdus { pdus: timeline_pdus, limited } = match load_timeline( -- services, -- sender_user, -- room_id, -- Some(roomsincecount), -- Some(PduCount::from(next_batch)), -- *timeline_limit, -- ) -- .await -- { -- | Ok(value) => value, -- | Err(err) => { -- warn!("Encountered missing timeline in {}, error {}", room_id, err); -- continue; -- }, -+ rooms.insert(room_id.clone(), sync_events::v5::response::Room { -+ initial: Some(roomsince == &0), -+ invite_state, -+ limited: true, -+ ..Default::default() -+ }); -+ continue; -+ } -+ -+ if all_knocked_rooms.clone().any(is_equal_to!(new_room_id)) { -+ let Ok(knock_count) = services -+ .rooms -+ .state_cache -+ .get_knock_count(room_id, sender_user) -+ .await -+ else { -+ continue; - }; -+ -+ if *roomsince >= knock_count { -+ continue; -+ } -+ -+ let Ok(knock_state) = services -+ .rooms -+ .state_cache -+ .knock_state(sender_user, room_id) -+ .await -+ else { -+ continue; -+ }; -+ -+ rooms.insert( -+ room_id.clone(), -+ assign!(sync_events::v5::response::Room::new(), { -+ initial: Some(roomsince == &0), -+ invite_state: Some(knock_state), -+ limited: true, -+ }), -+ ); -+ continue; -+ } -+ -+ if !services -+ .rooms -+ .state_cache -+ .is_joined(sender_user, room_id) -+ .await -+ { -+ continue; - } - -+ TimelinePdus { pdus: timeline_pdus, limited } = match load_timeline( -+ services, -+ sender_user, -+ room_id, -+ Some(roomsincecount), -+ Some(PduCount::from(next_batch)), -+ *timeline_limit, -+ ) -+ .await -+ { -+ | Ok(value) => value, -+ | Err(err) => { -+ warn!("Encountered missing timeline in {}, error {}", room_id, err); -+ continue; -+ }, -+ }; -+ - if body.extensions.account_data.enabled == Some(true) { - response.extensions.account_data.rooms.insert( - room_id.to_owned(), -@@ -627,7 +707,7 @@ async fn process_rooms<'a, Rooms>( - }, - initial: Some(roomsince == &0), - is_dm: None, -- invite_state, -+ invite_state: None, - unread_notifications: UnreadNotificationsCount { - highlight_count: Some( - services -@@ -753,6 +833,15 @@ async fn collect_typing_events( - - let mut typing_response = sync_events::v5::response::Typing::default(); - for (room_id, (_, _, roomsince)) in todo_rooms { -+ if !services -+ .rooms -+ .state_cache -+ .is_joined(sender_user, room_id) -+ .await -+ { -+ continue; -+ } -+ - if services.rooms.typing.last_typing_update(room_id).await? <= *roomsince { - continue; - } --- -2.55.0 - diff --git a/pkgs/by-name/ma/matrix-continuwuity_latest/0002-fix-backport-SEC28.patch b/pkgs/by-name/ma/matrix-continuwuity_latest/0002-fix-backport-SEC28.patch deleted file mode 100644 index d07419844698..000000000000 --- a/pkgs/by-name/ma/matrix-continuwuity_latest/0002-fix-backport-SEC28.patch +++ /dev/null @@ -1,37 +0,0 @@ -From dcb079931a929880518015794d709f93651154ca Mon Sep 17 00:00:00 2001 -From: Ginger -Date: Tue, 11 Aug 2026 15:59:26 -0400 -Subject: [PATCH 1/2] fix(backport): SEC28 - -(cherry picked from commit 49a8f6f53b6f86ed6abb8952843cb3a38c530ada) ---- - src/service/threepid/mod.rs | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/src/service/threepid/mod.rs b/src/service/threepid/mod.rs -index dcc0b58ab..bda80f82e 100644 ---- a/src/service/threepid/mod.rs -+++ b/src/service/threepid/mod.rs -@@ -112,6 +112,10 @@ pub async fn send_validation_email( - // If a validation session already exists for this client secret, we can either - // reuse it with a new token or return early because it's already valid. - | Some(session) => { -+ if session.email != recipient.email { -+ return Err!(Request(InvalidParam("Wrong email for session."))); -+ } -+ - match session.validation_state { - | ValidationState::Validated => { - // If the existing session is already valid, don't send an email. -@@ -119,7 +123,7 @@ pub async fn send_validation_email( - }, - | ValidationState::Pending(ref mut token) => { - // Check ratelimiting for the target address. -- if self.ratelimiter.check_key(&recipient.email).is_err() { -+ if self.ratelimiter.check_key(&session.email).is_err() { - return Err(Error::BadRequest( - ErrorKind::LimitExceeded { retry_after: None }, - "You're sending emails too fast, try again in a few minutes.", --- -2.55.0 - diff --git a/pkgs/by-name/ma/matrix-continuwuity_latest/0003-fix-backport-SEC26.patch b/pkgs/by-name/ma/matrix-continuwuity_latest/0003-fix-backport-SEC26.patch deleted file mode 100644 index 8736fdbeea72..000000000000 --- a/pkgs/by-name/ma/matrix-continuwuity_latest/0003-fix-backport-SEC26.patch +++ /dev/null @@ -1,132 +0,0 @@ -From a00a615799bc55bc093a6298735732565aa2b566 Mon Sep 17 00:00:00 2001 -From: Ginger -Date: Tue, 11 Aug 2026 16:35:24 -0400 -Subject: [PATCH 2/2] fix(backport): SEC26 - -Reviewed-By: timedout -Reviewed-By: Ginger -(cherry picked from commit 700fbe472d4a8385b96f870256bfc00f9a15f809) ---- - src/api/server/event_auth.rs | 27 ++++++++++----------------- - src/api/server/state.rs | 13 ++++++++++++- - src/api/server/state_ids.rs | 13 ++++++++++++- - 3 files changed, 34 insertions(+), 19 deletions(-) - -diff --git a/src/api/server/event_auth.rs b/src/api/server/event_auth.rs -index a9019e8e7..433e18f46 100644 ---- a/src/api/server/event_auth.rs -+++ b/src/api/server/event_auth.rs -@@ -1,12 +1,9 @@ - use std::{borrow::Borrow, iter::once}; - - use axum::extract::State; --use conduwuit::{Err, Error, Result, info, utils::stream::ReadyExt}; -+use conduwuit::{Err, Result, Event, info, utils::stream::ReadyExt}; - use futures::StreamExt; --use ruma::{ -- RoomId, -- api::{client::error::ErrorKind, federation::authorization::get_event_authorization}, --}; -+use ruma::api::federation::authorization::get_event_authorization; - - use super::AccessCheck; - use crate::Ruma; -@@ -42,25 +39,21 @@ pub(crate) async fn get_event_authorization_route( - return Err!(Request(NotFound("This server is not participating in that room."))); - } - -- let event = services -+ // The event must be in the room we just authorised access to -+ if !services - .rooms - .timeline -- .get_pdu_json(&body.event_id) -+ .get_pdu(&body.event_id) - .await -- .map_err(|_| Error::BadRequest(ErrorKind::NotFound, "Event not found."))?; -- -- let room_id_str = event -- .get("room_id") -- .and_then(|val| val.as_str()) -- .ok_or_else(|| Error::bad_database("Invalid event in database."))?; -- -- let room_id = <&RoomId>::try_from(room_id_str) -- .map_err(|_| Error::bad_database("Invalid room_id in event in database."))?; -+ .is_ok_and(|pdu| pdu.room_id_or_hash() == body.room_id) -+ { -+ return Err!(Request(NotFound("Event not found."))); -+ } - - let auth_chain = services - .rooms - .auth_chain -- .event_ids_iter(room_id, once(body.event_id.borrow())) -+ .event_ids_iter(&body.room_id, once(body.event_id.borrow())) - .ready_filter_map(Result::ok) - .filter_map(|id| async move { services.rooms.timeline.get_pdu_json(&id).await.ok() }) - .then(|pdu| services.sending.convert_to_outgoing_federation_event(pdu)) -diff --git a/src/api/server/state.rs b/src/api/server/state.rs -index 5e1ad8ca2..05a008b74 100644 ---- a/src/api/server/state.rs -+++ b/src/api/server/state.rs -@@ -1,7 +1,7 @@ - use std::{borrow::Borrow, iter::once}; - - use axum::extract::State; --use conduwuit::{Err, Result, at, err, info, utils::IterStream}; -+use conduwuit::{Err, Event, Result, at, err, info, utils::IterStream}; - use futures::{FutureExt, StreamExt, TryStreamExt}; - use ruma::{OwnedEventId, api::federation::event::get_room_state}; - -@@ -24,6 +24,17 @@ pub(crate) async fn get_room_state_route( - .check() - .await?; - -+ // The event must be in the room we just authorised access to -+ if !services -+ .rooms -+ .timeline -+ .get_pdu(&body.event_id) -+ .await -+ .is_ok_and(|pdu| pdu.room_id_or_hash() == body.room_id) -+ { -+ return Err!(Request(NotFound("Event not found."))); -+ } -+ - if !services - .rooms - .state_cache -diff --git a/src/api/server/state_ids.rs b/src/api/server/state_ids.rs -index c9dea3116..206f3efc5 100644 ---- a/src/api/server/state_ids.rs -+++ b/src/api/server/state_ids.rs -@@ -1,7 +1,7 @@ - use std::{borrow::Borrow, iter::once}; - - use axum::extract::State; --use conduwuit::{Err, Result, at, err, info}; -+use conduwuit::{Err, Event, Result, at, err, info}; - use futures::{StreamExt, TryStreamExt}; - use ruma::{OwnedEventId, api::federation::event::get_room_state_ids}; - -@@ -25,6 +25,17 @@ pub(crate) async fn get_room_state_ids_route( - .check() - .await?; - -+ // The event must be in the room we just authorised access to -+ if !services -+ .rooms -+ .timeline -+ .get_pdu(&body.event_id) -+ .await -+ .is_ok_and(|pdu| pdu.room_id_or_hash() == body.room_id) -+ { -+ return Err!(Request(NotFound("Event not found."))); -+ } -+ - if !services - .rooms - .state_cache --- -2.55.0 - diff --git a/pkgs/by-name/ma/matrix-continuwuity_latest/package.nix b/pkgs/by-name/ma/matrix-continuwuity_latest/package.nix index c94e635f7543..197b310f7f71 100644 --- a/pkgs/by-name/ma/matrix-continuwuity_latest/package.nix +++ b/pkgs/by-name/ma/matrix-continuwuity_latest/package.nix @@ -50,12 +50,6 @@ rustPlatform.buildRustPackage (finalAttrs: { cargoHash = "sha256-uvMiFURXxkLbbbwq4pG5hevsLZHQ1wVfTNvzQRTQWxE="; - patches = [ - ./0001-fix-backport-SEC10.patch - ./0002-fix-backport-SEC28.patch - ./0003-fix-backport-SEC26.patch - ]; - nativeBuildInputs = [ pkg-config rustPlatform.bindgenHook