Add apparmor element support to bus config parsing

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>
This commit is contained in:
Tyler Hicks 2014-02-10 19:02:04 -06:00 committed by Simon McVittie
parent f62bff5bca
commit 06033cb20f
9 changed files with 156 additions and 1 deletions

View 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 \

79
bus/apparmor.c Normal file
View file

@ -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
}

34
bus/apparmor.h Normal file
View file

@ -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 */

View 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");

View 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);

View 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

View 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>

View 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>

View 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