Merge b54a7c56be into sapling-pr-archive-bolinfest

This commit is contained in:
Michael Bolin
2025-12-05 10:36:34 -08:00
committed by GitHub
2 changed files with 45 additions and 29 deletions
@@ -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<String>) -> anyhow::Result<i32>
.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::<EscalateResponse>().await?;
+21 -15
View File
@@ -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::<libc::cmsghdr>();
(*cmsg).cmsg_len = libc::CMSG_LEN(size_of::<RawFd>() 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::<RawFd>();
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::<libc::cmsghdr>();
(*cmsg).cmsg_len =
libc::CMSG_LEN(size_of::<RawFd>() 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::<RawFd>();
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::<libc::cmsghdr>();
(*cmsg).cmsg_len =