1
0
Fork 0
forked from wry/wry

xwayland: disable direct libei access

This commit is contained in:
Julian Orth 2024-07-24 17:55:54 +02:00
parent 665127e6c0
commit 53ada31d74
3 changed files with 61 additions and 13 deletions

View file

@ -1300,6 +1300,7 @@ impl ConfigProxyHandler {
Some(f) => f,
_ => return Err(CphError::NoForker),
};
let env = env.into_iter().map(|(k, v)| (k, Some(v))).collect();
forker.spawn(prog.to_string(), args, env, fds);
Ok(())
}

View file

@ -3,7 +3,7 @@ mod io;
use {
crate::{
async_engine::{AsyncEngine, SpawnedFuture},
compositor::{DISPLAY, WAYLAND_DISPLAY},
compositor::{DISPLAY, LIBEI_SOCKET, WAYLAND_DISPLAY},
forker::io::{IoIn, IoOut},
io_uring::IoUring,
state::State,
@ -151,14 +151,18 @@ impl ForkerProxy {
pub async fn xwayland(
&self,
state: &State,
stderr: Rc<OwnedFd>,
dfd: Rc<OwnedFd>,
listenfd: Rc<OwnedFd>,
wmfd: Rc<OwnedFd>,
waylandfd: Rc<OwnedFd>,
) -> Result<(Rc<OwnedFd>, c::pid_t), ForkerError> {
let (prog, args) = xwayland::build_args();
let env = vec![("WAYLAND_SOCKET".to_string(), "6".to_string())];
let (prog, args) = xwayland::build_args(state, self).await;
let env = vec![
("WAYLAND_SOCKET".to_string(), Some("6".to_string())),
(LIBEI_SOCKET.to_string(), None),
];
let fds = vec![
(2, stderr),
(3, dfd),
@ -175,7 +179,7 @@ impl ForkerProxy {
&self,
prog: String,
args: Vec<String>,
env: Vec<(String, String)>,
env: Vec<(String, Option<String>)>,
fds: Vec<(i32, Rc<OwnedFd>)>,
) {
self.spawn_(prog, args, env, fds, None)
@ -185,7 +189,7 @@ impl ForkerProxy {
&self,
prog: String,
args: Vec<String>,
env: Vec<(String, String)>,
env: Vec<(String, Option<String>)>,
fds: Vec<(i32, Rc<OwnedFd>)>,
pidfd_id: Option<u32>,
) {
@ -291,7 +295,7 @@ enum ServerMessage {
Spawn {
prog: String,
args: Vec<String>,
env: Vec<(String, String)>,
env: Vec<(String, Option<String>)>,
fds: Vec<i32>,
pidfd_id: Option<u32>,
},
@ -408,7 +412,7 @@ impl Forker {
self: &Rc<Self>,
prog: String,
args: Vec<String>,
env: Vec<(String, String)>,
env: Vec<(String, Option<String>)>,
fds: Vec<i32>,
io: &mut IoIn,
pidfd_id: Option<u32>,
@ -424,7 +428,7 @@ impl Forker {
self: &Rc<Self>,
prog: String,
args: Vec<String>,
env: Vec<(String, String)>,
env: Vec<(String, Option<String>)>,
fds: Vec<(i32, OwnedFd)>,
pidfd_id: Option<u32>,
) {
@ -502,7 +506,10 @@ impl Forker {
c::signal(c::SIGCHLD, c::SIG_DFL);
}
for (key, val) in env {
env::set_var(&key, &val);
match val {
None => env::remove_var(&key),
Some(val) => env::set_var(&key, &val),
}
}
let prog = prog.into_ustr();
let mut argsnt = UstrPtr::new();

View file

@ -14,7 +14,7 @@ use {
io_uring::IoUringError,
state::State,
user_session::import_environment,
utils::{errorfmt::ErrorFmt, line_logger::log_lines, oserror::OsError},
utils::{buf::Buf, errorfmt::ErrorFmt, line_logger::log_lines, oserror::OsError},
wire::WlSurfaceId,
xcon::XconError,
xwayland::{
@ -153,6 +153,7 @@ async fn run(
let stderr_read = state.eng.spawn(log_xwayland(state.clone(), stderr_read));
let pidfd = forker
.xwayland(
&state,
Rc::new(stderr_write),
Rc::new(dfdwrite),
socket,
@ -195,9 +196,12 @@ async fn run(
Ok(())
}
pub fn build_args() -> (String, Vec<String>) {
let prog = "Xwayland".to_string();
let args = vec![
const PROG: &str = "Xwayland";
const ENABLE_EI_PORTAL: &str = "-enable-ei-portal";
pub async fn build_args(state: &State, forker: &ForkerProxy) -> (String, Vec<String>) {
let prog = PROG.to_string();
let mut args = vec![
"-terminate".to_string(),
"-rootless".to_string(),
"-verbose".to_string(),
@ -209,9 +213,45 @@ pub fn build_args() -> (String, Vec<String>) {
"-wm".to_string(),
"5".to_string(),
];
let features = detect_features(state, forker).await;
if features.ei_portal {
args.push(ENABLE_EI_PORTAL.to_string());
}
(prog, args)
}
#[derive(Default, Debug)]
struct XwaylandFeatures {
ei_portal: bool,
}
async fn detect_features(state: &State, forker: &ForkerProxy) -> XwaylandFeatures {
let mut features = Default::default();
let Ok((read, write)) = pipe2(c::O_CLOEXEC) else {
return features;
};
forker.spawn(
PROG.to_string(),
vec!["-help".to_string()],
vec![],
vec![(2, Rc::new(write))],
);
let read = Rc::new(read);
let mut help = Vec::new();
let mut buf = Buf::new(1024);
loop {
match state.ring.read(&read, buf.clone()).await {
Ok(0) => break,
Ok(n) => help.extend_from_slice(&buf[..n]),
Err(_) => return features,
}
}
if help.as_bstr().contains_str(ENABLE_EI_PORTAL) {
features.ei_portal = true;
}
features
}
async fn log_xwayland(state: Rc<State>, stderr: OwnedFd) {
let stderr = Rc::new(stderr);
let res = log_lines(&state.ring, &stderr, |left, right| {