libutil: Create chmodPath function

Move the identical static `chmod_` functions in libstore to
libutil. the function is called `chmodPath` instead of `chmod`
as otherwise it will shadow the standard library chmod in the nix
namespace, which is somewhat confusing.

Change-Id: I7b5ce379c6c602e3d3a1bbc49dbb70b1ae8f7bad
This commit is contained in:
Artemis Tosini 2024-05-19 22:07:58 +00:00
parent 139d31f876
commit 5411fbf204
Signed by: artemist
SSH key fingerprint: SHA256:EsuWCwx6fjxxExxf65rX+ocQJJAdw4R1KarpFue6Uwc
4 changed files with 22 additions and 24 deletions

View file

@ -786,13 +786,6 @@ void DerivationGoal::tryLocalBuild() {
} }
static void chmod_(const Path & path, mode_t mode)
{
if (chmod(path.c_str(), mode) == -1)
throw SysError("setting permissions on '%s'", path);
}
/* Move/rename path 'src' to 'dst'. Temporarily make 'src' writable if /* Move/rename path 'src' to 'dst'. Temporarily make 'src' writable if
it's a directory and we're not root (to be able to update the it's a directory and we're not root (to be able to update the
directory's parent link ".."). */ directory's parent link ".."). */
@ -803,12 +796,12 @@ static void movePath(const Path & src, const Path & dst)
bool changePerm = (geteuid() && S_ISDIR(st.st_mode) && !(st.st_mode & S_IWUSR)); bool changePerm = (geteuid() && S_ISDIR(st.st_mode) && !(st.st_mode & S_IWUSR));
if (changePerm) if (changePerm)
chmod_(src, st.st_mode | S_IWUSR); chmodPath(src, st.st_mode | S_IWUSR);
renameFile(src, dst); renameFile(src, dst);
if (changePerm) if (changePerm)
chmod_(dst, st.st_mode); chmodPath(dst, st.st_mode);
} }

View file

@ -272,12 +272,6 @@ void LocalDerivationGoal::tryLocalBuild()
started(); started();
} }
static void chmod_(const Path & path, mode_t mode)
{
if (chmod(path.c_str(), mode) == -1)
throw SysError("setting permissions on '%s'", path);
}
/* Move/rename path 'src' to 'dst'. Temporarily make 'src' writable if /* Move/rename path 'src' to 'dst'. Temporarily make 'src' writable if
it's a directory and we're not root (to be able to update the it's a directory and we're not root (to be able to update the
@ -289,12 +283,12 @@ static void movePath(const Path & src, const Path & dst)
bool changePerm = (geteuid() && S_ISDIR(st.st_mode) && !(st.st_mode & S_IWUSR)); bool changePerm = (geteuid() && S_ISDIR(st.st_mode) && !(st.st_mode & S_IWUSR));
if (changePerm) if (changePerm)
chmod_(src, st.st_mode | S_IWUSR); chmodPath(src, st.st_mode | S_IWUSR);
renameFile(src, dst); renameFile(src, dst);
if (changePerm) if (changePerm)
chmod_(dst, st.st_mode); chmodPath(dst, st.st_mode);
} }
@ -696,7 +690,7 @@ void LocalDerivationGoal::startBuilder()
instead.) */ instead.) */
Path chrootTmpDir = chrootRootDir + "/tmp"; Path chrootTmpDir = chrootRootDir + "/tmp";
createDirs(chrootTmpDir); createDirs(chrootTmpDir);
chmod_(chrootTmpDir, 01777); chmodPath(chrootTmpDir, 01777);
/* Create a /etc/passwd with entries for the build user and the /* Create a /etc/passwd with entries for the build user and the
nobody account. The latter is kind of a hack to support nobody account. The latter is kind of a hack to support
@ -721,7 +715,7 @@ void LocalDerivationGoal::startBuilder()
build user. */ build user. */
Path chrootStoreDir = chrootRootDir + worker.store.storeDir; Path chrootStoreDir = chrootRootDir + worker.store.storeDir;
createDirs(chrootStoreDir); createDirs(chrootStoreDir);
chmod_(chrootStoreDir, 01775); chmodPath(chrootStoreDir, 01775);
if (buildUser && chown(chrootStoreDir.c_str(), 0, buildUser->getGID()) == -1) if (buildUser && chown(chrootStoreDir.c_str(), 0, buildUser->getGID()) == -1)
throw SysError("cannot change ownership of '%1%'", chrootStoreDir); throw SysError("cannot change ownership of '%1%'", chrootStoreDir);
@ -1862,7 +1856,7 @@ void LocalDerivationGoal::runChild()
auto dst = chrootRootDir + i.first; auto dst = chrootRootDir + i.first;
createDirs(dirOf(dst)); createDirs(dirOf(dst));
writeFile(dst, std::string_view((const char *) sh, sizeof(sh))); writeFile(dst, std::string_view((const char *) sh, sizeof(sh)));
chmod_(dst, 0555); chmodPath(dst, 0555);
} else } else
#endif #endif
doBind(i.second.source, chrootRootDir + i.first, i.second.optional); doBind(i.second.source, chrootRootDir + i.first, i.second.optional);
@ -1900,7 +1894,7 @@ void LocalDerivationGoal::runChild()
/* Make sure /dev/pts/ptmx is world-writable. With some /* Make sure /dev/pts/ptmx is world-writable. With some
Linux versions, it is created with permissions 0. */ Linux versions, it is created with permissions 0. */
chmod_(chrootRootDir + "/dev/pts/ptmx", 0666); chmodPath(chrootRootDir + "/dev/pts/ptmx", 0666);
} else { } else {
if (errno != EINVAL) if (errno != EINVAL)
throw SysError("mounting /dev/pts"); throw SysError("mounting /dev/pts");
@ -1911,7 +1905,7 @@ void LocalDerivationGoal::runChild()
/* Make /etc unwritable */ /* Make /etc unwritable */
if (!parsedDrv->useUidRange()) if (!parsedDrv->useUidRange())
chmod_(chrootRootDir + "/etc", 0555); chmodPath(chrootRootDir + "/etc", 0555);
/* Unshare this mount namespace. This is necessary because /* Unshare this mount namespace. This is necessary because
pivot_root() below changes the root of the mount pivot_root() below changes the root of the mount

View file

@ -184,6 +184,11 @@ Path canonPath(PathView path, bool resolveSymlinks)
return s.empty() ? "/" : std::move(s); return s.empty() ? "/" : std::move(s);
} }
void chmodPath(const Path & path, mode_t mode)
{
if (chmod(path.c_str(), mode) == -1)
throw SysError("setting permissions on '%s'", path);
}
Path dirOf(const PathView path) Path dirOf(const PathView path)
{ {
@ -1799,8 +1804,7 @@ AutoCloseFD createUnixDomainSocket(const Path & path, mode_t mode)
bind(fdSocket.get(), path); bind(fdSocket.get(), path);
if (chmod(path.c_str(), mode) == -1) chmodPath(path.c_str(), mode);
throw SysError("changing permissions on '%1%'", path);
if (listen(fdSocket.get(), 100) == -1) if (listen(fdSocket.get(), 100) == -1)
throw SysError("cannot listen on socket '%1%'", path); throw SysError("cannot listen on socket '%1%'", path);

View file

@ -77,6 +77,13 @@ Path absPath(Path path,
*/ */
Path canonPath(PathView path, bool resolveSymlinks = false); Path canonPath(PathView path, bool resolveSymlinks = false);
/**
* Change the permissions of a path
* Not called `chmod` as it shadows and could be confused with
* `int chmod(char *, mode_t)`, which does not handle errors
*/
void chmodPath(const Path & path, mode_t mode);
/** /**
* @return The directory part of the given canonical path, i.e., * @return The directory part of the given canonical path, i.e.,
* everything before the final `/`. If the path is the root or an * everything before the final `/`. If the path is the root or an