1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-11-25 11:49:35 +01:00

SourceAccessor: Make lstat() virtual

With FilteringSourceAccessor, lstat() needs to throw a different
exception if the path is inaccessible than if it doesn't exist.
This commit is contained in:
Eelco Dolstra 2025-09-22 22:43:12 +02:00 committed by John Ericson
parent 46095284f1
commit 55c7ef9d40
5 changed files with 33 additions and 2 deletions

View file

@ -3127,6 +3127,11 @@ SourcePath EvalState::findFile(const LookupPath & lookupPath, const std::string_
auto res = (r / CanonPath(suffix)).resolveSymlinks(); auto res = (r / CanonPath(suffix)).resolveSymlinks();
if (res.pathExists()) if (res.pathExists())
return res; return res;
// Backward compatibility hack: throw an exception if access
// to this path is not allowed.
if (auto accessor = res.accessor.dynamic_pointer_cast<FilteringSourceAccessor>())
accessor->checkAccess(res.path);
} }
if (hasPrefix(path, "nix/")) if (hasPrefix(path, "nix/"))
@ -3193,6 +3198,11 @@ std::optional<SourcePath> EvalState::resolveLookupPathPath(const LookupPath::Pat
if (path.resolveSymlinks().pathExists()) if (path.resolveSymlinks().pathExists())
return finish(std::move(path)); return finish(std::move(path));
else { else {
// Backward compatibility hack: throw an exception if access
// to this path is not allowed.
if (auto accessor = path.accessor.dynamic_pointer_cast<FilteringSourceAccessor>())
accessor->checkAccess(path.path);
logWarning({.msg = HintFmt("Nix search path entry '%1%' does not exist, ignoring", value)}); logWarning({.msg = HintFmt("Nix search path entry '%1%' does not exist, ignoring", value)});
} }
} }

View file

@ -16,15 +16,26 @@ std::string FilteringSourceAccessor::readFile(const CanonPath & path)
return next->readFile(prefix / path); return next->readFile(prefix / path);
} }
void FilteringSourceAccessor::readFile(const CanonPath & path, Sink & sink, std::function<void(uint64_t)> sizeCallback)
{
checkAccess(path);
return next->readFile(prefix / path, sink, sizeCallback);
}
bool FilteringSourceAccessor::pathExists(const CanonPath & path) bool FilteringSourceAccessor::pathExists(const CanonPath & path)
{ {
return isAllowed(path) && next->pathExists(prefix / path); return isAllowed(path) && next->pathExists(prefix / path);
} }
std::optional<SourceAccessor::Stat> FilteringSourceAccessor::maybeLstat(const CanonPath & path) std::optional<SourceAccessor::Stat> FilteringSourceAccessor::maybeLstat(const CanonPath & path)
{
return isAllowed(path) ? next->maybeLstat(prefix / path) : std::nullopt;
}
SourceAccessor::Stat FilteringSourceAccessor::lstat(const CanonPath & path)
{ {
checkAccess(path); checkAccess(path);
return next->maybeLstat(prefix / path); return next->lstat(prefix / path);
} }
SourceAccessor::DirEntries FilteringSourceAccessor::readDirectory(const CanonPath & path) SourceAccessor::DirEntries FilteringSourceAccessor::readDirectory(const CanonPath & path)

View file

@ -36,8 +36,12 @@ struct FilteringSourceAccessor : SourceAccessor
std::string readFile(const CanonPath & path) override; std::string readFile(const CanonPath & path) override;
void readFile(const CanonPath & path, Sink & sink, std::function<void(uint64_t)> sizeCallback) override;
bool pathExists(const CanonPath & path) override; bool pathExists(const CanonPath & path) override;
Stat lstat(const CanonPath & path) override;
std::optional<Stat> maybeLstat(const CanonPath & path) override; std::optional<Stat> maybeLstat(const CanonPath & path) override;
DirEntries readDirectory(const CanonPath & path) override; DirEntries readDirectory(const CanonPath & path) override;

View file

@ -121,7 +121,7 @@ struct SourceAccessor : std::enable_shared_from_this<SourceAccessor>
std::string typeString(); std::string typeString();
}; };
Stat lstat(const CanonPath & path); virtual Stat lstat(const CanonPath & path);
virtual std::optional<Stat> maybeLstat(const CanonPath & path) = 0; virtual std::optional<Stat> maybeLstat(const CanonPath & path) = 0;

View file

@ -27,6 +27,12 @@ struct MountedSourceAccessorImpl : MountedSourceAccessor
return accessor->readFile(subpath); return accessor->readFile(subpath);
} }
Stat lstat(const CanonPath & path) override
{
auto [accessor, subpath] = resolve(path);
return accessor->lstat(subpath);
}
std::optional<Stat> maybeLstat(const CanonPath & path) override std::optional<Stat> maybeLstat(const CanonPath & path) override
{ {
auto [accessor, subpath] = resolve(path); auto [accessor, subpath] = resolve(path);