mirror of
https://github.com/openai/codex.git
synced 2026-10-29 19:08:43 +00:00
Reject implicitly discovered bare Git repositories (#36924)
## Why A repository can contain a tracked directory that Git implicitly treats as a bare repository. Its configuration may select helpers such as `core.fsmonitor`, causing Codex Git operations in that directory to execute repository-controlled code. ## What changed - Pass `-c safe.bareRepository=explicit` to Codex-managed Git commands so they reject implicitly discovered bare repositories. - Continue to support repositories explicitly selected with `--git-dir` or `GIT_DIR`. ## Testing Add a regression test that clones a repository containing a tracked embedded Git repository and verifies that guarded Git inspection rejects it without running its configured filesystem monitor. GitOrigin-RevId: 344b5bc1e0ffa94f2a1b788488aa653222da10f3
This commit is contained in:
@@ -125,6 +125,7 @@ pub fn apply_git_patch(req: &ApplyGitRequest) -> io::Result<ApplyGitResult> {
|
||||
|
||||
fn resolve_git_root(cwd: &Path) -> io::Result<PathBuf> {
|
||||
let out = std::process::Command::new("git")
|
||||
.args(["-c", crate::SAFE_BARE_REPOSITORY_CONFIG])
|
||||
.arg("rev-parse")
|
||||
.arg("--show-toplevel")
|
||||
.current_dir(cwd)
|
||||
@@ -153,6 +154,7 @@ fn run_git(cwd: &Path, git_cfg: &[String], args: &[String]) -> io::Result<(i32,
|
||||
for p in git_cfg {
|
||||
cmd.arg(p);
|
||||
}
|
||||
cmd.args(["-c", crate::SAFE_BARE_REPOSITORY_CONFIG]);
|
||||
for a in args {
|
||||
cmd.arg(a);
|
||||
}
|
||||
@@ -330,6 +332,7 @@ pub fn stage_paths(git_root: &Path, diff: &str) -> io::Result<()> {
|
||||
return Ok(());
|
||||
}
|
||||
let mut cmd = std::process::Command::new("git");
|
||||
cmd.args(["-c", crate::SAFE_BARE_REPOSITORY_CONFIG]);
|
||||
cmd.arg("add");
|
||||
cmd.arg("--");
|
||||
for p in &existing {
|
||||
|
||||
@@ -400,7 +400,10 @@ impl crate::FsmonitorProbeRunner for LocalFsmonitorProbeRunner<'_> {
|
||||
// Both probes are fast, bounded metadata queries that do not inspect the
|
||||
// worktree or index, so do not reduce the requested command's timeout.
|
||||
let mut command = Command::new(self.git);
|
||||
command.args(args).current_dir(self.cwd);
|
||||
command
|
||||
.args(["-c", crate::SAFE_BARE_REPOSITORY_CONFIG])
|
||||
.args(args)
|
||||
.current_dir(self.cwd);
|
||||
match run_git_command_with_timeout_output(&mut command, GIT_COMMAND_TIMEOUT).await {
|
||||
Some(output) if output.status.success() => Some(output.stdout),
|
||||
_ => None,
|
||||
@@ -422,6 +425,7 @@ async fn run_git_command_with_timeout_from(
|
||||
let mut command = Command::new(git);
|
||||
command
|
||||
.env("GIT_OPTIONAL_LOCKS", "0")
|
||||
.args(["-c", crate::SAFE_BARE_REPOSITORY_CONFIG])
|
||||
// Keep internal Git commands independent of repository-selected hooks
|
||||
// and fsmonitor helpers while preserving built-in fsmonitor acceleration.
|
||||
.args(["-c", &format!("core.hooksPath={DISABLED_HOOKS_PATH}")])
|
||||
@@ -1032,6 +1036,7 @@ mod tests {
|
||||
std::fs::write(
|
||||
&git,
|
||||
"#!/bin/sh\n\
|
||||
if [ \"$1\" = \"-c\" ] && [ \"$2\" = \"safe.bareRepository=explicit\" ]; then shift 2; fi\n\
|
||||
printf '%s\\n' \"$*\" >>\"$0.log\"\n\
|
||||
case \"$1\" in\n\
|
||||
config) printf '/tmp/fsmonitor-helper\\000' ;;\n\
|
||||
@@ -1097,6 +1102,7 @@ mod tests {
|
||||
std::fs::write(
|
||||
&git,
|
||||
"#!/bin/sh\n\
|
||||
if [ \"$1\" = \"-c\" ] && [ \"$2\" = \"safe.bareRepository=explicit\" ]; then shift 2; fi\n\
|
||||
printf '%s\\n' \"$*\" >>\"$0.log\"\n\
|
||||
case \"$1\" in\n\
|
||||
config)\n\
|
||||
|
||||
@@ -8,6 +8,10 @@ mod info;
|
||||
mod operations;
|
||||
mod platform;
|
||||
|
||||
/// Git configuration that rejects implicitly discovered bare repositories while
|
||||
/// preserving repositories selected explicitly through `GIT_DIR` or `--git-dir`.
|
||||
pub const SAFE_BARE_REPOSITORY_CONFIG: &str = "safe.bareRepository=explicit";
|
||||
|
||||
pub use apply::ApplyGitRequest;
|
||||
pub use apply::ApplyGitResult;
|
||||
pub use apply::apply_git_patch;
|
||||
|
||||
@@ -100,7 +100,9 @@ where
|
||||
{
|
||||
let iterator = args.into_iter();
|
||||
let (lower, upper) = iterator.size_hint();
|
||||
let mut args_vec = Vec::with_capacity(upper.unwrap_or(lower) + 2);
|
||||
let mut args_vec = Vec::with_capacity(upper.unwrap_or(lower) + 4);
|
||||
args_vec.push(OsString::from("-c"));
|
||||
args_vec.push(OsString::from(crate::SAFE_BARE_REPOSITORY_CONFIG));
|
||||
// Keep internal Git helper commands independent of configured hook directories.
|
||||
args_vec.push(OsString::from("-c"));
|
||||
args_vec.push(OsString::from(format!(
|
||||
|
||||
Reference in New Issue
Block a user