Skip to content

Commit

Permalink
Remove TOCTOU errors in Git clone (#10758)
Browse files Browse the repository at this point in the history
## Summary

We should try to remove, then fail gracefully, rather than checking
existence.
charliermarsh authored Jan 20, 2025
1 parent 23e8920 commit c0bde88
Showing 1 changed file with 10 additions and 6 deletions.
16 changes: 10 additions & 6 deletions crates/uv-git/src/git.rs
Original file line number Diff line number Diff line change
@@ -275,11 +275,13 @@ impl GitRemote {
// Otherwise start from scratch to handle corrupt git repositories.
// After our fetch (which is interpreted as a clone now) we do the same
// resolution to figure out what we cloned.
if into.exists() {
paths::remove_dir_all(into)?;
match fs_err::remove_dir_all(into) {
Ok(()) => {}
Err(e) if e.kind() == std::io::ErrorKind::NotFound => {}
Err(e) => return Err(e.into()),
}

paths::create_dir_all(into)?;
fs_err::create_dir_all(into)?;
let mut repo = GitRepository::init(into)?;
fetch(&mut repo, &self.url, reference, client)
.with_context(|| format!("failed to clone into: {}", into.user_display()))?;
@@ -392,9 +394,11 @@ impl GitCheckout {
/// This is a filesystem-to-filesystem clone.
fn clone_into(into: &Path, database: &GitDatabase, revision: GitOid) -> Result<Self> {
let dirname = into.parent().unwrap();
paths::create_dir_all(dirname)?;
if into.exists() {
paths::remove_dir_all(into)?;
fs_err::create_dir_all(dirname)?;
match fs_err::remove_dir_all(into) {
Ok(()) => {}
Err(e) if e.kind() == std::io::ErrorKind::NotFound => {}
Err(e) => return Err(e.into()),
}

// Perform a local clone of the repository, which will attempt to use

0 comments on commit c0bde88

Please sign in to comment.