Compare commits

...

1 Commits

Author SHA1 Message Date
David Wiesen
54ace16760 fix windows elevated sandbox payload handoff 2026-05-26 13:07:37 -07:00
2 changed files with 84 additions and 8 deletions

View File

@@ -66,6 +66,7 @@ use windows_sys::Win32::Storage::FileSystem::FILE_GENERIC_READ;
use windows_sys::Win32::Storage::FileSystem::FILE_GENERIC_WRITE;
const DENY_ACCESS: i32 = 3;
const PAYLOAD_FILE_ARG_PREFIX: &str = "--payload-file=";
mod read_acl_mutex;
mod sandbox_users;
@@ -367,6 +368,30 @@ pub fn main() -> Result<()> {
ret
}
fn decode_payload_arg(payload_arg: &str) -> Result<Vec<u8>> {
if let Some(path) = payload_arg.strip_prefix(PAYLOAD_FILE_ARG_PREFIX) {
let payload_path = PathBuf::from(path);
let payload_json = std::fs::read(&payload_path).map_err(|err| {
anyhow::Error::new(SetupFailure::new(
SetupErrorCode::HelperRequestArgsFailed,
format!(
"failed to read payload file {}: {err}",
payload_path.display()
),
))
})?;
let _ = std::fs::remove_file(&payload_path);
return Ok(payload_json);
}
BASE64.decode(payload_arg).map_err(|err| {
anyhow::Error::new(SetupFailure::new(
SetupErrorCode::HelperRequestArgsFailed,
format!("failed to decode payload b64: {err}"),
))
})
}
fn real_main() -> Result<()> {
let mut args = std::env::args().collect::<Vec<_>>();
if args.len() != 2 {
@@ -375,13 +400,7 @@ fn real_main() -> Result<()> {
"expected payload argument",
)));
}
let payload_b64 = args.remove(1);
let payload_json = BASE64.decode(payload_b64).map_err(|err| {
anyhow::Error::new(SetupFailure::new(
SetupErrorCode::HelperRequestArgsFailed,
format!("failed to decode payload b64: {err}"),
))
})?;
let payload_json = decode_payload_arg(&args.remove(1))?;
let payload: Payload = serde_json::from_slice(&payload_json).map_err(|err| {
anyhow::Error::new(SetupFailure::new(
SetupErrorCode::HelperRequestArgsFailed,
@@ -912,6 +931,7 @@ fn run_setup_full(payload: &Payload, log: &mut File, sbx_dir: &Path) -> Result<(
#[cfg(test)]
mod tests {
use super::BASE64;
use super::Payload;
use super::SETUP_VERSION;
use codex_otel::StatsigMetricsSettings;
@@ -954,4 +974,27 @@ mod tests {
})
);
}
#[test]
fn decode_payload_arg_accepts_inline_base64() {
let bytes = super::decode_payload_arg(&BASE64.encode(br#"{"ok":true}"#)).expect("decode");
assert_eq!(bytes, br#"{"ok":true}"#);
}
#[test]
fn decode_payload_arg_accepts_payload_file() {
let dir = tempfile::tempdir().expect("tempdir");
let path = dir.path().join("payload.json");
std::fs::write(&path, br#"{"ok":true}"#).expect("write payload");
let bytes = super::decode_payload_arg(&format!(
"{}{}",
super::PAYLOAD_FILE_ARG_PREFIX,
path.display()
))
.expect("decode");
assert_eq!(bytes, br#"{"ok":true}"#);
assert!(!path.exists());
}
}

View File

@@ -9,6 +9,8 @@ use std::path::Path;
use std::path::PathBuf;
use std::process::Command;
use std::process::Stdio;
use std::time::SystemTime;
use std::time::UNIX_EPOCH;
use crate::allow::AllowDenyPaths;
use crate::allow::compute_allow_paths;
@@ -596,6 +598,33 @@ fn report_helper_failure(
}
}
const PAYLOAD_FILE_ARG_PREFIX: &str = "--payload-file=";
fn persist_setup_payload_file(codex_home: &Path, payload_json: &str) -> Result<PathBuf> {
let dir = sandbox_dir(codex_home);
std::fs::create_dir_all(&dir).map_err(|err| {
failure(
SetupErrorCode::OrchestratorSandboxDirCreateFailed,
format!("failed to create sandbox dir {}: {err}", dir.display()),
)
})?;
let nonce = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap_or_default()
.as_nanos();
let path = dir.join(format!(
"setup-payload-{}-{nonce}.json",
std::process::id()
));
std::fs::write(&path, payload_json).map_err(|err| {
failure(
SetupErrorCode::OrchestratorPayloadSerializeFailed,
format!("failed to write setup payload file {}: {err}", path.display()),
)
})?;
Ok(path)
}
fn run_setup_exe(
payload: &ElevationPayload,
needs_elevation: bool,
@@ -661,7 +690,11 @@ fn run_setup_exe(
}
let exe_w = crate::winutil::to_wide(&exe);
let params = quote_arg(&payload_b64);
let payload_path = persist_setup_payload_file(codex_home, &payload_json)?;
let params = quote_arg(&format!(
"{PAYLOAD_FILE_ARG_PREFIX}{}",
payload_path.display()
));
let params_w = crate::winutil::to_wide(params);
let verb_w = crate::winutil::to_wide("runas");
let mut sei: SHELLEXECUTEINFOW = unsafe { std::mem::zeroed() };