summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorAuke Kok <auke-jan.h.kok@intel.com>2012-10-29 15:30:05 -0700
committerLennart Poettering <lennart@poettering.net>2012-10-30 03:40:42 +0100
commit0eb59ccfe619cbc4b42ef8ff02b52971994dfe05 (patch)
tree67cd3e7e7638b8d5e34fee03fce91d070f56a2ef /src/core
parent978cf3c75fbd94fd0e046206ada6169b35edd919 (diff)
SMACK: Add configuration options. (v3)
This adds SMACK label configuration options to socket units. SMACK labels should be applied to most objects on disk well before execution time, but two items remain that are generated dynamically at run time that require SMACK labels to be set in order to enforce MAC on all objects. Files on disk can be labelled using package management. For device nodes, simple udev rules are sufficient to add SMACK labels at boot/insertion time. Sockets can be created at run time and systemd does just that for several services. In order to protect FIFO's and UNIX domain sockets, we must instruct systemd to apply SMACK labels at runtime. This patch adds the following options: Smack - applicable to FIFO's. SmackIpIn/SmackIpOut - applicable to sockets. No external dependencies are required to support SMACK, as setting the labels is done using fsetxattr(). The labels can be set on a kernel that does not have SMACK enabled either, so there is no need to #ifdef any of this code out. For more information about SMACK, please see Documentation/Smack.txt in the kernel source code. v3 of this patch changes the config options to be CamelCased.
Diffstat (limited to 'src/core')
-rw-r--r--src/core/dbus-socket.c6
-rw-r--r--src/core/load-fragment-gperf.gperf.m43
-rw-r--r--src/core/socket.c32
-rw-r--r--src/core/socket.h4
4 files changed, 45 insertions, 0 deletions
diff --git a/src/core/dbus-socket.c b/src/core/dbus-socket.c
index c57cce19fb..095a031612 100644
--- a/src/core/dbus-socket.c
+++ b/src/core/dbus-socket.c
@@ -63,6 +63,9 @@
" <property name=\"MessageQueueMaxMessages\" type=\"x\" access=\"read\"/>\n" \
" <property name=\"MessageQueueMessageSize\" type=\"x\" access=\"read\"/>\n" \
" <property name=\"Result\" type=\"s\" access=\"read\"/>\n" \
+ " <property name=\"SmackLabel\" type=\"s\" access=\"read\"/>\n" \
+ " <property name=\"SmackLabelIPIn\" type=\"s\" access=\"read\"/>\n" \
+ " <property name=\"SmackLabelIPOut\" type=\"s\" access=\"read\"/>\n" \
" </interface>\n" \
#define INTROSPECTION \
@@ -126,6 +129,9 @@ static const BusProperty bus_socket_properties[] = {
{ "MessageQueueMaxMessages", bus_property_append_long, "x", offsetof(Socket, mq_maxmsg) },
{ "MessageQueueMessageSize", bus_property_append_long, "x", offsetof(Socket, mq_msgsize) },
{ "Result", bus_socket_append_socket_result, "s", offsetof(Socket, result) },
+ { "SmackLabel", bus_property_append_string, "s", offsetof(Socket, smack), true },
+ { "SmackLabelIPIn", bus_property_append_string, "s", offsetof(Socket, smack_ip_in), true },
+ { "SmackLabelIPOut",bus_property_append_string, "s", offsetof(Socket, smack_ip_out), true },
{ NULL, }
};
diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4
index 8187cd48c6..0c5ccebd73 100644
--- a/src/core/load-fragment-gperf.gperf.m4
+++ b/src/core/load-fragment-gperf.gperf.m4
@@ -208,6 +208,9 @@ Socket.TCPCongestion, config_parse_string, 0,
Socket.MessageQueueMaxMessages, config_parse_long, 0, offsetof(Socket, mq_maxmsg)
Socket.MessageQueueMessageSize, config_parse_long, 0, offsetof(Socket, mq_msgsize)
Socket.Service, config_parse_socket_service, 0, 0
+Socket.SmackLabel, config_parse_string, 0, offsetof(Socket, smack)
+Socket.SmackLabelIPIn, config_parse_string, 0, offsetof(Socket, smack_ip_in)
+Socket.SmackLabelIPOut, config_parse_string, 0, offsetof(Socket, smack_ip_out)
EXEC_CONTEXT_CONFIG_ITEMS(Socket)m4_dnl
KILL_CONTEXT_CONFIG_ITEMS(Socket)m4_dnl
m4_dnl
diff --git a/src/core/socket.c b/src/core/socket.c
index 71cdf2dfc8..c0959815c1 100644
--- a/src/core/socket.c
+++ b/src/core/socket.c
@@ -28,6 +28,7 @@
#include <signal.h>
#include <arpa/inet.h>
#include <mqueue.h>
+#include <attr/xattr.h>
#include "unit.h"
#include "socket.h"
@@ -131,6 +132,10 @@ static void socket_done(Unit *u) {
free(s->bind_to_device);
s->bind_to_device = NULL;
+ free(s->smack);
+ free(s->smack_ip_in);
+ free(s->smack_ip_out);
+
unit_unwatch_timer(u, &s->timer_watch);
}
@@ -508,6 +513,21 @@ static void socket_dump(Unit *u, FILE *f, const char *prefix) {
"%sMessageQueueMessageSize: %li\n",
prefix, s->mq_msgsize);
+ if (s->smack)
+ fprintf(f,
+ "%sSmackLabel: %s\n",
+ prefix, s->smack);
+
+ if (s->smack_ip_in)
+ fprintf(f,
+ "%sSmackLabelIPIn: %s\n",
+ prefix, s->smack_ip_in);
+
+ if (s->smack_ip_out)
+ fprintf(f,
+ "%sSmackLabelIPOut: %s\n",
+ prefix, s->smack_ip_out);
+
LIST_FOREACH(port, p, s->ports) {
if (p->type == SOCKET_SOCKET) {
@@ -747,6 +767,14 @@ static void socket_apply_socket_options(Socket *s, int fd) {
if (s->tcp_congestion)
if (setsockopt(fd, SOL_TCP, TCP_CONGESTION, s->tcp_congestion, strlen(s->tcp_congestion)+1) < 0)
log_warning("TCP_CONGESTION failed: %m");
+
+ if (s->smack_ip_in)
+ if (fsetxattr(fd, "security.SMACK64IPIN", s->smack_ip_in, strlen(s->smack_ip_in), 0) < 0)
+ log_error("fsetxattr(\"security.SMACK64IPIN\"): %m");
+
+ if (s->smack_ip_out)
+ if (fsetxattr(fd, "security.SMACK64IPOUT", s->smack_ip_out, strlen(s->smack_ip_out), 0) < 0)
+ log_error("fsetxattr(\"security.SMACK64IPOUT\"): %m");
}
static void socket_apply_fifo_options(Socket *s, int fd) {
@@ -756,6 +784,10 @@ static void socket_apply_fifo_options(Socket *s, int fd) {
if (s->pipe_size > 0)
if (fcntl(fd, F_SETPIPE_SZ, s->pipe_size) < 0)
log_warning("F_SETPIPE_SZ: %m");
+
+ if (s->smack)
+ if (fsetxattr(fd, "security.SMACK64", s->smack, strlen(s->smack), 0) < 0)
+ log_error("fsetxattr(\"security.SMACK64\"): %m");
}
static int fifo_address_create(
diff --git a/src/core/socket.h b/src/core/socket.h
index a06b3eae94..f099520dce 100644
--- a/src/core/socket.h
+++ b/src/core/socket.h
@@ -144,6 +144,10 @@ struct Socket {
/* Only for INET6 sockets: issue IPV6_V6ONLY sockopt */
SocketAddressBindIPv6Only bind_ipv6_only;
+
+ char *smack;
+ char *smack_ip_in;
+ char *smack_ip_out;
};
/* Called from the service code when collecting fds */