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, Some(f) => f,
_ => return Err(CphError::NoForker), _ => return Err(CphError::NoForker),
}; };
let env = env.into_iter().map(|(k, v)| (k, Some(v))).collect();
forker.spawn(prog.to_string(), args, env, fds); forker.spawn(prog.to_string(), args, env, fds);
Ok(()) Ok(())
} }

View file

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

View file

@ -14,7 +14,7 @@ use {
io_uring::IoUringError, io_uring::IoUringError,
state::State, state::State,
user_session::import_environment, 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, wire::WlSurfaceId,
xcon::XconError, xcon::XconError,
xwayland::{ xwayland::{
@ -153,6 +153,7 @@ async fn run(
let stderr_read = state.eng.spawn(log_xwayland(state.clone(), stderr_read)); let stderr_read = state.eng.spawn(log_xwayland(state.clone(), stderr_read));
let pidfd = forker let pidfd = forker
.xwayland( .xwayland(
&state,
Rc::new(stderr_write), Rc::new(stderr_write),
Rc::new(dfdwrite), Rc::new(dfdwrite),
socket, socket,
@ -195,9 +196,12 @@ async fn run(
Ok(()) Ok(())
} }
pub fn build_args() -> (String, Vec<String>) { const PROG: &str = "Xwayland";
let prog = "Xwayland".to_string(); const ENABLE_EI_PORTAL: &str = "-enable-ei-portal";
let args = vec![
pub async fn build_args(state: &State, forker: &ForkerProxy) -> (String, Vec<String>) {
let prog = PROG.to_string();
let mut args = vec![
"-terminate".to_string(), "-terminate".to_string(),
"-rootless".to_string(), "-rootless".to_string(),
"-verbose".to_string(), "-verbose".to_string(),
@ -209,9 +213,45 @@ pub fn build_args() -> (String, Vec<String>) {
"-wm".to_string(), "-wm".to_string(),
"5".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) (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) { async fn log_xwayland(state: Rc<State>, stderr: OwnedFd) {
let stderr = Rc::new(stderr); let stderr = Rc::new(stderr);
let res = log_lines(&state.ring, &stderr, |left, right| { let res = log_lines(&state.ring, &stderr, |left, right| {