mirror of
https://github.com/openai/codex.git
synced 2026-05-01 09:56:37 +00:00
Because the `codex` process could contain sensitive information in memory, such as API keys, we add logic so that when `CODEX_SECURE_MODE=1` is specified, we avail ourselves of whatever the operating system provides to restrict observability/tampering, which includes: - disabling `ptrace(2)`, so it is not possible to attach to the process with a debugger, such as `gdb` - disabling core dumps Admittedly, a user with root privileges can defeat these safeguards. For now, we only add support for this in the `codex` multitool, but we may ultimately want to support this in some of the smaller CLIs that are buildable out of our Cargo workspace.
99 lines
2.8 KiB
Rust
99 lines
2.8 KiB
Rust
#[cfg(any(target_os = "linux", target_os = "android"))]
|
|
const PRCTL_FAILED_EXIT_CODE: i32 = 5;
|
|
|
|
#[cfg(target_os = "macos")]
|
|
const PTRACE_DENY_ATTACH_FAILED_EXIT_CODE: i32 = 6;
|
|
|
|
#[cfg(any(target_os = "linux", target_os = "android", target_os = "macos"))]
|
|
const SET_RLIMIT_CORE_FAILED_EXIT_CODE: i32 = 7;
|
|
|
|
#[cfg(any(target_os = "linux", target_os = "android"))]
|
|
pub(crate) fn pre_main_hardening_linux() {
|
|
// Disable ptrace attach / mark process non-dumpable.
|
|
let ret_code = unsafe { libc::prctl(libc::PR_SET_DUMPABLE, 0, 0, 0, 0) };
|
|
if ret_code != 0 {
|
|
eprintln!(
|
|
"ERROR: prctl(PR_SET_DUMPABLE, 0) failed: {}",
|
|
std::io::Error::last_os_error()
|
|
);
|
|
std::process::exit(PRCTL_FAILED_EXIT_CODE);
|
|
}
|
|
|
|
// For "defense in depth," set the core file size limit to 0.
|
|
set_core_file_size_limit_to_zero();
|
|
|
|
// Official Codex releases are MUSL-linked, which means that variables such
|
|
// as LD_PRELOAD are ignored anyway, but just to be sure, clear them here.
|
|
let ld_keys: Vec<String> = std::env::vars()
|
|
.filter_map(|(key, _)| {
|
|
if key.starts_with("LD_") {
|
|
Some(key)
|
|
} else {
|
|
None
|
|
}
|
|
})
|
|
.collect();
|
|
|
|
for key in ld_keys {
|
|
unsafe {
|
|
std::env::remove_var(key);
|
|
}
|
|
}
|
|
}
|
|
|
|
#[cfg(target_os = "macos")]
|
|
pub(crate) fn pre_main_hardening_macos() {
|
|
// Prevent debuggers from attaching to this process.
|
|
let ret_code = unsafe { libc::ptrace(libc::PT_DENY_ATTACH, 0, std::ptr::null_mut(), 0) };
|
|
if ret_code == -1 {
|
|
eprintln!(
|
|
"ERROR: ptrace(PT_DENY_ATTACH) failed: {}",
|
|
std::io::Error::last_os_error()
|
|
);
|
|
std::process::exit(PTRACE_DENY_ATTACH_FAILED_EXIT_CODE);
|
|
}
|
|
|
|
// Set the core file size limit to 0 to prevent core dumps.
|
|
set_core_file_size_limit_to_zero();
|
|
|
|
// Remove all DYLD_ environment variables, which can be used to subvert
|
|
// library loading.
|
|
let dyld_keys: Vec<String> = std::env::vars()
|
|
.filter_map(|(key, _)| {
|
|
if key.starts_with("DYLD_") {
|
|
Some(key)
|
|
} else {
|
|
None
|
|
}
|
|
})
|
|
.collect();
|
|
|
|
for key in dyld_keys {
|
|
unsafe {
|
|
std::env::remove_var(key);
|
|
}
|
|
}
|
|
}
|
|
|
|
#[cfg(unix)]
|
|
fn set_core_file_size_limit_to_zero() {
|
|
let rlim = libc::rlimit {
|
|
rlim_cur: 0,
|
|
rlim_max: 0,
|
|
};
|
|
|
|
let ret_code = unsafe { libc::setrlimit(libc::RLIMIT_CORE, &rlim) };
|
|
if ret_code != 0 {
|
|
eprintln!(
|
|
"ERROR: setrlimit(RLIMIT_CORE) failed: {}",
|
|
std::io::Error::last_os_error()
|
|
);
|
|
std::process::exit(SET_RLIMIT_CORE_FAILED_EXIT_CODE);
|
|
}
|
|
}
|
|
|
|
#[cfg(windows)]
|
|
pub(crate) fn pre_main_hardening_windows() {
|
|
// TODO(mbolin): Perform the appropriate configuration for Windows.
|
|
}
|