From 4f78cca71e5df9c130597dab01f77559602d08d5 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Fri, 23 Oct 2026 01:17:20 +0100 Subject: [PATCH] Protect desktop notification service ownership --- shell/ferese-shell/src/notifications.rs | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/shell/ferese-shell/src/notifications.rs b/shell/ferese-shell/src/notifications.rs index e6b81f8..569dd4b 100644 --- a/shell/ferese-shell/src/notifications.rs +++ b/shell/ferese-shell/src/notifications.rs @@ -224,6 +224,13 @@ impl Service { None => zbus::blocking::connection::Builder::session(), } .and_then(|builder| builder.serve_at(PATH, server)) + // A preview or test sharing the session bus must not replace the + // desktop's notification service, or leave it ownerless on exit. + .map(|builder| { + builder + .allow_name_replacements(false) + .replace_existing_names(false) + }) .and_then(|builder| builder.name(INTERFACE)) .and_then(|builder| builder.build()); let connection = match connection { @@ -1117,6 +1124,22 @@ mod tests { let info: (String, String, String, String) = proxy.call("GetServerInformation", &()).unwrap(); assert_eq!(info.0, "Ferese"); + // A second shell on this bus must fail to claim the name without + // displacing the running desktop's notification service. + let second = Service::connect(&config, Some(address.trim().to_owned())); + assert!(matches!(received(&second), Event::Failed(_))); + drop(second); + let info: (String, String, String, String) = + proxy.call("GetServerInformation", &()).unwrap(); + assert_eq!(info.0, "Ferese"); + // Older shells use zbus's default replacement flags. They must not be + // able to steal the name either. + let replacement = zbus::blocking::connection::Builder::address(address.trim()) + .unwrap() + .name(INTERFACE) + .unwrap() + .build(); + assert!(matches!(replacement, Err(zbus::Error::NameTaken))); let notify = |replace| -> u32 { proxy .call(