1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2025-07-05 12:21:48 +02:00

Merge commit from fork

Fix unsafe NAR unpacking
This commit is contained in:
Eelco Dolstra 2024-09-10 12:42:55 +02:00 committed by GitHub
commit 9c0e968843
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 113 additions and 37 deletions

View file

@ -23,7 +23,7 @@ struct ArchiveSettings : Config
false,
#endif
"use-case-hack",
"Whether to enable a Darwin-specific hack for dealing with file name collisions."};
"Whether to enable a macOS-specific hack for dealing with file name case collisions."};
};
static ArchiveSettings archiveSettings;
@ -214,11 +214,13 @@ static void parse(FileSystemObjectSink & sink, Source & source, const CanonPath
else if (t == "directory") {
sink.createDirectory(path);
std::string prevName;
while (1) {
s = getString();
if (s == "entry") {
std::string name, prevName;
std::string name;
s = getString();
if (s != "(") throw badArchive("expected open tag");
@ -241,6 +243,9 @@ static void parse(FileSystemObjectSink & sink, Source & source, const CanonPath
debug("case collision between '%1%' and '%2%'", i->first, name);
name += caseHackSuffix;
name += std::to_string(++i->second);
auto j = names.find(name);
if (j != names.end())
throw Error("NAR contains file name '%s' that collides with case-hacked file name '%s'", prevName, j->first);
} else
names[name] = 0;
}

View file

@ -68,10 +68,19 @@ static RestoreSinkSettings restoreSinkSettings;
static GlobalConfig::Register r1(&restoreSinkSettings);
static std::filesystem::path append(const std::filesystem::path & src, const CanonPath & path)
{
auto dst = src;
if (!path.rel().empty())
dst /= path.rel();
return dst;
}
void RestoreSink::createDirectory(const CanonPath & path)
{
std::filesystem::create_directory(dstPath / path.rel());
auto p = append(dstPath, path);
if (!std::filesystem::create_directory(p))
throw Error("path '%s' already exists", p.string());
};
struct RestoreRegularFile : CreateRegularFileSink {
@ -93,14 +102,6 @@ struct RestoreRegularFile : CreateRegularFileSink {
void preallocateContents(uint64_t size) override;
};
static std::filesystem::path append(const std::filesystem::path & src, const CanonPath & path)
{
auto dst = src;
if (!path.rel().empty())
dst /= path.rel();
return dst;
}
void RestoreSink::createRegularFile(const CanonPath & path, std::function<void(CreateRegularFileSink &)> func)
{
auto p = append(dstPath, path);