mirror of
https://github.com/privatevoid-net/nix-super.git
synced 2024-11-23 22:46:16 +02:00
canonicalisePathMetaData(): Support a UID range
This commit is contained in:
parent
836573a9a2
commit
c3e0a68c7e
4 changed files with 39 additions and 17 deletions
|
@ -524,7 +524,7 @@ public:
|
||||||
|
|
||||||
uid_t getUID() { assert(uid); return uid; }
|
uid_t getUID() { assert(uid); return uid; }
|
||||||
gid_t getGID() { assert(gid); return gid; }
|
gid_t getGID() { assert(gid); return gid; }
|
||||||
uint32_t getIDCount() { return 1; }
|
uint32_t getIDCount() { return settings.idsPerBuild; }
|
||||||
std::vector<gid_t> getSupplementaryGIDs() { return supplementaryGIDs; }
|
std::vector<gid_t> getSupplementaryGIDs() { return supplementaryGIDs; }
|
||||||
|
|
||||||
bool findFreeUser();
|
bool findFreeUser();
|
||||||
|
@ -3744,7 +3744,10 @@ void DerivationGoal::registerOutputs()
|
||||||
/* Canonicalise first. This ensures that the path we're
|
/* Canonicalise first. This ensures that the path we're
|
||||||
rewriting doesn't contain a hard link to /etc/shadow or
|
rewriting doesn't contain a hard link to /etc/shadow or
|
||||||
something like that. */
|
something like that. */
|
||||||
canonicalisePathMetaData(actualPath, buildUser ? buildUser->getUID() : -1, inodesSeen);
|
canonicalisePathMetaData(
|
||||||
|
actualPath,
|
||||||
|
buildUser ? std::optional(std::make_pair(buildUser->getUID(), buildUser->getUID() + buildUser->getIDCount() - 1)) : std::nullopt,
|
||||||
|
inodesSeen);
|
||||||
|
|
||||||
/* FIXME: this is in-memory. */
|
/* FIXME: this is in-memory. */
|
||||||
StringSink sink;
|
StringSink sink;
|
||||||
|
@ -3819,7 +3822,10 @@ void DerivationGoal::registerOutputs()
|
||||||
/* Get rid of all weird permissions. This also checks that
|
/* Get rid of all weird permissions. This also checks that
|
||||||
all files are owned by the build user, if applicable. */
|
all files are owned by the build user, if applicable. */
|
||||||
canonicalisePathMetaData(actualPath,
|
canonicalisePathMetaData(actualPath,
|
||||||
buildUser && !rewritten ? buildUser->getUID() : -1, inodesSeen);
|
buildUser && !rewritten
|
||||||
|
? std::optional(std::make_pair(buildUser->getUID(), buildUser->getUID() + buildUser->getIDCount() - 1))
|
||||||
|
: std::nullopt,
|
||||||
|
inodesSeen);
|
||||||
|
|
||||||
/* For this output path, find the references to other paths
|
/* For this output path, find the references to other paths
|
||||||
contained in it. Compute the SHA-256 NAR hash at the same
|
contained in it. Compute the SHA-256 NAR hash at the same
|
||||||
|
|
|
@ -424,7 +424,10 @@ void canonicaliseTimestampAndPermissions(const Path & path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void canonicalisePathMetaData_(const Path & path, uid_t fromUid, InodesSeen & inodesSeen)
|
static void canonicalisePathMetaData_(
|
||||||
|
const Path & path,
|
||||||
|
std::optional<std::pair<uid_t, uid_t>> uidRange,
|
||||||
|
InodesSeen & inodesSeen)
|
||||||
{
|
{
|
||||||
checkInterrupt();
|
checkInterrupt();
|
||||||
|
|
||||||
|
@ -475,7 +478,7 @@ static void canonicalisePathMetaData_(const Path & path, uid_t fromUid, InodesSe
|
||||||
However, ignore files that we chown'ed ourselves previously to
|
However, ignore files that we chown'ed ourselves previously to
|
||||||
ensure that we don't fail on hard links within the same build
|
ensure that we don't fail on hard links within the same build
|
||||||
(i.e. "touch $out/foo; ln $out/foo $out/bar"). */
|
(i.e. "touch $out/foo; ln $out/foo $out/bar"). */
|
||||||
if (fromUid != (uid_t) -1 && st.st_uid != fromUid) {
|
if (uidRange && (st.st_uid < uidRange->first || st.st_uid > uidRange->second)) {
|
||||||
assert(!S_ISDIR(st.st_mode));
|
assert(!S_ISDIR(st.st_mode));
|
||||||
if (inodesSeen.find(Inode(st.st_dev, st.st_ino)) == inodesSeen.end())
|
if (inodesSeen.find(Inode(st.st_dev, st.st_ino)) == inodesSeen.end())
|
||||||
throw BuildError("invalid ownership on file '%1%'", path);
|
throw BuildError("invalid ownership on file '%1%'", path);
|
||||||
|
@ -509,14 +512,17 @@ static void canonicalisePathMetaData_(const Path & path, uid_t fromUid, InodesSe
|
||||||
if (S_ISDIR(st.st_mode)) {
|
if (S_ISDIR(st.st_mode)) {
|
||||||
DirEntries entries = readDirectory(path);
|
DirEntries entries = readDirectory(path);
|
||||||
for (auto & i : entries)
|
for (auto & i : entries)
|
||||||
canonicalisePathMetaData_(path + "/" + i.name, fromUid, inodesSeen);
|
canonicalisePathMetaData_(path + "/" + i.name, uidRange, inodesSeen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void canonicalisePathMetaData(const Path & path, uid_t fromUid, InodesSeen & inodesSeen)
|
void canonicalisePathMetaData(
|
||||||
|
const Path & path,
|
||||||
|
std::optional<std::pair<uid_t, uid_t>> uidRange,
|
||||||
|
InodesSeen & inodesSeen)
|
||||||
{
|
{
|
||||||
canonicalisePathMetaData_(path, fromUid, inodesSeen);
|
canonicalisePathMetaData_(path, uidRange, inodesSeen);
|
||||||
|
|
||||||
/* On platforms that don't have lchown(), the top-level path can't
|
/* On platforms that don't have lchown(), the top-level path can't
|
||||||
be a symlink, since we can't change its ownership. */
|
be a symlink, since we can't change its ownership. */
|
||||||
|
@ -531,10 +537,11 @@ void canonicalisePathMetaData(const Path & path, uid_t fromUid, InodesSeen & ino
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void canonicalisePathMetaData(const Path & path, uid_t fromUid)
|
void canonicalisePathMetaData(const Path & path,
|
||||||
|
std::optional<std::pair<uid_t, uid_t>> uidRange)
|
||||||
{
|
{
|
||||||
InodesSeen inodesSeen;
|
InodesSeen inodesSeen;
|
||||||
canonicalisePathMetaData(path, fromUid, inodesSeen);
|
canonicalisePathMetaData(path, uidRange, inodesSeen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1021,7 +1028,7 @@ void LocalStore::addToStore(const ValidPathInfo & info, Source & source,
|
||||||
|
|
||||||
autoGC();
|
autoGC();
|
||||||
|
|
||||||
canonicalisePathMetaData(realPath, -1);
|
canonicalisePathMetaData(realPath, {});
|
||||||
|
|
||||||
optimisePath(realPath); // FIXME: combine with hashPath()
|
optimisePath(realPath); // FIXME: combine with hashPath()
|
||||||
|
|
||||||
|
@ -1064,7 +1071,7 @@ StorePath LocalStore::addToStoreFromDump(const string & dump, const string & nam
|
||||||
} else
|
} else
|
||||||
writeFile(realPath, dump);
|
writeFile(realPath, dump);
|
||||||
|
|
||||||
canonicalisePathMetaData(realPath, -1);
|
canonicalisePathMetaData(realPath, {});
|
||||||
|
|
||||||
/* Register the SHA-256 hash of the NAR serialisation of
|
/* Register the SHA-256 hash of the NAR serialisation of
|
||||||
the path in the database. We may just have computed it
|
the path in the database. We may just have computed it
|
||||||
|
@ -1134,7 +1141,7 @@ StorePath LocalStore::addTextToStore(const string & name, const string & s,
|
||||||
|
|
||||||
writeFile(realPath, s);
|
writeFile(realPath, s);
|
||||||
|
|
||||||
canonicalisePathMetaData(realPath, -1);
|
canonicalisePathMetaData(realPath, {});
|
||||||
|
|
||||||
StringSink sink;
|
StringSink sink;
|
||||||
dumpString(s, sink);
|
dumpString(s, sink);
|
||||||
|
|
|
@ -311,9 +311,18 @@ typedef set<Inode> InodesSeen;
|
||||||
- the permissions are set of 444 or 555 (i.e., read-only with or
|
- the permissions are set of 444 or 555 (i.e., read-only with or
|
||||||
without execute permission; setuid bits etc. are cleared)
|
without execute permission; setuid bits etc. are cleared)
|
||||||
- the owner and group are set to the Nix user and group, if we're
|
- the owner and group are set to the Nix user and group, if we're
|
||||||
running as root. */
|
running as root.
|
||||||
void canonicalisePathMetaData(const Path & path, uid_t fromUid, InodesSeen & inodesSeen);
|
If uidRange is not empty, this function will throw an error if it
|
||||||
void canonicalisePathMetaData(const Path & path, uid_t fromUid);
|
encounters files owned by a user outside of the closed interval
|
||||||
|
[uidRange->first, uidRange->second].
|
||||||
|
*/
|
||||||
|
void canonicalisePathMetaData(
|
||||||
|
const Path & path,
|
||||||
|
std::optional<std::pair<uid_t, uid_t>> uidRange,
|
||||||
|
InodesSeen & inodesSeen);
|
||||||
|
void canonicalisePathMetaData(
|
||||||
|
const Path & path,
|
||||||
|
std::optional<std::pair<uid_t, uid_t>> uidRange);
|
||||||
|
|
||||||
void canonicaliseTimestampAndPermissions(const Path & path);
|
void canonicaliseTimestampAndPermissions(const Path & path);
|
||||||
|
|
||||||
|
|
|
@ -500,7 +500,7 @@ static void registerValidity(bool reregister, bool hashGiven, bool canonicalise)
|
||||||
if (!store->isValidPath(info->path) || reregister) {
|
if (!store->isValidPath(info->path) || reregister) {
|
||||||
/* !!! races */
|
/* !!! races */
|
||||||
if (canonicalise)
|
if (canonicalise)
|
||||||
canonicalisePathMetaData(store->printStorePath(info->path), -1);
|
canonicalisePathMetaData(store->printStorePath(info->path), {});
|
||||||
if (!hashGiven) {
|
if (!hashGiven) {
|
||||||
HashResult hash = hashPath(htSHA256, store->printStorePath(info->path));
|
HashResult hash = hashPath(htSHA256, store->printStorePath(info->path));
|
||||||
info->narHash = hash.first;
|
info->narHash = hash.first;
|
||||||
|
|
Loading…
Reference in a new issue