Run exec-server fs operations through sandbox helper (#17294)

## Summary
- run exec-server filesystem RPCs requiring sandboxing through a
`codex-fs` arg0 helper over stdin/stdout
- keep direct local filesystem execution for `DangerFullAccess` and
external sandbox policies
- remove the standalone exec-server binary path in favor of top-level
arg0 dispatch/runtime paths
- add sandbox escape regression coverage for local and remote filesystem
paths

## Validation
- `just fmt`
- `git diff --check`
- remote devbox: `cd codex-rs && bazel test --bes_backend=
--bes_results_url= //codex-rs/exec-server:all` (6/6 passed)

---------

Co-authored-by: Codex <noreply@openai.com>
This commit is contained in:
starr-openai
2026-04-12 18:36:03 -07:00
committed by GitHub
parent 7c1e41c8b6
commit d626dc3895
52 changed files with 2313 additions and 895 deletions

View File

@@ -0,0 +1,45 @@
use std::error::Error;
use tokio::io;
use tokio::io::AsyncReadExt;
use tokio::io::AsyncWriteExt;
use crate::fs_helper::FsHelperRequest;
use crate::fs_helper::FsHelperResponse;
use crate::fs_helper::run_direct_request;
pub fn main() -> ! {
let exit_code = match tokio::runtime::Builder::new_current_thread()
.enable_all()
.build()
{
Ok(runtime) => match runtime.block_on(run_main()) {
Ok(()) => 0,
Err(err) => {
eprintln!("fs sandbox helper failed: {err}");
1
}
},
Err(err) => {
eprintln!("failed to start fs sandbox helper runtime: {err}");
1
}
};
std::process::exit(exit_code);
}
async fn run_main() -> Result<(), Box<dyn Error + Send + Sync>> {
let mut input = Vec::new();
io::stdin().read_to_end(&mut input).await?;
let request: FsHelperRequest = serde_json::from_slice(&input)?;
let response = match run_direct_request(request).await {
Ok(payload) => FsHelperResponse::Ok(payload),
Err(error) => FsHelperResponse::Error(error),
};
let mut stdout = io::stdout();
stdout
.write_all(serde_json::to_string(&response)?.as_bytes())
.await?;
stdout.write_all(b"\n").await?;
Ok(())
}