Skip to content

fix: always use absolute paths#323

Merged
Stebalien merged 1 commit intomasterfrom
steb/fix-abs-path
Feb 8, 2025
Merged

fix: always use absolute paths#323
Stebalien merged 1 commit intomasterfrom
steb/fix-abs-path

Conversation

@Stebalien
Copy link
Copy Markdown
Owner

We used absolute paths in the builder when making directories and in create_named but this didn't cover Builder::make_in and technically introduced a small race in some unnamed tempfile cases (i.e., when we can't atomically create unnamed temporary files and need to create then immediately delete them).

Instead, we now resolve the filename into an absolute path inside the main create helper.

We used absolute paths in the builder when making directories and in
`create_named` but this didn't cover `Builder::make_in` and technically
introduced a small race in some unnamed tempfile cases (i.e., when we
can't atomically create unnamed temporary files and need to create then
immediately delete them).

Instead, we now resolve the filename into an absolute path inside the
main create helper.
@Stebalien Stebalien merged commit 8afa07a into master Feb 8, 2025
@Stebalien Stebalien deleted the steb/fix-abs-path branch February 8, 2025 23:17
@nagisa
Copy link
Copy Markdown

nagisa commented Mar 7, 2025

I want to report that this has caused breakage in my code that was written along the lines of

Builder::new().make_in("", |filename| {
    Ok(std::fs::File::from(rustix::fs::openat(dirfd, filename, flags, mode)?))
});

functionally with the intent to use tempfile for the express purpose of randomly generating the temporary file name. The reason this code is written the way it is because the base directory is only known by its descriptor and not path.

In the past the code would properly create the temporary file within directory referenced by dirfd, but now it creates the file in the current working directory instead.

To be fair there is nothing in the documentation of make_in that suggests this is a valid use-case so I'm not going to ask to revert this code or anything, but it would be neat if tempfile exposed a a way to generate a random filename as was possible before with make_in.

@Stebalien
Copy link
Copy Markdown
Owner Author

Hm. The issue is that tempfile needs to know where exactly the file lives so it can correctly delete it. In your case, it would have attempted to delete filename in the current directory, ignoring dirfd.

I'm curious, what's your use-case? I've considered supporting directory-relative temporary files (#40) but I've never had a strong use-case.

@nagisa
Copy link
Copy Markdown

nagisa commented Mar 7, 2025

Aha, nicely spotted. Yeah, deletion would have probably been buggy too. The only reason I hadn't hit it was because in the happy path all of these temporary files would get retained (into_temp_path() + renameat2 + keep) and renameat2 failure would've been the only time deletion logic would've triggered.

To elaborate more on the overarching use-case: my code is implementing a filesystem-level cache. One of the concerns are that the lookups for a given filename should only succeed once the value has been fully written (hence the rename(at2).) And the reason for dirfd use was primarily due to not wanting to deal with all possible corner cases of the meaning of base directory path changing. This in my mind seemed like a significant enough concern where the binary might run for months at a time and rm -rf everything or mv cache elsewhere being plausible enough (it isn't invalid to remove the files within the directory but I didn't want to deal with the directory itself getting nuked.)

To be honest I don't mind at all implementing all of that funky logic myself, tempfile came in as a dependency, as I mentioned, chiefly to avoid implementing the somewhat subtle random name generation code and instead focus on the subtlety in the other parts of the logic there ^^

takumi-earth pushed a commit to earthlings-dev/tempfile that referenced this pull request Jan 27, 2026
We used absolute paths in the builder when making directories and in
`create_named` but this didn't cover `Builder::make_in` and technically
introduced a small race in some unnamed tempfile cases (i.e., when we
can't atomically create unnamed temporary files and need to create then
immediately delete them).

Instead, we now resolve the filename into an absolute path inside the
main create helper.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants