From 758049e7224f3b21e251fdf2cdfa33c9971844cd Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Thu, 24 Oct 2024 19:56:20 +0200 Subject: [PATCH] toplevel_info: Fix racy data creation --- src/wayland/protocols/toplevel_info.rs | 35 ++++++++++++++++++++------ 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/src/wayland/protocols/toplevel_info.rs b/src/wayland/protocols/toplevel_info.rs index 48b9e483..f46fba11 100644 --- a/src/wayland/protocols/toplevel_info.rs +++ b/src/wayland/protocols/toplevel_info.rs @@ -90,7 +90,7 @@ pub struct ToplevelHandleStateInner { title: String, app_id: String, states: Vec, - pub(super) window: W, + pub(super) window: Option, } pub type ToplevelHandleState = Mutex>; @@ -104,7 +104,20 @@ impl ToplevelHandleStateInner { title: String::new(), app_id: String::new(), states: Vec::new(), - window: window.clone(), + window: Some(window.clone()), + }) + } + + fn empty() -> ToplevelHandleState { + ToplevelHandleState::new(ToplevelHandleStateInner { + outputs: Vec::new(), + geometry: None, + wl_outputs: HashSet::new(), + workspaces: Vec::new(), + title: String::new(), + app_id: String::new(), + states: Vec::new(), + window: None, }) } } @@ -187,6 +200,10 @@ where .instances .push(instance); } else { + let _ = data_init.init( + cosmic_toplevel, + ToplevelHandleStateInner::empty(), + ); error!(?foreign_toplevel, "Toplevel for foreign-toplevel-list not registered for cosmic-toplevel-info."); } } @@ -509,10 +526,14 @@ where } handle_state.states = states.clone(); - let states = states - .iter() - .flat_map(|state| (*state as u32).to_ne_bytes()) - .collect::>(); + let states: Vec = { + let ratio = std::mem::size_of::() / std::mem::size_of::(); + let ptr = states.as_mut_ptr() as *mut u8; + let len = states.len() * ratio; + let cap = states.capacity() * ratio; + std::mem::forget(states); + unsafe { Vec::from_raw_parts(ptr, len, cap) } + }; instance.state(states); changed = true; } @@ -600,7 +621,7 @@ where pub fn window_from_handle(handle: ZcosmicToplevelHandleV1) -> Option { handle .data::>() - .map(|state| state.lock().unwrap().window.clone()) + .and_then(|state| state.lock().unwrap().window.clone()) } macro_rules! delegate_toplevel_info {