[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