mirror of
https://github.com/NixOS/nix.git
synced 2025-11-28 05:00:58 +01:00
Merge pull request #14651 from NixOS/restore-sink-more-openat2
libutil: Use openFileEnsureBeneathNoSymlinks in RestoreSink::createRe…
This commit is contained in:
commit
c38349583f
4 changed files with 10 additions and 1 deletions
|
|
@ -351,6 +351,10 @@ TEST(openFileEnsureBeneathNoSymlinks, works)
|
||||||
sink.createDirectory(
|
sink.createDirectory(
|
||||||
CanonPath("a/b/c/f"), [](FileSystemObjectSink & dirSink, const CanonPath & relPath) {}),
|
CanonPath("a/b/c/f"), [](FileSystemObjectSink & dirSink, const CanonPath & relPath) {}),
|
||||||
SymlinkNotAllowed);
|
SymlinkNotAllowed);
|
||||||
|
ASSERT_THROW(
|
||||||
|
sink.createRegularFile(
|
||||||
|
CanonPath("a/b/c/regular"), [](CreateRegularFileSink & crf) { crf("some contents"); }),
|
||||||
|
SymlinkNotAllowed);
|
||||||
}
|
}
|
||||||
|
|
||||||
AutoCloseFD dirFd = openDirectory(tmpDir);
|
AutoCloseFD dirFd = openDirectory(tmpDir);
|
||||||
|
|
|
||||||
|
|
@ -170,7 +170,7 @@ void RestoreSink::createRegularFile(const CanonPath & path, std::function<void(C
|
||||||
constexpr int flags = O_CREAT | O_EXCL | O_WRONLY | O_CLOEXEC;
|
constexpr int flags = O_CREAT | O_EXCL | O_WRONLY | O_CLOEXEC;
|
||||||
if (!dirFd)
|
if (!dirFd)
|
||||||
return ::open(p.c_str(), flags, 0666);
|
return ::open(p.c_str(), flags, 0666);
|
||||||
return ::openat(dirFd.get(), path.rel_c_str(), flags, 0666);
|
return unix::openFileEnsureBeneathNoSymlinks(dirFd.get(), path, flags, 0666);
|
||||||
}();
|
}();
|
||||||
#endif
|
#endif
|
||||||
;
|
;
|
||||||
|
|
|
||||||
|
|
@ -263,6 +263,8 @@ struct SymlinkNotAllowed : public Error
|
||||||
* @param flags O_* flags
|
* @param flags O_* flags
|
||||||
* @param mode Mode for O_{CREAT,TMPFILE}
|
* @param mode Mode for O_{CREAT,TMPFILE}
|
||||||
*
|
*
|
||||||
|
* @pre path.isRoot() is false
|
||||||
|
*
|
||||||
* @throws SymlinkNotAllowed if any path components
|
* @throws SymlinkNotAllowed if any path components
|
||||||
*/
|
*/
|
||||||
Descriptor openFileEnsureBeneathNoSymlinks(Descriptor dirFd, const CanonPath & path, int flags, mode_t mode = 0);
|
Descriptor openFileEnsureBeneathNoSymlinks(Descriptor dirFd, const CanonPath & path, int flags, mode_t mode = 0);
|
||||||
|
|
|
||||||
|
|
@ -269,6 +269,7 @@ openFileEnsureBeneathNoSymlinksIterative(Descriptor dirFd, const CanonPath & pat
|
||||||
{
|
{
|
||||||
AutoCloseFD parentFd;
|
AutoCloseFD parentFd;
|
||||||
auto nrComponents = std::ranges::distance(path);
|
auto nrComponents = std::ranges::distance(path);
|
||||||
|
assert(nrComponents >= 1);
|
||||||
auto components = std::views::take(path, nrComponents - 1); /* Everything but last component */
|
auto components = std::views::take(path, nrComponents - 1); /* Everything but last component */
|
||||||
auto getParentFd = [&]() { return parentFd ? parentFd.get() : dirFd; };
|
auto getParentFd = [&]() { return parentFd ? parentFd.get() : dirFd; };
|
||||||
|
|
||||||
|
|
@ -320,6 +321,8 @@ openFileEnsureBeneathNoSymlinksIterative(Descriptor dirFd, const CanonPath & pat
|
||||||
|
|
||||||
Descriptor unix::openFileEnsureBeneathNoSymlinks(Descriptor dirFd, const CanonPath & path, int flags, mode_t mode)
|
Descriptor unix::openFileEnsureBeneathNoSymlinks(Descriptor dirFd, const CanonPath & path, int flags, mode_t mode)
|
||||||
{
|
{
|
||||||
|
assert(!path.rel().starts_with('/')); /* Just in case the invariant is somehow broken. */
|
||||||
|
assert(!path.isRoot());
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
auto maybeFd = linux::openat2(
|
auto maybeFd = linux::openat2(
|
||||||
dirFd, path.rel_c_str(), flags, static_cast<uint64_t>(mode), RESOLVE_BENEATH | RESOLVE_NO_SYMLINKS);
|
dirFd, path.rel_c_str(), flags, static_cast<uint64_t>(mode), RESOLVE_BENEATH | RESOLVE_NO_SYMLINKS);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue