1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2025-06-25 19:01:16 +02:00

Merge pull request #12882 from NixOS/mergify/bp/2.28-maintenance/pr-12869

Apply makeNotAllowedError to empty Git repos (backport #12869)
This commit is contained in:
Eelco Dolstra 2025-04-03 10:07:07 +02:00 committed by GitHub
commit 3a5bbca252
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 45 additions and 12 deletions

View file

@ -273,7 +273,7 @@ EvalState::EvalState(
/* Apply access control if needed. */ /* Apply access control if needed. */
if (settings.restrictEval || settings.pureEval) if (settings.restrictEval || settings.pureEval)
accessor = AllowListSourceAccessor::create(accessor, {}, accessor = AllowListSourceAccessor::create(accessor, {}, {},
[&settings](const CanonPath & path) -> RestrictedPathError { [&settings](const CanonPath & path) -> RestrictedPathError {
auto modeInformation = settings.pureEval auto modeInformation = settings.pureEval
? "in pure evaluation mode (use '--impure' to override)" ? "in pure evaluation mode (use '--impure' to override)"

View file

@ -58,18 +58,23 @@ void FilteringSourceAccessor::checkAccess(const CanonPath & path)
struct AllowListSourceAccessorImpl : AllowListSourceAccessor struct AllowListSourceAccessorImpl : AllowListSourceAccessor
{ {
std::set<CanonPath> allowedPrefixes; std::set<CanonPath> allowedPrefixes;
std::unordered_set<CanonPath> allowedPaths;
AllowListSourceAccessorImpl( AllowListSourceAccessorImpl(
ref<SourceAccessor> next, ref<SourceAccessor> next,
std::set<CanonPath> && allowedPrefixes, std::set<CanonPath> && allowedPrefixes,
std::unordered_set<CanonPath> && allowedPaths,
MakeNotAllowedError && makeNotAllowedError) MakeNotAllowedError && makeNotAllowedError)
: AllowListSourceAccessor(SourcePath(next), std::move(makeNotAllowedError)) : AllowListSourceAccessor(SourcePath(next), std::move(makeNotAllowedError))
, allowedPrefixes(std::move(allowedPrefixes)) , allowedPrefixes(std::move(allowedPrefixes))
, allowedPaths(std::move(allowedPaths))
{ } { }
bool isAllowed(const CanonPath & path) override bool isAllowed(const CanonPath & path) override
{ {
return path.isAllowed(allowedPrefixes); return
allowedPaths.contains(path)
|| path.isAllowed(allowedPrefixes);
} }
void allowPrefix(CanonPath prefix) override void allowPrefix(CanonPath prefix) override
@ -81,9 +86,14 @@ struct AllowListSourceAccessorImpl : AllowListSourceAccessor
ref<AllowListSourceAccessor> AllowListSourceAccessor::create( ref<AllowListSourceAccessor> AllowListSourceAccessor::create(
ref<SourceAccessor> next, ref<SourceAccessor> next,
std::set<CanonPath> && allowedPrefixes, std::set<CanonPath> && allowedPrefixes,
std::unordered_set<CanonPath> && allowedPaths,
MakeNotAllowedError && makeNotAllowedError) MakeNotAllowedError && makeNotAllowedError)
{ {
return make_ref<AllowListSourceAccessorImpl>(next, std::move(allowedPrefixes), std::move(makeNotAllowedError)); return make_ref<AllowListSourceAccessorImpl>(
next,
std::move(allowedPrefixes),
std::move(allowedPaths),
std::move(makeNotAllowedError));
} }
bool CachingFilteringSourceAccessor::isAllowed(const CanonPath & path) bool CachingFilteringSourceAccessor::isAllowed(const CanonPath & path)

View file

@ -1215,16 +1215,12 @@ ref<SourceAccessor> GitRepoImpl::getAccessor(
ref<SourceAccessor> GitRepoImpl::getAccessor(const WorkdirInfo & wd, bool exportIgnore, MakeNotAllowedError makeNotAllowedError) ref<SourceAccessor> GitRepoImpl::getAccessor(const WorkdirInfo & wd, bool exportIgnore, MakeNotAllowedError makeNotAllowedError)
{ {
auto self = ref<GitRepoImpl>(shared_from_this()); auto self = ref<GitRepoImpl>(shared_from_this());
/* In case of an empty workdir, return an empty in-memory tree. We
cannot use AllowListSourceAccessor because it would return an
error for the root (and we can't add the root to the allow-list
since that would allow access to all its children). */
ref<SourceAccessor> fileAccessor = ref<SourceAccessor> fileAccessor =
wd.files.empty() AllowListSourceAccessor::create(
? makeEmptySourceAccessor()
: AllowListSourceAccessor::create(
makeFSSourceAccessor(path), makeFSSourceAccessor(path),
std::set<CanonPath> { wd.files }, std::set<CanonPath>{ wd.files },
// Always allow access to the root, but not its children.
std::unordered_set<CanonPath>{CanonPath::root},
std::move(makeNotAllowedError)).cast<SourceAccessor>(); std::move(makeNotAllowedError)).cast<SourceAccessor>();
if (exportIgnore) if (exportIgnore)
return make_ref<GitExportIgnoreSourceAccessor>(self, fileAccessor, std::nullopt); return make_ref<GitExportIgnoreSourceAccessor>(self, fileAccessor, std::nullopt);

View file

@ -2,6 +2,8 @@
#include "nix/util/source-path.hh" #include "nix/util/source-path.hh"
#include <unordered_set>
namespace nix { namespace nix {
/** /**
@ -70,6 +72,7 @@ struct AllowListSourceAccessor : public FilteringSourceAccessor
static ref<AllowListSourceAccessor> create( static ref<AllowListSourceAccessor> create(
ref<SourceAccessor> next, ref<SourceAccessor> next,
std::set<CanonPath> && allowedPrefixes, std::set<CanonPath> && allowedPrefixes,
std::unordered_set<CanonPath> && allowedPaths,
MakeNotAllowedError && makeNotAllowedError); MakeNotAllowedError && makeNotAllowedError);
using FilteringSourceAccessor::FilteringSourceAccessor; using FilteringSourceAccessor::FilteringSourceAccessor;

View file

@ -29,7 +29,8 @@ suites += {
'non-flake-inputs.sh', 'non-flake-inputs.sh',
'relative-paths.sh', 'relative-paths.sh',
'symlink-paths.sh', 'symlink-paths.sh',
'debugger.sh' 'debugger.sh',
'source-paths.sh',
], ],
'workdir': meson.current_source_dir(), 'workdir': meson.current_source_dir(),
} }

View file

@ -0,0 +1,23 @@
#!/usr/bin/env bash
source ./common.sh
requireGit
repo=$TEST_ROOT/repo
createGitRepo "$repo"
cat > "$repo/flake.nix" <<EOF
{
outputs = { ... }: {
x = 1;
};
}
EOF
expectStderr 1 nix eval "$repo#x" | grepQuiet "error: Path 'flake.nix' in the repository \"$repo\" is not tracked by Git."
git -C "$repo" add flake.nix
[[ $(nix eval "$repo#x") = 1 ]]