1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-11-08 19:46:02 +01:00

Prevent infinite symlink loop in followLinksToStore()

The followLinksToStore() function could hang indefinitely when encountering
symlink cycles outside the Nix store, causing 100% CPU usage and blocking
any operations that use this function.

This affects multiple commands including nix-store --query, --delete,
--verify, nix-env, and nix-copy-closure when given paths with symlink cycles.

The fix adds a maximum limit of 1024 symlink follows (matching the limit
used by canonPath) and throws an error when exceeded, preventing the
infinite loop while preserving the original semantics of stopping at
the first path inside the store.
This commit is contained in:
Jörg Thalheim 2025-09-29 12:21:57 +02:00
parent 7cbc0f97e7
commit 5ec9138179

View file

@ -58,12 +58,22 @@ std::pair<StorePath, Path> StoreDirConfig::toStorePath(PathView path) const
Path Store::followLinksToStore(std::string_view _path) const
{
Path path = absPath(std::string(_path));
// Limit symlink follows to prevent infinite loops
unsigned int followCount = 0;
const unsigned int maxFollow = 1024;
while (!isInStore(path)) {
if (!std::filesystem::is_symlink(path))
break;
if (++followCount >= maxFollow)
throw Error("too many symbolic links encountered while resolving '%s'", _path);
auto target = readLink(path);
path = absPath(target, dirOf(path));
}
if (!isInStore(path))
throw BadStorePath("path '%1%' is not in the Nix store", path);
return path;