[systemd-devel] [PATCH v2] SMACK: Add configuration options.

Auke Kok auke-jan.h.kok at intel.com
Thu Oct 25 18:14:24 PDT 2012


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:

SMACK64 - applicable to FIFO's.
SMACK64IPIN/SMACK64IPOUT - 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.

Signed-off-by: Auke Kok <auke-jan.h.kok at intel.com>

---
 man/systemd.socket.xml                | 29 +++++++++++++++++++++++++++++
 src/core/load-fragment-gperf.gperf.m4 |  3 +++
 src/core/socket.c                     | 28 ++++++++++++++++++++++++++++
 src/core/socket.h                     |  4 ++++
 4 files changed, 64 insertions(+)

diff --git a/man/systemd.socket.xml b/man/systemd.socket.xml
index 9db39b1..73fa962 100644
--- a/man/systemd.socket.xml
+++ b/man/systemd.socket.xml
@@ -485,6 +485,35 @@
                         </varlistentry>
 
                         <varlistentry>
+                                <term><varname>SMACK64=</varname></term>
+                                <listitem><para>Takes a string
+                                value. Controls the security.SMACK64 xattr,
+                                or smack label of the FIFO. See
+                                <citerefentry><refentrytitle>Documentation/Smack.txt</refentrytitle></citerefentry>
+                                in the Linux kernel source code for details.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>SMACK64IPIN=</varname></term>
+                                <listitem><para>Takes a string
+                                value. Controls the security.SMACK64IPIN xattr,
+                                or smack label for incoming connections to the
+                                socket. See
+                                <citerefentry><refentrytitle>Documentation/Smack.txt</refentrytitle></citerefentry>
+                                in the Linux kernel source code for details.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>SMACK64IPOUT=</varname></term>
+                                <listitem><para>Takes a string
+                                value. Controls the security.SMACK64IPOUT xattr,
+                                or smack label for outgoing connections from the
+                                socket. See
+                                <citerefentry><refentrytitle>Documentation/Smack.txt</refentrytitle></citerefentry>
+                                in the Linux kernel source code for details.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
                                 <term><varname>PipeSize=</varname></term>
                                 <listitem><para>Takes an integer
                                 value. Controls the pipe buffer size
diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4
index 8187cd4..cfe9545 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.SMACK64,                  config_parse_string,                0,                             offsetof(Socket, smack64)
+Socket.SMACK64IPIN,              config_parse_string,                0,                             offsetof(Socket, smack64ipin)
+Socket.SMACK64IPOUT,             config_parse_string,                0,                             offsetof(Socket, smack64ipout)
 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 71cdf2d..24998ee 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"
@@ -508,6 +509,21 @@ static void socket_dump(Unit *u, FILE *f, const char *prefix) {
                         "%sMessageQueueMessageSize: %li\n",
                         prefix, s->mq_msgsize);
 
+        if (s->smack64)
+                fprintf(f,
+                        "%sSMACK64: %s\n",
+                        prefix, s->smack64);
+
+        if (s->smack64ipin)
+                fprintf(f,
+                        "%sSMACK64IPIN: %s\n",
+                        prefix, s->smack64ipin);
+
+        if (s->smack64ipout)
+                fprintf(f,
+                        "%sSMACK64IPOUT: %s\n",
+                        prefix, s->smack64ipout);
+
         LIST_FOREACH(port, p, s->ports) {
 
                 if (p->type == SOCKET_SOCKET) {
@@ -747,6 +763,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->smack64ipin)
+                if (fsetxattr(fd, "security.SMACK64IPIN", s->smack64ipin, strlen(s->smack64ipin), 0) < 0)
+                        log_error("fsetxattr(\"security.SMACK64IPIN\"): %m");
+
+        if (s->smack64ipout)
+                if (fsetxattr(fd, "security.SMACK64IPOUT", s->smack64ipout, strlen(s->smack64ipout), 0) < 0)
+                        log_error("fsetxattr(\"security.SMACK64IPOUT\"): %m");
 }
 
 static void socket_apply_fifo_options(Socket *s, int fd) {
@@ -756,6 +780,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->smack64)
+                if (fsetxattr(fd, "security.SMACK64", s->smack64, strlen(s->smack64), 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 a06b3ea..95af608 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 *smack64;
+        char *smack64ipin;
+        char *smack64ipout;
 };
 
 /* Called from the service code when collecting fds */
-- 
1.7.12.3



More information about the systemd-devel mailing list