cool#8703 - Drop random node creation and rely on inherited fd.

Re-using an inherited file descriptor to /dev/urandom frees us
from problems with mount options including 'nodev' and removes a
capability from the set we need.

Change-Id: I70337e923f802d7efbd3159c11a4e39f6529b6e6
Signed-off-by: Michael Meeks <michael.meeks@collabora.com>
This commit is contained in:
Michael Meeks 2024-04-06 15:07:30 +01:00 committed by Andras Timar
parent 7311352dd6
commit 144b701453
13 changed files with 21 additions and 116 deletions

View file

@ -463,7 +463,7 @@ CAPABILITIES = $(if @ENABLE_SETCAP@,true,false)
RUN_GDB = $(if $(GDB_FRONTEND),$(GDB_FRONTEND),gdb --tui --args)
if ENABLE_SETCAP
SET_CAPS_COMMAND=sudo @SETCAP@ cap_fowner,cap_chown,cap_mknod,cap_sys_chroot=ep coolforkit && sudo @SETCAP@ cap_sys_admin=ep coolmount
SET_CAPS_COMMAND=sudo @SETCAP@ cap_fowner,cap_chown,cap_sys_chroot=ep coolforkit && sudo @SETCAP@ cap_sys_admin=ep coolmount
else
SET_CAPS_COMMAND=echo "Skipping capability setting"
endif

View file

@ -14,6 +14,7 @@
#include "FileUtil.hpp"
#include "JailUtil.hpp"
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
@ -314,107 +315,6 @@ void setupChildRoot(bool bindMount, const std::string& childRoot, const std::str
"mount_jail_tree config in coolwsd.xml.");
}
/// Create a random device, either via mknod or by bind-mounting.
bool createRandomDeviceInJail(const std::string& root, const std::string& devicePath, dev_t dev)
{
const std::string absPath = root + devicePath;
if (FileUtil::Stat(absPath).exists())
{
LOG_DBG("Random device [" << devicePath << "] already exits");
return true;
}
LOG_DBG("Making [" << devicePath << "] node in [" << root << "/dev]");
if (mknod((absPath).c_str(),
S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH, dev) == 0)
{
LOG_DBG("Created random device [" << absPath << ']');
return true;
}
const auto mknodErrno = errno;
if (isBindMountingEnabled())
{
static bool warned = false;
if (!warned)
{
warned = true;
LOG_WRN("Performance issue: nodev mount permission or mknod fails. Have to bind mount "
"random devices");
}
Poco::File(absPath).createFile();
if (coolmount("-b", devicePath, absPath))
{
LOG_DBG("Bind mounted [" << devicePath << "] -> [" << absPath << ']');
return true;
}
LOG_INF("Failed to bind mount [" << devicePath << "] -> [" << absPath << ']');
}
else
{
LOG_INF("Failed to create random device via mknod("
<< absPath << "). Mount must not use nodev flag, or bind-mount must be enabled: "
<< strerror(mknodErrno));
}
static bool warned = false;
if (!warned)
{
warned = true;
LOG_ERR("Failed to create random device ["
<< devicePath << "] at [" << absPath
<< "]. Please either allow creating devices or enable bind-mounting. Some "
"features, such us password-protection and document-signing, might not work");
}
return false;
}
// This is the second stage of setting up /dev/[u]random
// in the jails. Here we create the random devices in
// /tmp/dev/ in the jail chroot. See setupRandomDeviceLinks().
void setupJailDevNodes(const std::string& root)
{
if (!FileUtil::isWritable(root))
{
LOG_WRN("Path [" << root << "] is read-only. Will not create the random device nodes.");
return;
}
const auto pathDev = Poco::Path(root, "/dev");
try
{
// Create the path first.
Poco::File(pathDev).createDirectory();
}
catch (const std::exception& ex)
{
LOG_ERR("Failed to create [" << pathDev.toString() << "]: " << ex.what());
return;
}
#ifndef __FreeBSD__
// Create the random and urandom devices.
createRandomDeviceInJail(root, "/dev/random", makedev(1, 8));
createRandomDeviceInJail(root, "/dev/urandom", makedev(1, 9));
#else
if (!FileUtil::Stat(root + "/dev/random").exists())
{
const bool res = coolmount("-d", "", root + "/dev");
if (res)
LOG_TRC("Mounted devfs hierarchy -> [" << root << "/dev].");
else
LOG_ERR("Failed to mount devfs -> [" << root << "/dev].");
}
#endif
}
/// The envar name used to control bind-mounting of systemplate/jails.
constexpr const char* BIND_MOUNTING_ENVAR_NAME = "COOL_BIND_MOUNT";

View file

@ -52,9 +52,6 @@ void createJailPath(const std::string& path);
/// Setup the Child-Root directory.
void setupChildRoot(bool bindMount, const std::string& jailRoot, const std::string& sysTemplate);
/// Setup /dev/random and /dev/urandom in the given jail path.
void setupJailDevNodes(const std::string& root);
/// Enable bind-mounting in this process.
void enableBindMounting();

View file

@ -105,3 +105,10 @@
/* Define to 1 if this is the WASM app build. */
#undef WASMAPP
/* Define to 1 if we have sys/random.h */
#undef HAVE_SYS_RANDOM_H
/* Define to 1 if we have a getentropy function */
#undef HAVE_GETENTROPY

View file

@ -94,7 +94,7 @@ getent group cool >/dev/null || groupadd -r cool
getent passwd cool >/dev/null || useradd -g cool -r cool -d /opt/cool -s /bin/bash
%post
setcap cap_fowner,cap_chown,cap_mknod,cap_sys_chroot=ep /usr/bin/coolforkit
setcap cap_fowner,cap_chown,cap_sys_chroot=ep /usr/bin/coolforkit
setcap cap_sys_admin=ep /usr/bin/coolmount
if [ -f /etc/loolwsd/loolwsd.xml ]; then /usr/bin/coolconfig migrateconfig --write; fi
# compatibility with older systemd versions

View file

@ -4,7 +4,7 @@ set -e
case "$1" in
configure)
setcap cap_fowner,cap_chown,cap_mknod,cap_sys_chroot=ep /usr/bin/coolforkit || true
setcap cap_fowner,cap_chown,cap_sys_chroot=ep /usr/bin/coolforkit || true
setcap cap_sys_admin=ep /usr/bin/coolmount || true
if [ -f /etc/loolwsd/loolwsd.xml ]; then /usr/bin/coolconfig migrateconfig --write || true; fi

View file

@ -20,7 +20,7 @@ COPY /start-collabora-online.sh /
# set up Collabora Online (normally done by postinstall script of package)
# Fix permissions
RUN setcap cap_fowner,cap_chown,cap_mknod,cap_sys_chroot=ep /usr/bin/coolforkit && \
RUN setcap cap_fowner,cap_chown,cap_sys_chroot=ep /usr/bin/coolforkit && \
setcap cap_sys_admin=ep /usr/bin/coolmount && \
useradd --system --user-group --create-home --home-dir /opt/cool cool && \
rm -rf /opt/cool && \

View file

@ -24,7 +24,7 @@ COPY /start-collabora-online.sh /
# set up Collabora Online (normally done by postinstall script of package)
# Fix permissions
RUN setcap cap_fowner,cap_chown,cap_mknod,cap_sys_chroot=ep /usr/bin/coolforkit && \
RUN setcap cap_fowner,cap_chown,cap_sys_chroot=ep /usr/bin/coolforkit && \
setcap cap_sys_admin=ep /usr/bin/coolmount && \
adduser --quiet --system --group --home /opt/cool cool && \
rm -rf /opt/cool && \

View file

@ -26,7 +26,7 @@ COPY /start-collabora-online.sh /
# set up Collabora Online (normally done by postinstall script of package)
# Fix permissions
RUN setcap cap_fowner,cap_chown,cap_mknod,cap_sys_chroot=ep /usr/bin/coolforkit && \
RUN setcap cap_fowner,cap_chown,cap_sys_chroot=ep /usr/bin/coolforkit && \
setcap cap_sys_admin=ep /usr/bin/coolmount && \
adduser --quiet --system --group --home /opt/cool cool && \
rm -rf /opt/cool && \

View file

@ -20,7 +20,7 @@ COPY /start-collabora-online.sh /
# set up Collabora Online (normally done by postinstall script of package)
# Fix permissions
RUN setcap cap_fowner,cap_chown,cap_mknod,cap_sys_chroot=ep /usr/bin/coolforkit && \
RUN setcap cap_fowner,cap_chown,cap_sys_chroot=ep /usr/bin/coolforkit && \
setcap cap_sys_admin=ep /usr/bin/coolmount && \
groupadd -r cool && \
useradd -g cool -r cool -d /opt/cool -s /bin/bash && \

View file

@ -256,8 +256,6 @@ static bool haveCorrectCapabilities()
// Do check them all, don't shortcut with &&
if (!haveCapability(CAP_SYS_CHROOT))
result = false;
if (!haveCapability(CAP_MKNOD))
result = false;
if (!haveCapability(CAP_FOWNER))
result = false;
if (!haveCapability(CAP_CHOWN))

View file

@ -2709,9 +2709,13 @@ void copyCertificateDatabaseToTmp(Poco::Path const& jailPath)
}
}
}
#endif
}
void lokit_main(
#if !MOBILEAPP
const std::string& childRoot,
@ -2917,8 +2921,7 @@ void lokit_main(
}
}
// Setup the devices inside /tmp and set TMPDIR.
JailUtil::setupJailDevNodes(Poco::Path(jailPath, "/tmp").toString());
// Setup /tmp and set TMPDIR.
::setenv("TMPDIR", "/tmp", 1);
allowedPaths += ":w:/tmp";

View file

@ -3361,7 +3361,7 @@ bool COOLWSD::createForKit()
std::string parentPath = Path(Application::instance().commandPath()).parent().toString();
#if STRACE_COOLFORKIT
// if you want to use this, you need to sudo setcap cap_fowner,cap_chown,cap_mknod,cap_sys_chroot=ep /usr/bin/strace
// if you want to use this, you need to sudo setcap cap_fowner,cap_chown,cap_sys_chroot=ep /usr/bin/strace
args.push_back("-o");
args.push_back("strace.log");
args.push_back("-f");