Skip to content

Commit 26b33aa

Browse files
authored
Merge pull request #12869 from DeterminateSystems/empty-git-repo
Apply makeNotAllowedError to empty Git repos
2 parents 70dcd73 + 67e957b commit 26b33aa

File tree

6 files changed

+45
-12
lines changed

6 files changed

+45
-12
lines changed

src/libexpr/eval.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ EvalState::EvalState(
273273

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

src/libfetchers/filtering-source-accessor.cc

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,18 +58,23 @@ void FilteringSourceAccessor::checkAccess(const CanonPath & path)
5858
struct AllowListSourceAccessorImpl : AllowListSourceAccessor
5959
{
6060
std::set<CanonPath> allowedPrefixes;
61+
std::unordered_set<CanonPath> allowedPaths;
6162

6263
AllowListSourceAccessorImpl(
6364
ref<SourceAccessor> next,
6465
std::set<CanonPath> && allowedPrefixes,
66+
std::unordered_set<CanonPath> && allowedPaths,
6567
MakeNotAllowedError && makeNotAllowedError)
6668
: AllowListSourceAccessor(SourcePath(next), std::move(makeNotAllowedError))
6769
, allowedPrefixes(std::move(allowedPrefixes))
70+
, allowedPaths(std::move(allowedPaths))
6871
{ }
6972

7073
bool isAllowed(const CanonPath & path) override
7174
{
72-
return path.isAllowed(allowedPrefixes);
75+
return
76+
allowedPaths.contains(path)
77+
|| path.isAllowed(allowedPrefixes);
7378
}
7479

7580
void allowPrefix(CanonPath prefix) override
@@ -81,9 +86,14 @@ struct AllowListSourceAccessorImpl : AllowListSourceAccessor
8186
ref<AllowListSourceAccessor> AllowListSourceAccessor::create(
8287
ref<SourceAccessor> next,
8388
std::set<CanonPath> && allowedPrefixes,
89+
std::unordered_set<CanonPath> && allowedPaths,
8490
MakeNotAllowedError && makeNotAllowedError)
8591
{
86-
return make_ref<AllowListSourceAccessorImpl>(next, std::move(allowedPrefixes), std::move(makeNotAllowedError));
92+
return make_ref<AllowListSourceAccessorImpl>(
93+
next,
94+
std::move(allowedPrefixes),
95+
std::move(allowedPaths),
96+
std::move(makeNotAllowedError));
8797
}
8898

8999
bool CachingFilteringSourceAccessor::isAllowed(const CanonPath & path)

src/libfetchers/git-utils.cc

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1215,16 +1215,12 @@ ref<SourceAccessor> GitRepoImpl::getAccessor(
12151215
ref<SourceAccessor> GitRepoImpl::getAccessor(const WorkdirInfo & wd, bool exportIgnore, MakeNotAllowedError makeNotAllowedError)
12161216
{
12171217
auto self = ref<GitRepoImpl>(shared_from_this());
1218-
/* In case of an empty workdir, return an empty in-memory tree. We
1219-
cannot use AllowListSourceAccessor because it would return an
1220-
error for the root (and we can't add the root to the allow-list
1221-
since that would allow access to all its children). */
12221218
ref<SourceAccessor> fileAccessor =
1223-
wd.files.empty()
1224-
? makeEmptySourceAccessor()
1225-
: AllowListSourceAccessor::create(
1219+
AllowListSourceAccessor::create(
12261220
makeFSSourceAccessor(path),
1227-
std::set<CanonPath> { wd.files },
1221+
std::set<CanonPath>{ wd.files },
1222+
// Always allow access to the root, but not its children.
1223+
std::unordered_set<CanonPath>{CanonPath::root},
12281224
std::move(makeNotAllowedError)).cast<SourceAccessor>();
12291225
if (exportIgnore)
12301226
return make_ref<GitExportIgnoreSourceAccessor>(self, fileAccessor, std::nullopt);

src/libfetchers/include/nix/fetchers/filtering-source-accessor.hh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
#include "nix/util/source-path.hh"
44

5+
#include <unordered_set>
6+
57
namespace nix {
68

79
/**
@@ -70,6 +72,7 @@ struct AllowListSourceAccessor : public FilteringSourceAccessor
7072
static ref<AllowListSourceAccessor> create(
7173
ref<SourceAccessor> next,
7274
std::set<CanonPath> && allowedPrefixes,
75+
std::unordered_set<CanonPath> && allowedPaths,
7376
MakeNotAllowedError && makeNotAllowedError);
7477

7578
using FilteringSourceAccessor::FilteringSourceAccessor;

tests/functional/flakes/meson.build

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ suites += {
2929
'non-flake-inputs.sh',
3030
'relative-paths.sh',
3131
'symlink-paths.sh',
32-
'debugger.sh'
32+
'debugger.sh',
33+
'source-paths.sh',
3334
],
3435
'workdir': meson.current_source_dir(),
3536
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#!/usr/bin/env bash
2+
3+
source ./common.sh
4+
5+
requireGit
6+
7+
repo=$TEST_ROOT/repo
8+
9+
createGitRepo "$repo"
10+
11+
cat > "$repo/flake.nix" <<EOF
12+
{
13+
outputs = { ... }: {
14+
x = 1;
15+
};
16+
}
17+
EOF
18+
19+
expectStderr 1 nix eval "$repo#x" | grepQuiet "error: Path 'flake.nix' in the repository \"$repo\" is not tracked by Git."
20+
21+
git -C "$repo" add flake.nix
22+
23+
[[ $(nix eval "$repo#x") = 1 ]]

0 commit comments

Comments
 (0)