]> git.ipfire.org Git - thirdparty/dbus.git/commitdiff
Add apparmor element support to bus config parsing
authorTyler Hicks <tyhicks@canonical.com>
Tue, 11 Feb 2014 01:02:04 +0000 (19:02 -0600)
committerSimon McVittie <simon.mcvittie@collabora.co.uk>
Wed, 18 Feb 2015 17:04:00 +0000 (17:04 +0000)
The <apparmor> element can contain a single mode attribute that has one
of three values:

 "enabled"
 "disabled"
 "required"

"enabled" means that kernel support is autodetected and, if available,
AppArmor mediation occurs in dbus-daemon. If kernel support is not
detected, mediation is disabled. "disabled" means that mediation does
not occur. "required" means that kernel support must be detected for
dbus-daemon to start.

Bug: https://bugs.freedesktop.org/show_bug.cgi?id=75113
Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Reviewed-by: Simon McVittie <simon.mcvittie@collabora.co.uk>
bus/Makefile.am
bus/apparmor.c [new file with mode: 0644]
bus/apparmor.h [new file with mode: 0644]
bus/config-parser-common.c
bus/config-parser-common.h
bus/config-parser.c
bus/session.conf.in
bus/system.conf.in
cmake/bus/CMakeLists.txt

index e0eead3c38bbb680235013762ca33bb4b041145a..9d3cb006c946062a25e6385e94abe0712653df8e 100644 (file)
@@ -4,6 +4,7 @@ dbus_daemon_execdir = $(DBUS_DAEMONDIR)
 DBUS_BUS_LIBS = \
        $(XML_LIBS) \
        $(SELINUX_LIBS) \
+       $(APPARMOR_LIBS) \
        $(THREAD_LIBS) \
        $(ADT_LIBS) \
        $(NETWORK_libs) \
@@ -70,6 +71,8 @@ BUS_SOURCES=                                  \
        activation.c                            \
        activation.h                            \
        activation-exit-codes.h                 \
+       apparmor.c                              \
+       apparmor.h                              \
        bus.c                                   \
        bus.h                                   \
        config-parser.c                         \
diff --git a/bus/apparmor.c b/bus/apparmor.c
new file mode 100644 (file)
index 0000000..b53d051
--- /dev/null
@@ -0,0 +1,79 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ * apparmor.c  AppArmor security checks for D-Bus
+ *
+ * Based on selinux.c
+ *
+ * Copyright © 2014-2015 Canonical, Ltd.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
+ *
+ */
+
+#include <config.h>
+#include "apparmor.h"
+
+#ifdef HAVE_APPARMOR
+
+#include <dbus/dbus-internals.h>
+#include <string.h>
+
+typedef enum {
+  APPARMOR_DISABLED,
+  APPARMOR_ENABLED,
+  APPARMOR_REQUIRED
+} AppArmorConfigMode;
+
+/* Store the value of the AppArmor mediation mode in the bus configuration */
+static AppArmorConfigMode apparmor_config_mode = APPARMOR_ENABLED;
+
+#endif /* HAVE_APPARMOR */
+
+dbus_bool_t
+bus_apparmor_set_mode_from_config (const char *mode, DBusError *error)
+{
+#ifdef HAVE_APPARMOR
+  if (mode != NULL)
+  {
+    if (strcmp (mode, "disabled") == 0)
+      apparmor_config_mode = APPARMOR_DISABLED;
+    else if (strcmp (mode, "enabled") == 0)
+      apparmor_config_mode = APPARMOR_ENABLED;
+    else if (strcmp (mode, "required") == 0)
+      apparmor_config_mode = APPARMOR_REQUIRED;
+    else
+      {
+        dbus_set_error (error, DBUS_ERROR_FAILED,
+                        "Mode attribute on <apparmor> must have value "
+                        "\"required\", \"enabled\" or \"disabled\", "
+                        "not \"%s\"", mode);
+        return FALSE;
+      }
+  }
+
+  return TRUE;
+#else
+  if (mode == NULL || strcmp (mode, "disabled") == 0 ||
+                      strcmp (mode, "enabled") == 0)
+    return TRUE;
+
+  dbus_set_error (error, DBUS_ERROR_FAILED,
+                  "Mode attribute on <apparmor> must have value \"enabled\" or "
+                  "\"disabled\" but cannot be \"%s\" when D-Bus is built "
+                  "without AppArmor support", mode);
+  return FALSE;
+#endif
+}
diff --git a/bus/apparmor.h b/bus/apparmor.h
new file mode 100644 (file)
index 0000000..0d6f274
--- /dev/null
@@ -0,0 +1,34 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ * apparmor.c  AppArmor security checks for D-Bus
+ *
+ * Authors: John Johansen <john.johansen@canonical.com>
+ *          Tyler Hicks <tyhicks@canonical.com>
+ * Based on: selinux.h by Matthew Rickard
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
+ *
+ */
+
+#ifndef BUS_APPARMOR_H
+#define BUS_APPARMOR_H
+
+#include <dbus/dbus.h>
+
+dbus_bool_t bus_apparmor_set_mode_from_config (const char *mode,
+                                               DBusError *error);
+
+#endif /* BUS_APPARMOR_H */
index c522ff49f75402db6dbb91fe4ddb64c45b3308d9..5db6b2891f8cf3714dac2d2577c8615bffff1609 100644 (file)
@@ -127,6 +127,10 @@ bus_config_parser_element_name_to_type (const char *name)
     {
       return ELEMENT_ALLOW_ANONYMOUS;
     }
+  else if (strcmp (name, "apparmor") == 0)
+    {
+      return ELEMENT_APPARMOR;
+    }
   return ELEMENT_NONE;
 }
 
@@ -181,6 +185,8 @@ bus_config_parser_element_type_to_name (ElementType type)
       return "keep_umask";
     case ELEMENT_ALLOW_ANONYMOUS:
       return "allow_anonymous";
+    case ELEMENT_APPARMOR:
+      return "apparmor";
     }
 
   _dbus_assert_not_reached ("bad element type");
index 186bf4cf7428ad97aa1b9158523a160587cb48cb..382a0141fe48716b9f5ca6fed4b2722a8b1bec57 100644 (file)
@@ -49,7 +49,8 @@ typedef enum
   ELEMENT_STANDARD_SYSTEM_SERVICEDIRS,
   ELEMENT_KEEP_UMASK,
   ELEMENT_SYSLOG,
-  ELEMENT_ALLOW_ANONYMOUS
+  ELEMENT_ALLOW_ANONYMOUS,
+  ELEMENT_APPARMOR
 } ElementType;
 
 ElementType bus_config_parser_element_name_to_type (const char *element_name);
index ee2d4e7d28fb6d01bef9f6c12c1ad2443211821a..58048a50994a86086a536b1863153b82c5b22025 100644 (file)
@@ -28,6 +28,7 @@
 #include "utils.h"
 #include "policy.h"
 #include "selinux.h"
+#include "apparmor.h"
 #include <dbus/dbus-list.h>
 #include <dbus/dbus-internals.h>
 #include <dbus/dbus-misc.h>
@@ -1136,6 +1137,27 @@ start_busconfig_child (BusConfigParser   *parser,
 
       return TRUE;
     }
+  else if (element_type == ELEMENT_APPARMOR)
+    {
+      Element *e;
+      const char *mode;
+
+      if ((e = push_element (parser, ELEMENT_APPARMOR)) == NULL)
+        {
+          BUS_SET_OOM (error);
+          return FALSE;
+        }
+
+      if (!locate_attributes (parser, "apparmor",
+                              attribute_names,
+                              attribute_values,
+                              error,
+                              "mode", &mode,
+                              NULL))
+        return FALSE;
+
+      return bus_apparmor_set_mode_from_config (mode, error);
+    }
   else
     {
       dbus_set_error (error, DBUS_ERROR_FAILED,
@@ -2074,6 +2096,7 @@ bus_config_parser_end_element (BusConfigParser   *parser,
     case ELEMENT_STANDARD_SESSION_SERVICEDIRS:
     case ELEMENT_STANDARD_SYSTEM_SERVICEDIRS:
     case ELEMENT_ALLOW_ANONYMOUS:
+    case ELEMENT_APPARMOR:
       break;
     }
 
@@ -2373,6 +2396,7 @@ bus_config_parser_content (BusConfigParser   *parser,
     case ELEMENT_ALLOW_ANONYMOUS:
     case ELEMENT_SELINUX:
     case ELEMENT_ASSOCIATE:
+    case ELEMENT_APPARMOR:
       if (all_whitespace (content))
         return TRUE;
       else
index cfe9544fbe5913127df116d260870bfaf629a3d9..d2e3f2d05d1aad6cb55f229fa7a8effeeef1fd03 100644 (file)
@@ -25,6 +25,9 @@
     <allow own="*"/>
   </policy>
 
+  <!-- Enable AppArmor mediation when it is available -->
+  <apparmor mode="enabled"/>
+
   <!-- Config files are placed here that among other things, 
        further restrict the above policy for specific services. -->
   <includedir>session.d</includedir>
index ac78c734f53837ddec8ea336e597b795d0e03e1f..fc472bd76b82bc802479ba82ca8fb56ac61c7e5e 100644 (file)
@@ -97,6 +97,9 @@
            send_interface="org.freedesktop.DBus.Debug.Stats"/>
   </policy>
 
+  <!-- Enable AppArmor mediation when it is available -->
+  <apparmor mode="enabled"/>
+
   <!-- Config files are placed here that among other things, punch 
        holes in the above policy for specific services. -->
   <includedir>system.d</includedir>
index a3528c7f36b988d19ee3329d751cc507f98b27c5..40f66909d3726384f1bad1afdc0a9d6615e76ca3 100644 (file)
@@ -37,6 +37,8 @@ endif (DBUS_BUS_ENABLE_INOTIFY)
 set (BUS_SOURCES 
        ${BUS_DIR}/activation.c                         
        ${BUS_DIR}/activation.h                         
+       ${BUS_DIR}/apparmor.c
+       ${BUS_DIR}/apparmor.h
        ${BUS_DIR}/bus.c                                        
        ${BUS_DIR}/bus.h                                        
        ${BUS_DIR}/config-parser.c