[Libreoffice-commits] online.git: loolwsd/configure.ac loolwsd/LOOLForKit.cpp loolwsd/loolmount.c loolwsd/LOOLWSD.cpp loolwsd/security.h loolwsd/test loolwsd/Util.hpp

Michael Meeks michael.meeks at collabora.com
Tue Apr 12 16:14:17 UTC 2016


 loolwsd/LOOLForKit.cpp      |   10 ++++++++++
 loolwsd/LOOLWSD.cpp         |    4 ++--
 loolwsd/Util.hpp            |    3 +++
 loolwsd/configure.ac        |   13 ++++++++-----
 loolwsd/loolmount.c         |    7 ++++++-
 loolwsd/security.h          |   40 ++++++++++++++++++++++++++++++++++++++++
 loolwsd/test/run_test.sh.in |    8 ++++++++
 loolwsd/test/run_unit.sh.in |   17 ++++++++++++++---
 8 files changed, 91 insertions(+), 11 deletions(-)

New commits:
commit 6a990dfb61f85d777aa9bad8766cf8771ed8a6fe
Author: Michael Meeks <michael.meeks at collabora.com>
Date:   Tue Apr 12 10:00:33 2016 +0100

    Security bits and test cleanup.
    
    Enforce user being 'lool' for setcap binaries loolmount and loolforkit.
    
    Add warnings if configured without --enable-debug.
    
    Developers should pass --enable-debug to configure.

diff --git a/loolwsd/LOOLForKit.cpp b/loolwsd/LOOLForKit.cpp
index 23f43da..4ad66b3 100644
--- a/loolwsd/LOOLForKit.cpp
+++ b/loolwsd/LOOLForKit.cpp
@@ -11,6 +11,8 @@
  * spawn lots of kits as children.
  */
 
+#include "config.h"
+
 #include <sys/capability.h>
 #include <sys/wait.h>
 #include <sys/types.h>
@@ -34,6 +36,8 @@
 #include "Unit.hpp"
 #include "ChildProcessSession.hpp"
 
+#include "security.h"
+
 using Poco::Path;
 using Poco::Process;
 using Poco::StringTokenizer;
@@ -137,6 +141,9 @@ static void printArgumentHelp()
 
 int main(int argc, char** argv)
 {
+    if (!hasCorrectUID("loolforkit"))
+        return 1;
+
     if (std::getenv("SLEEPFORDEBUGGER"))
     {
         std::cerr << "Sleeping " << std::getenv("SLEEPFORDEBUGGER")
@@ -192,11 +199,14 @@ int main(int argc, char** argv)
             eq = std::strchr(cmd, '=');
             ClientPortNumber = std::stoll(std::string(eq+1));
         }
+#if ENABLE_DEBUG
+        // this process has various privileges - don't run arbitrary code.
         else if (std::strstr(cmd, "--unitlib=") == cmd)
         {
             eq = std::strchr(cmd, '=');
             UnitTestLibrary = std::string(eq+1);
         }
+#endif
     }
 
     if (loSubPath.empty() || sysTemplate.empty() ||
diff --git a/loolwsd/LOOLWSD.cpp b/loolwsd/LOOLWSD.cpp
index 8e30bdf..c48baad 100644
--- a/loolwsd/LOOLWSD.cpp
+++ b/loolwsd/LOOLWSD.cpp
@@ -1154,12 +1154,12 @@ void LOOLWSD::defineOptions(OptionSet& optionSet)
                         .required(false)
                         .repeatable(false));
 
+#if ENABLE_DEBUG
     optionSet.addOption(Option("unitlib", "", "Unit testing library path.")
                         .required(false)
                         .repeatable(false)
                         .argument("unitlib"));
 
-#if ENABLE_DEBUG
     optionSet.addOption(Option("careerspan", "", "How many seconds to run.")
                         .required(false)
                         .repeatable(false)
@@ -1202,9 +1202,9 @@ void LOOLWSD::handleOption(const std::string& optionName,
         AdminCreds = value;
     else if (optionName == "allowlocalstorage")
         AllowLocalStorage = true;
+#if ENABLE_DEBUG
     else if (optionName == "unitlib")
         UnitTestLibrary = value;
-#if ENABLE_DEBUG
     else if (optionName == "careerspan")
         careerSpanSeconds = std::stoi(value);
 #endif
diff --git a/loolwsd/Util.hpp b/loolwsd/Util.hpp
index 09c63bd..b47c4ca 100644
--- a/loolwsd/Util.hpp
+++ b/loolwsd/Util.hpp
@@ -133,6 +133,9 @@ namespace Util
     std::string formatLinesForLog(const std::string& s);
 
     void setThreadName(const std::string& s);
+
+    /// Ensure that we have the correct UID unless in debug mode.
+    bool hasCorrectUID();
 };
 
 //TODO: Move to own file.
diff --git a/loolwsd/configure.ac b/loolwsd/configure.ac
index 435d19a..ce4f255 100644
--- a/loolwsd/configure.ac
+++ b/loolwsd/configure.ac
@@ -79,13 +79,16 @@ AS_IF([test "$enable_debug" = yes -a -n "$with_poco_libs"],
       [POCO_DEBUG_SUFFIX=d],
       [POCO_DEBUG_SUFFIX=])
 
-AS_IF([test "$enable_debug" = yes],
-      [AC_DEFINE([ENABLE_DEBUG],1,[Whether to compile in some extra debugging support code and disable some security pieces ])])
-
+ENABLE_DEBUG=
 debug_msg="secure mode: product build"
-if test "$enable_debug" = yes; then
-   debug_msg="low security debugging mode"
+if test "$enable_debug" = "yes"; then
+   AC_DEFINE([ENABLE_DEBUG],1,[Whether to compile in some extra debugging support code and disable some security pieces ])
+   ENABLE_DEBUG=true
+   if test "$enable_debug" = yes; then
+      debug_msg="low security debugging mode"
+   fi
 fi
+AC_SUBST(ENABLE_DEBUG)
 
 # Test for build environment
 
diff --git a/loolwsd/loolmount.c b/loolwsd/loolmount.c
index ceadeec..b8d87d3 100644
--- a/loolwsd/loolmount.c
+++ b/loolwsd/loolmount.c
@@ -7,13 +7,18 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 /*
- * This is a trivial helper to allow bind mounting.
+ * This is a very tiny helper to allow overlay mounting.
  */
 
 #include <sys/mount.h>
 
+#include "security.h"
+
 int main(int argc, char **argv)
 {
+    if (!hasCorrectUID("loolmount"))
+        return 1;
+
     if (argc < 3)
         return 1;
 
diff --git a/loolwsd/security.h b/loolwsd/security.h
new file mode 100644
index 0000000..cd4dd0f
--- /dev/null
+++ b/loolwsd/security.h
@@ -0,0 +1,40 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+/*
+ * Place for simple security-related code.
+ */
+
+#include <sys/mount.h>
+#include <sys/types.h>
+
+#include <pwd.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdio.h>
+
+#define LOOL_USER_ID "lool"
+
+static int hasCorrectUID(const char *appName)
+{
+#if ENABLE_DEBUG
+    (void)appName;
+    return 1; // insecure but easy to use.
+#else
+    struct passwd *pw = getpwuid(getuid());
+    if (pw && pw->pw_name && !strcmp(pw->pw_name, LOOL_USER_ID))
+        return 1;
+    else {
+        fprintf(stderr, "Error: %s incorrect user-name: %s - aborting\n",
+		appName, pw && pw->pw_name ? pw->pw_name : "<null>");
+	return 0;
+    }
+#endif
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/loolwsd/test/run_test.sh.in b/loolwsd/test/run_test.sh.in
index 864fd0e..b5678f9 100755
--- a/loolwsd/test/run_test.sh.in
+++ b/loolwsd/test/run_test.sh.in
@@ -10,6 +10,14 @@ test_log_output="$test_build/test_output"
 
 mkdir -p $test_log_output
 
+if test "z at ENABLE_DEBUG@" != "ztrue"; then
+    echo ""
+    echo "It is necessary to configure with --enable-debug for unit tests to pass"
+    echo ""
+    echo ":test-result: FAIL $tst" > $test_output
+    exit 1;
+fi
+
 # result logging
 echo > $test_output
 
diff --git a/loolwsd/test/run_unit.sh.in b/loolwsd/test/run_unit.sh.in
index b9bc830..63b3bdc 100755
--- a/loolwsd/test/run_unit.sh.in
+++ b/loolwsd/test/run_unit.sh.in
@@ -6,8 +6,19 @@
 export LOOL_LOGLEVEL=trace
 
 abs_top_builddir="@abs_top_builddir@"
+test_build="${abs_top_builddir}/test"
+test_output="$test_build/run_unit.sh.trs"
+test_log_output="$test_build/test_output"
 
-mkdir -p test_output
+mkdir -p $test_log_output
+
+if test "z at ENABLE_DEBUG@" != "ztrue"; then
+    echo ""
+    echo "It is necessary to configure with --enable-debug for unit tests to pass"
+    echo ""
+    echo ":test-result: FAIL $tst" > $test_output
+    exit 1;
+fi
 
 # result logging
 echo > run_unit.sh.trs
@@ -18,7 +29,7 @@ for tst in timeout storage prefork; do
     if ../loolwsd --systemplate="@SYSTEMPLATE_PATH@" --lotemplate="@LO_PATH@" \
 	          --childroot="@JAILS_PATH@" --unitlib=".libs/unit-$tst.so" 2> "$tst_log"; then
 	echo "Test $tst passed."
-	echo ":test-result: PASS $tst" >> run_unit.sh.trs
+	echo ":test-result: PASS $tst" >> $test_output
     else
 	cat "$tst_log"
         echo "============================================================="
@@ -26,7 +37,7 @@ for tst in timeout storage prefork; do
 	echo "   $ gdb --args ../loolwsd --systemplate=\"@SYSTEMPLATE_PATH@\" --lotemplate=\"@LO_PATH@\" \\"
 	echo "         --childroot=\"@JAILS_PATH@\" --unitlib=\".libs/unit-$tst.so\""
         echo "============================================================="
-	echo ":test-result: FAIL $tst" >> run_unit.sh.trs
+	echo ":test-result: FAIL $tst" >> $test_output
     fi
 done
 


More information about the Libreoffice-commits mailing list