Change how COSMIC_ENABLE_WAYLAND_SECURITY/privileged is handled
Manually starting `cosmic-panel` was not working properly in release builds, because without `cfg!(debug_assertions)`, the `privileged` flag wasn't sent on the panel, so it couldn't be propagated to the applets, which also fail the `client_has_no_security_context()` check. I don't see a way to have both the `cfg!(debug_assertions)` check and `COSMIC_ENABLE_WAYLAND_SECURITY`. Now only the latter is used, and it determines the value of `privileged` for clients started normally. In the future, we could make the default value of `COSMIC_ENABLE_WAYLAND_SECURITY` depend on `cfg!(debug_assertions)` if desired. This also corrects the inconsistency that the `cfg!(debug_assertions)` check wasn't applied to the render-node-specific Wayland sockets.
This commit is contained in:
parent
954aa6edeb
commit
a9740e5040
4 changed files with 31 additions and 60 deletions
|
|
@ -96,7 +96,10 @@ impl State {
|
||||||
.insert_source(listener, move |client_stream, _, state: &mut State| {
|
.insert_source(listener, move |client_stream, _, state: &mut State| {
|
||||||
if let Err(err) = state.common.display_handle.insert_client(
|
if let Err(err) = state.common.display_handle.insert_client(
|
||||||
client_stream,
|
client_stream,
|
||||||
Arc::new(state.new_client_state_with_node(render_node)),
|
Arc::new(ClientState {
|
||||||
|
advertised_drm_node: Some(render_node),
|
||||||
|
..state.new_client_state()
|
||||||
|
}),
|
||||||
) {
|
) {
|
||||||
warn!(
|
warn!(
|
||||||
socket_name = socket_name_clone,
|
socket_name = socket_name_clone,
|
||||||
|
|
|
||||||
14
src/main.rs
14
src/main.rs
|
|
@ -13,7 +13,9 @@ use std::{env, ffi::OsString, os::unix::process::CommandExt, process, sync::Arc}
|
||||||
use tracing::{error, info, warn};
|
use tracing::{error, info, warn};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
shell::SeatExt, state::BackendData, wayland::handlers::compositor::client_compositor_state,
|
shell::SeatExt,
|
||||||
|
state::{BackendData, ClientState},
|
||||||
|
wayland::handlers::compositor::client_compositor_state,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub mod backend;
|
pub mod backend;
|
||||||
|
|
@ -198,14 +200,12 @@ fn init_wayland_display(
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let client_state = state.new_client_state();
|
||||||
if let Err(err) = state.common.display_handle.insert_client(
|
if let Err(err) = state.common.display_handle.insert_client(
|
||||||
client_stream,
|
client_stream,
|
||||||
Arc::new(if cfg!(debug_assertions) {
|
Arc::new(ClientState {
|
||||||
state.new_privileged_client_state()
|
advertised_drm_node: node.or(client_state.advertised_drm_node),
|
||||||
} else if let Some(node) = node {
|
..client_state
|
||||||
state.new_client_state_with_node(node)
|
|
||||||
} else {
|
|
||||||
state.new_client_state()
|
|
||||||
}),
|
}),
|
||||||
) {
|
) {
|
||||||
warn!(?err, "Error adding wayland client")
|
warn!(?err, "Error adding wayland client")
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ use std::{
|
||||||
};
|
};
|
||||||
use tracing::{error, warn};
|
use tracing::{error, warn};
|
||||||
|
|
||||||
use crate::state::State;
|
use crate::state::{ClientState, State};
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
#[serde(rename_all = "snake_case", tag = "message")]
|
#[serde(rename_all = "snake_case", tag = "message")]
|
||||||
|
|
@ -146,7 +146,11 @@ pub fn setup_socket(handle: LoopHandle<State>, state: &State) -> Result<()> {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let stream = unsafe { UnixStream::from_raw_fd(fd) };
|
let stream = unsafe { UnixStream::from_raw_fd(fd) };
|
||||||
if let Err(err) = state.common.display_handle.insert_client(stream, Arc::new(state.new_privileged_client_state())) {
|
let client_state = Arc::new(ClientState {
|
||||||
|
privileged: true,
|
||||||
|
..state.new_client_state()
|
||||||
|
});
|
||||||
|
if let Err(err) = state.common.display_handle.insert_client(stream, client_state) {
|
||||||
warn!(?err, "Failed to add privileged client to display");
|
warn!(?err, "Failed to add privileged client to display");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
64
src/state.rs
64
src/state.rs
|
|
@ -364,8 +364,8 @@ pub fn client_is_privileged(client: &Client) -> bool {
|
||||||
.map_or(false, |client_state| client_state.privileged)
|
.map_or(false, |client_state| client_state.privileged)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn client_should_see_privileged_protocols(client: &Client) -> bool {
|
fn enable_wayland_security() -> bool {
|
||||||
if std::env::var("COSMIC_ENABLE_WAYLAND_SECURITY")
|
std::env::var("COSMIC_ENABLE_WAYLAND_SECURITY")
|
||||||
.map(|x| {
|
.map(|x| {
|
||||||
x == "1"
|
x == "1"
|
||||||
|| x.to_lowercase() == "true"
|
|| x.to_lowercase() == "true"
|
||||||
|
|
@ -373,11 +373,6 @@ pub fn client_should_see_privileged_protocols(client: &Client) -> bool {
|
||||||
|| x.to_lowercase() == "y"
|
|| x.to_lowercase() == "y"
|
||||||
})
|
})
|
||||||
.unwrap_or(false)
|
.unwrap_or(false)
|
||||||
{
|
|
||||||
client_is_privileged(client)
|
|
||||||
} else {
|
|
||||||
client_is_privileged(client) || client_has_no_security_context(client)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl State {
|
impl State {
|
||||||
|
|
@ -409,14 +404,11 @@ impl State {
|
||||||
let fractional_scale_state = FractionalScaleManagerState::new::<State>(dh);
|
let fractional_scale_state = FractionalScaleManagerState::new::<State>(dh);
|
||||||
let keyboard_shortcuts_inhibit_state = KeyboardShortcutsInhibitState::new::<Self>(dh);
|
let keyboard_shortcuts_inhibit_state = KeyboardShortcutsInhibitState::new::<Self>(dh);
|
||||||
let output_state = OutputManagerState::new_with_xdg_output::<Self>(dh);
|
let output_state = OutputManagerState::new_with_xdg_output::<Self>(dh);
|
||||||
let output_configuration_state =
|
let output_configuration_state = OutputConfigurationState::new(dh, client_is_privileged);
|
||||||
OutputConfigurationState::new(dh, client_should_see_privileged_protocols);
|
|
||||||
let presentation_state = PresentationState::new::<Self>(dh, clock.id() as u32);
|
let presentation_state = PresentationState::new::<Self>(dh, clock.id() as u32);
|
||||||
let primary_selection_state = PrimarySelectionState::new::<Self>(dh);
|
let primary_selection_state = PrimarySelectionState::new::<Self>(dh);
|
||||||
let image_source_state =
|
let image_source_state = ImageSourceState::new::<Self, _>(dh, client_is_privileged);
|
||||||
ImageSourceState::new::<Self, _>(dh, client_should_see_privileged_protocols);
|
let screencopy_state = ScreencopyState::new::<Self, _>(dh, client_is_privileged);
|
||||||
let screencopy_state =
|
|
||||||
ScreencopyState::new::<Self, _>(dh, client_should_see_privileged_protocols);
|
|
||||||
let shm_state =
|
let shm_state =
|
||||||
ShmState::new::<Self>(dh, vec![wl_shm::Format::Xbgr8888, wl_shm::Format::Abgr8888]);
|
ShmState::new::<Self>(dh, vec![wl_shm::Format::Xbgr8888, wl_shm::Format::Abgr8888]);
|
||||||
let seat_state = SeatState::<Self>::new();
|
let seat_state = SeatState::<Self>::new();
|
||||||
|
|
@ -425,15 +417,15 @@ impl State {
|
||||||
let kde_decoration_state = KdeDecorationState::new::<Self>(&dh, Mode::Client);
|
let kde_decoration_state = KdeDecorationState::new::<Self>(&dh, Mode::Client);
|
||||||
let xdg_decoration_state = XdgDecorationState::new::<Self>(&dh);
|
let xdg_decoration_state = XdgDecorationState::new::<Self>(&dh);
|
||||||
let session_lock_manager_state =
|
let session_lock_manager_state =
|
||||||
SessionLockManagerState::new::<Self, _>(&dh, client_should_see_privileged_protocols);
|
SessionLockManagerState::new::<Self, _>(&dh, client_is_privileged);
|
||||||
XWaylandKeyboardGrabState::new::<Self>(&dh);
|
XWaylandKeyboardGrabState::new::<Self>(&dh);
|
||||||
PointerConstraintsState::new::<Self>(&dh);
|
PointerConstraintsState::new::<Self>(&dh);
|
||||||
PointerGesturesState::new::<Self>(&dh);
|
PointerGesturesState::new::<Self>(&dh);
|
||||||
TabletManagerState::new::<Self>(&dh);
|
TabletManagerState::new::<Self>(&dh);
|
||||||
SecurityContextState::new::<Self, _>(&dh, client_has_no_security_context);
|
SecurityContextState::new::<Self, _>(&dh, client_has_no_security_context);
|
||||||
InputMethodManagerState::new::<Self, _>(&dh, client_should_see_privileged_protocols);
|
InputMethodManagerState::new::<Self, _>(&dh, client_is_privileged);
|
||||||
TextInputManagerState::new::<Self>(&dh);
|
TextInputManagerState::new::<Self>(&dh);
|
||||||
VirtualKeyboardManagerState::new::<State, _>(&dh, client_should_see_privileged_protocols);
|
VirtualKeyboardManagerState::new::<State, _>(&dh, client_is_privileged);
|
||||||
|
|
||||||
let idle_notifier_state = IdleNotifierState::<Self>::new(&dh, handle.clone());
|
let idle_notifier_state = IdleNotifierState::<Self>::new(&dh, handle.clone());
|
||||||
let idle_inhibit_manager_state = IdleInhibitManagerState::new::<State>(&dh);
|
let idle_inhibit_manager_state = IdleInhibitManagerState::new::<State>(&dh);
|
||||||
|
|
@ -445,10 +437,8 @@ impl State {
|
||||||
|
|
||||||
let shell = Arc::new(RwLock::new(Shell::new(&config)));
|
let shell = Arc::new(RwLock::new(Shell::new(&config)));
|
||||||
|
|
||||||
let layer_shell_state = WlrLayerShellState::new_with_filter::<State, _>(
|
let layer_shell_state =
|
||||||
dh,
|
WlrLayerShellState::new_with_filter::<State, _>(dh, client_is_privileged);
|
||||||
client_should_see_privileged_protocols,
|
|
||||||
);
|
|
||||||
let xdg_shell_state = XdgShellState::new_with_capabilities::<State>(
|
let xdg_shell_state = XdgShellState::new_with_capabilities::<State>(
|
||||||
dh,
|
dh,
|
||||||
[
|
[
|
||||||
|
|
@ -459,8 +449,7 @@ impl State {
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
let xdg_activation_state = XdgActivationState::new::<State>(dh);
|
let xdg_activation_state = XdgActivationState::new::<State>(dh);
|
||||||
let toplevel_info_state =
|
let toplevel_info_state = ToplevelInfoState::new(dh, client_is_privileged);
|
||||||
ToplevelInfoState::new(dh, client_should_see_privileged_protocols);
|
|
||||||
let toplevel_management_state = ToplevelManagementState::new::<State, _>(
|
let toplevel_management_state = ToplevelManagementState::new::<State, _>(
|
||||||
dh,
|
dh,
|
||||||
vec![
|
vec![
|
||||||
|
|
@ -470,9 +459,9 @@ impl State {
|
||||||
ManagementCapabilities::Minimize,
|
ManagementCapabilities::Minimize,
|
||||||
ManagementCapabilities::MoveToWorkspace,
|
ManagementCapabilities::MoveToWorkspace,
|
||||||
],
|
],
|
||||||
client_should_see_privileged_protocols,
|
client_is_privileged,
|
||||||
);
|
);
|
||||||
let workspace_state = WorkspaceState::new(dh, client_should_see_privileged_protocols);
|
let workspace_state = WorkspaceState::new(dh, client_is_privileged);
|
||||||
|
|
||||||
if let Err(err) = crate::dbus::init(&handle) {
|
if let Err(err) = crate::dbus::init(&handle) {
|
||||||
tracing::warn!(?err, "Failed to initialize dbus handlers");
|
tracing::warn!(?err, "Failed to initialize dbus handlers");
|
||||||
|
|
@ -548,32 +537,7 @@ impl State {
|
||||||
BackendData::Kms(kms_state) => Some(kms_state.primary_node),
|
BackendData::Kms(kms_state) => Some(kms_state.primary_node),
|
||||||
_ => None,
|
_ => None,
|
||||||
},
|
},
|
||||||
privileged: false,
|
privileged: !enable_wayland_security(),
|
||||||
evls: self.common.event_loop_signal.clone(),
|
|
||||||
security_context: None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new_client_state_with_node(&self, drm_node: DrmNode) -> ClientState {
|
|
||||||
ClientState {
|
|
||||||
compositor_client_state: CompositorClientState::default(),
|
|
||||||
workspace_client_state: WorkspaceClientState::default(),
|
|
||||||
advertised_drm_node: Some(drm_node),
|
|
||||||
privileged: false,
|
|
||||||
evls: self.common.event_loop_signal.clone(),
|
|
||||||
security_context: None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new_privileged_client_state(&self) -> ClientState {
|
|
||||||
ClientState {
|
|
||||||
compositor_client_state: CompositorClientState::default(),
|
|
||||||
workspace_client_state: WorkspaceClientState::default(),
|
|
||||||
advertised_drm_node: match &self.backend {
|
|
||||||
BackendData::Kms(kms_state) => Some(kms_state.primary_node),
|
|
||||||
_ => None,
|
|
||||||
},
|
|
||||||
privileged: true,
|
|
||||||
evls: self.common.event_loop_signal.clone(),
|
evls: self.common.event_loop_signal.clone(),
|
||||||
security_context: None,
|
security_context: None,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue