Skip to content

Commit

Permalink
wayland: Enforce privileged protocol security
Browse files Browse the repository at this point in the history
  • Loading branch information
Drakulix committed Nov 1, 2023
1 parent 809eeaf commit 5cdfe46
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 24 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -88,4 +88,4 @@ debug = true
lto = "fat"

[patch."https://github.com/Smithay/smithay.git"]
smithay = { git = "https://github.com/pop-os/smithay", branch = "x11_fixes" }
smithay = { git = "https://github.com/pop-os/smithay", branch = "panel_security" }
21 changes: 6 additions & 15 deletions src/shell/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ use smithay::{

use crate::{
config::{Config, KeyModifiers, KeyPattern},
state::client_has_security_context,
state::client_is_privileged,
utils::prelude::*,
wayland::protocols::{
toplevel_info::ToplevelInfoState,
Expand Down Expand Up @@ -849,28 +849,19 @@ pub struct InvalidWorkspaceIndex;

impl Shell {
pub fn new(config: &Config, dh: &DisplayHandle) -> Self {
// TODO: Privileged protocols
let layer_shell_state = WlrLayerShellState::new::<State>(dh);
let layer_shell_state =
WlrLayerShellState::new_with_filter::<State, _>(dh, client_is_privileged);
let xdg_shell_state = XdgShellState::new::<State>(dh);
let toplevel_info_state = ToplevelInfoState::new(
dh,
//|client| client.get_data::<ClientState>().map_or(false, |s| s.privileged),
client_has_security_context,
);
let toplevel_info_state = ToplevelInfoState::new(dh, client_is_privileged);
let toplevel_management_state = ToplevelManagementState::new::<State, _>(
dh,
vec![
ManagementCapabilities::Close,
ManagementCapabilities::Activate,
],
//|client| client.get_data::<ClientState>().map_or(false, |s| s.privileged),
client_has_security_context,
);
let workspace_state = WorkspaceState::new(
dh,
//|client| client.get_data::<ClientState>().map_or(false, |s| s.privileged),
client_has_security_context,
client_is_privileged,
);
let workspace_state = WorkspaceState::new(dh, client_is_privileged);
let theme = cosmic::theme::system_preference();

Shell {
Expand Down
27 changes: 20 additions & 7 deletions src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -279,12 +279,26 @@ impl BackendData {
}
}

pub fn client_has_security_context(client: &Client) -> bool {
pub fn client_has_no_security_context(client: &Client) -> bool {
client
.get_data::<ClientState>()
.map_or(true, |client_state| client_state.security_context.is_none())
}

pub fn client_is_privileged(client: &Client) -> bool {
std::env::var("COSMIC_DISABLE_WAYLAND_SECURITY")
.map(|x| {
x == "1"
|| x.to_lowercase() == "true"
|| x.to_lowercase() == "yes"
|| x.to_lowercase() == "y"
})
.unwrap_or(false)
|| client
.get_data::<ClientState>()
.map_or(false, |client_state| client_state.privileged)
}

impl State {
pub fn new(
dh: &DisplayHandle,
Expand All @@ -305,15 +319,14 @@ impl State {
let fractional_scale_state = FractionalScaleManagerState::new::<State>(dh);
let keyboard_shortcuts_inhibit_state = KeyboardShortcutsInhibitState::new::<Self>(dh);
let output_state = OutputManagerState::new_with_xdg_output::<Self>(dh);
let output_configuration_state =
OutputConfigurationState::new(dh, client_has_security_context);
let output_configuration_state = OutputConfigurationState::new(dh, client_is_privileged);
let presentation_state = PresentationState::new::<Self>(dh, clock.id() as u32);
let primary_selection_state = PrimarySelectionState::new::<Self>(dh);
let screencopy_state = ScreencopyState::new::<Self, _, _>(
dh,
vec![CursorMode::Embedded, CursorMode::Hidden],
client_has_security_context,
); // TODO: privileged
client_is_privileged,
);
let shm_state =
ShmState::new::<Self>(dh, vec![wl_shm::Format::Xbgr8888, wl_shm::Format::Abgr8888]);
let seat_state = SeatState::<Self>::new();
Expand All @@ -322,11 +335,11 @@ impl State {
let kde_decoration_state = KdeDecorationState::new::<Self>(&dh, Mode::Client);
let xdg_decoration_state = XdgDecorationState::new::<Self>(&dh);
let session_lock_manager_state =
SessionLockManagerState::new::<Self, _>(&dh, client_has_security_context);
SessionLockManagerState::new::<Self, _>(&dh, client_is_privileged);
XWaylandKeyboardGrabState::new::<Self>(&dh);
PointerConstraintsState::new::<Self>(&dh);
PointerGesturesState::new::<Self>(&dh);
SecurityContextState::new::<Self, _>(&dh, client_has_security_context);
SecurityContextState::new::<Self, _>(&dh, client_has_no_security_context);

let shell = Shell::new(&config, dh);

Expand Down
30 changes: 30 additions & 0 deletions src/wayland/handlers/security_context.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
use crate::state::{ClientState, State};
use smithay::{
backend::drm::DrmNode,
delegate_security_context,
wayland::security_context::{
SecurityContext, SecurityContextHandler, SecurityContextListenerSource,
},
xwayland::XWaylandClientData,
};
use std::sync::Arc;
use tracing::warn;
Expand All @@ -17,10 +19,38 @@ impl SecurityContextHandler for State {
self.common
.event_loop_handle
.insert_source(source, move |client_stream, _, state| {
let client_data = state
.common
.display_handle
.backend_handle()
.get_client_data(security_context.client_id.clone())
.ok();

let privileged = client_data
.as_ref()
.and_then(|data| data.downcast_ref::<ClientState>())
.map(|data| data.privileged)
.unwrap_or(false);

let drm_node = client_data
.as_ref()
.and_then(|data| data.downcast_ref::<ClientState>())
.and_then(|data| data.drm_node.clone())
.or_else(|| {
client_data
.as_ref()
.and_then(|data| data.downcast_ref::<XWaylandClientData>())
.and_then(|data| data.user_data().get::<DrmNode>().cloned())
});

if let Err(err) = state.common.display_handle.insert_client(
client_stream,
Arc::new(ClientState {
security_context: Some(security_context.clone()),
privileged: privileged
&& security_context.sandbox_engine.as_deref()
== Some("com.system76.CosmicPanel"),
drm_node,
..state.new_client_state()
}),
) {
Expand Down

0 comments on commit 5cdfe46

Please sign in to comment.