diff --git a/codex-rs/exec-server/src/posix/escalate_client.rs b/codex-rs/exec-server/src/posix/escalate_client.rs index bea4b6fa5f..3fc6dd0788 100644 --- a/codex-rs/exec-server/src/posix/escalate_client.rs +++ b/codex-rs/exec-server/src/posix/escalate_client.rs @@ -1,3 +1,4 @@ +use std::collections::HashMap; use std::io; use std::os::fd::AsRawFd; use std::os::fd::FromRawFd as _; @@ -34,21 +35,30 @@ pub(crate) async fn run(file: String, argv: Vec) -> anyhow::Result .send_with_fds(&HANDSHAKE_MESSAGE, &[server.into_inner().into()]) .await .context("failed to send handshake datagram")?; - let env = std::env::vars() - .filter(|(k, _)| { - !matches!( - k.as_str(), - ESCALATE_SOCKET_ENV_VAR | BASH_EXEC_WRAPPER_ENV_VAR - ) - }) - .collect(); + let mut env = HashMap::new(); + const MAX_ENV_ENTRY_LEN: i64 = 8_192; + for (key, value) in std::env::vars() { + if matches!( + key.as_str(), + ESCALATE_SOCKET_ENV_VAR | BASH_EXEC_WRAPPER_ENV_VAR + ) { + continue; + } + let entry_len = (key.len() + value.len()) as i64; + if entry_len > MAX_ENV_ENTRY_LEN { + tracing::debug!(key, entry_len, "skipping oversized environment variable"); + continue; + } + env.insert(key, value); + } + let request = EscalateRequest { + file: file.clone().into(), + argv: argv.clone(), + workdir: std::env::current_dir()?, + env, + }; client - .send(EscalateRequest { - file: file.clone().into(), - argv: argv.clone(), - workdir: std::env::current_dir()?, - env, - }) + .send(request) .await .context("failed to send EscalateRequest")?; let message = client.receive::().await?; diff --git a/codex-rs/exec-server/src/posix/socket.rs b/codex-rs/exec-server/src/posix/socket.rs index 92c93dcc7d..7dc74e8e91 100644 --- a/codex-rs/exec-server/src/posix/socket.rs +++ b/codex-rs/exec-server/src/posix/socket.rs @@ -182,21 +182,26 @@ fn send_message_bytes(socket: &Socket, data: &[u8], fds: &[OwnedFd]) -> std::io: frame.extend_from_slice(&encode_length(data.len())?); frame.extend_from_slice(data); - let mut control = vec![0u8; control_space_for_fds(fds.len())]; - unsafe { - let cmsg = control.as_mut_ptr().cast::(); - (*cmsg).cmsg_len = libc::CMSG_LEN(size_of::() as c_uint * fds.len() as c_uint) as _; - (*cmsg).cmsg_level = libc::SOL_SOCKET; - (*cmsg).cmsg_type = libc::SCM_RIGHTS; - let data_ptr = libc::CMSG_DATA(cmsg).cast::(); - for (i, fd) in fds.iter().enumerate() { - data_ptr.add(i).write(fd.as_raw_fd()); - } - } - + let mut control; let payload = [IoSlice::new(&frame)]; - let msg = MsgHdr::new().with_buffers(&payload).with_control(&control); - let mut sent = socket.sendmsg(&msg, 0)?; + let mut sent = if fds.is_empty() { + socket.send(&frame)? + } else { + control = vec![0u8; control_space_for_fds(fds.len())]; + unsafe { + let cmsg = control.as_mut_ptr().cast::(); + (*cmsg).cmsg_len = + libc::CMSG_LEN(size_of::() as c_uint * fds.len() as c_uint) as _; + (*cmsg).cmsg_level = libc::SOL_SOCKET; + (*cmsg).cmsg_type = libc::SCM_RIGHTS; + let data_ptr = libc::CMSG_DATA(cmsg).cast::(); + for (i, fd) in fds.iter().enumerate() { + data_ptr.add(i).write(fd.as_raw_fd()); + } + } + let msg = MsgHdr::new().with_buffers(&payload).with_control(&control); + socket.sendmsg(&msg, 0)? + }; while sent < frame.len() { let bytes = socket.send(&frame[sent..])?; if bytes == 0 { @@ -236,8 +241,9 @@ fn send_datagram_bytes(socket: &Socket, data: &[u8], fds: &[OwnedFd]) -> std::io format!("too many fds: {}", fds.len()), )); } - let mut control = vec![0u8; control_space_for_fds(fds.len())]; + let mut control = Vec::new(); if !fds.is_empty() { + control = vec![0u8; control_space_for_fds(fds.len())]; unsafe { let cmsg = control.as_mut_ptr().cast::(); (*cmsg).cmsg_len =