Compare commits

...

3 Commits

Author SHA1 Message Date
viyatb-oai
4e7454c5e2 Merge branch 'main' into codex/viyatb/fix-arg0-stale-shims 2026-04-22 14:36:43 -07:00
viyatb-oai
1bb23094b0 Merge branch 'main' into codex/viyatb/fix-arg0-stale-shims 2026-04-16 18:05:50 -07:00
viyatb-oai
3a8c5642d2 fix: protect active arg0 helper dirs
Co-authored-by: Codex noreply@openai.com
2026-04-12 14:41:54 -07:00

View File

@@ -16,6 +16,7 @@ const MISSPELLED_APPLY_PATCH_ARG0: &str = "applypatch";
#[cfg(unix)]
const EXECVE_WRAPPER_ARG0: &str = "codex-execve-wrapper";
const LOCK_FILENAME: &str = ".lock";
const PID_FILENAME: &str = ".pid";
const TOKIO_WORKER_STACK_SIZE_BYTES: usize = 16 * 1024 * 1024;
#[derive(Clone, Debug, Default, Eq, PartialEq)]
@@ -318,6 +319,7 @@ pub fn prepend_path_entry_for_codex_aliases() -> std::io::Result<Arg0PathEntryGu
.prefix("codex-arg0")
.tempdir_in(&temp_root)?;
let path = temp_dir.path();
write_owner_pid(path)?;
let lock_path = path.join(LOCK_FILENAME);
let lock_file = File::options()
@@ -421,6 +423,10 @@ fn janitor_cleanup(temp_root: &Path) -> std::io::Result<()> {
continue;
}
if dir_belongs_to_running_process(&path) {
continue;
}
// Skip the directory if locking fails or the lock is currently held.
let Some(_lock_file) = try_lock_dir(&path)? else {
continue;
@@ -437,6 +443,36 @@ fn janitor_cleanup(temp_root: &Path) -> std::io::Result<()> {
Ok(())
}
fn write_owner_pid(dir: &Path) -> std::io::Result<()> {
std::fs::write(dir.join(PID_FILENAME), format!("{}\n", std::process::id()))
}
fn dir_belongs_to_running_process(dir: &Path) -> bool {
let Ok(pid) = std::fs::read_to_string(dir.join(PID_FILENAME)) else {
return false;
};
let Ok(pid) = pid.trim().parse::<u32>() else {
return false;
};
owner_pid_is_running(pid)
}
fn owner_pid_is_running(pid: u32) -> bool {
if pid == std::process::id() {
return true;
}
#[cfg(target_os = "linux")]
{
Path::new("/proc").join(pid.to_string()).exists()
}
#[cfg(not(target_os = "linux"))]
{
false
}
}
fn try_lock_dir(dir: &Path) -> std::io::Result<Option<File>> {
let lock_path = dir.join(LOCK_FILENAME);
let lock_file = match File::options().read(true).write(true).open(&lock_path) {
@@ -457,6 +493,7 @@ mod tests {
use super::Arg0DispatchPaths;
use super::Arg0PathEntryGuard;
use super::LOCK_FILENAME;
use super::PID_FILENAME;
use super::janitor_cleanup;
use super::linux_sandbox_exe_path;
#[cfg(unix)]
@@ -479,6 +516,10 @@ mod tests {
.open(lock_path)
}
fn write_pid(dir: &Path, pid: u32) -> std::io::Result<()> {
fs::write(dir.join(PID_FILENAME), format!("{pid}\n"))
}
#[test]
fn linux_sandbox_exe_path_prefers_codex_linux_sandbox_alias() -> std::io::Result<()> {
let temp_dir = TempDir::new()?;
@@ -570,6 +611,34 @@ mod tests {
Ok(())
}
#[test]
fn janitor_skips_dirs_owned_by_running_process() -> std::io::Result<()> {
let root = tempfile::tempdir()?;
let dir = root.path().join("active-pid");
fs::create_dir(&dir)?;
create_lock(&dir)?;
write_pid(&dir, std::process::id())?;
janitor_cleanup(root.path())?;
assert!(dir.exists());
Ok(())
}
#[test]
fn janitor_removes_dirs_with_stale_pid_and_unlocked_lock() -> std::io::Result<()> {
let root = tempfile::tempdir()?;
let dir = root.path().join("stale-pid");
fs::create_dir(&dir)?;
create_lock(&dir)?;
write_pid(&dir, u32::MAX)?;
janitor_cleanup(root.path())?;
assert!(!dir.exists());
Ok(())
}
#[test]
fn janitor_removes_dirs_with_unlocked_lock() -> std::io::Result<()> {
let root = tempfile::tempdir()?;