Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 16 additions & 3 deletions src/libstore/unix/build/derivation-builder.cc
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "nix/store/build/derivation-builder.hh"
#include "nix/util/file-system-at.hh"
#include "nix/util/file-system.hh"
#include "nix/store/local-store.hh"
#include "nix/util/processes.hh"
Expand Down Expand Up @@ -384,11 +385,16 @@ class DerivationBuilderImpl : public DerivationBuilder, public DerivationBuilder

/**
* Make a file owned by the builder addressed by its file descriptor.
*
* @param path Only used for error messages.
*/
void chownToBuilder(int fd, const std::filesystem::path & path);

/**
* Create a file in `tmpDir` owned by the builder.
*
* @param Name must not contain more than one path segment and none of them must be `..`, `.`
* Otherwise this function throws an Error.
*/
void writeBuilderFile(const std::string & name, std::string_view contents);

Expand Down Expand Up @@ -1264,9 +1270,16 @@ void DerivationBuilderImpl::chownToBuilder(int fd, const std::filesystem::path &

void DerivationBuilderImpl::writeBuilderFile(const std::string & name, std::string_view contents)
{
auto path = std::filesystem::path(tmpDir) / name;
AutoCloseFD fd{
openat(tmpDirFd.get(), name.c_str(), O_WRONLY | O_TRUNC | O_CREAT | O_CLOEXEC | O_EXCL | O_NOFOLLOW, 0666)};
auto relPath = CanonPath(name);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be worth adding a CanonFilename type to verify this in the constructor or something I suppose.

/* Path must be the same after normalisation. This is an additional sanity check in addition to
existing parsing checks for non-structured attrs exportReferencesGraph. In practice we only expect
a single path component without any `..`, `.` components. */
if (relPath.rel() != name || std::ranges::distance(relPath) != 1)
throw Error("invalid file name for a builder file: '%s'", name);

AutoCloseFD fd = openFileEnsureBeneathNoSymlinks(
tmpDirFd.get(), relPath, O_WRONLY | O_TRUNC | O_CREAT | O_CLOEXEC | O_EXCL | O_NOFOLLOW, 0666);
auto path = tmpDir / relPath.rel(); /* This is used only for error messages. */
if (!fd)
throw SysError("creating file %s", PathFmt(path));
writeFile(fd.get(), contents);
Expand Down
Loading