[Libreoffice-commits] online.git: Branch 'distro/collabora/collabora-online-1-0' - loolwsd/LOOLForKit.cpp
Tor Lillqvist
tml at collabora.com
Wed Oct 12 12:21:20 UTC 2016
loolwsd/LOOLForKit.cpp | 72 +++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 72 insertions(+)
New commits:
commit 36895fa2ca9ab8addb2307c6eb30dbebed496143
Author: Tor Lillqvist <tml at collabora.com>
Date: Wed Oct 12 14:19:42 2016 +0300
Verify at run-time that the loolforkit program has the required capabilities
If not, log a mesage and exit.
Check the capabilities only after opening the fifo. loolwsd is waiting
in open() for loolforkit to open its end of the pipe, so if loolforkit
exits before it has opened the pipe, loolwsd will wait forever and not
notice that loolforkit has exited. Which is not ideal.
Note that there are other sanity checks done before loolforkit opens
the pipe, and if some of them fail, and loolforkit exits, loolwsd will
be hanging in the open and not notice. Need to carefully look through
that and re-factor as necessary.
Using a named pipe (FIFO) is probably pointless. We should just create
a normal pipe in loolwsd and pass the fd of the reading end on the
command-line to loolforkit.
diff --git a/loolwsd/LOOLForKit.cpp b/loolwsd/LOOLForKit.cpp
index 1c4144e..eaa3c9a 100644
--- a/loolwsd/LOOLForKit.cpp
+++ b/loolwsd/LOOLForKit.cpp
@@ -113,6 +113,75 @@ private:
}
};
+static bool haveCapability(cap_value_t capability)
+{
+ cap_t caps = cap_get_proc();
+
+ if (caps == nullptr)
+ {
+ Log::syserror("cap_get_proc() failed.");
+ return false;
+ }
+
+ char *cap_name = cap_to_name(capability);
+ cap_flag_value_t value;
+
+ if (cap_get_flag(caps, capability, CAP_EFFECTIVE, &value) == -1)
+ {
+ if (cap_name)
+ {
+ Log::syserror("cap_get_flag failed for " + std::string(cap_name) + ".");
+ cap_free(cap_name);
+ }
+ else
+ {
+ Log::syserror("cap_get_flag failed for capability " + std::to_string(capability) + ".");
+ }
+ return false;
+ }
+
+ if (value != CAP_SET)
+ {
+ if (cap_name)
+ {
+ Log::error("Capability " + std::string(cap_name) + " is not set for the loolforkit program.");
+ cap_free(cap_name);
+ }
+ else
+ {
+ Log::error("Capability " + std::to_string(capability) + " is not set for the loolforkit program.");
+ }
+ return false;
+ }
+
+ if (cap_name)
+ {
+ Log::info("Have capability " + std::string(cap_name));
+ cap_free(cap_name);
+ }
+ else
+ {
+ Log::info("Have capability " + std::to_string(capability));
+ }
+
+ return true;
+}
+
+static bool haveCorrectCapabilities()
+{
+ bool result = true;
+
+ // 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;
+
+ return result;
+}
+
/// Check if some previously forked kids have died.
static void cleanupChildren()
{
@@ -304,6 +373,9 @@ int main(int argc, char** argv)
}
Log::debug("open(" + pipeLoolwsd + ", RDONLY) = " + std::to_string(pipeFd));
+ if (!haveCorrectCapabilities())
+ return Application::EXIT_SOFTWARE;
+
// Initialize LoKit
if (!globalPreinit(loTemplate))
std::_Exit(Application::EXIT_SOFTWARE);
More information about the Libreoffice-commits
mailing list