[systemd-commits] 6 commits - TODO man/sd_bus_creds_get_pid.xml man/systemd-nspawn.xml man/systemd.exec.xml man/systemd.journal-fields.xml man/tmpfiles.d.xml src/core src/nspawn src/shared

Lennart Poettering lennart at kemper.freedesktop.org
Mon Feb 10 04:18:39 PST 2014


 TODO                                  |    6 --
 man/sd_bus_creds_get_pid.xml          |    2 
 man/systemd-nspawn.xml                |   45 +++++++++++++-----
 man/systemd.exec.xml                  |   17 ++++++
 man/systemd.journal-fields.xml        |    4 -
 man/tmpfiles.d.xml                    |    6 +-
 src/core/dbus-execute.c               |    1 
 src/core/execute.c                    |   32 ++++++++++++
 src/core/execute.h                    |    2 
 src/core/load-fragment-gperf.gperf.m4 |    3 -
 src/nspawn/nspawn.c                   |   84 +++++++++++++++++++---------------
 src/shared/exit-status.c              |    3 +
 src/shared/exit-status.h              |    3 -
 13 files changed, 147 insertions(+), 61 deletions(-)

New commits:
commit 8a96d94e4c33173d1426b7e0a6325405804ba224
Author: Lennart Poettering <lennart at poettering.net>
Date:   Mon Feb 10 13:15:42 2014 +0100

    nspawn: add new --share-system switch to run a container without PID/UTS/IPC namespacing

diff --git a/man/systemd-nspawn.xml b/man/systemd-nspawn.xml
index 96ccc5c..ca99da4 100644
--- a/man/systemd-nspawn.xml
+++ b/man/systemd-nspawn.xml
@@ -428,6 +428,27 @@
                                 itself.</para></listitem>
                         </varlistentry>
 
+                        <varlistentry>
+                                <term><option>--share-system</option></term>
+
+                                <listitem><para>Allows the container
+                                to share certain system facilities
+                                with the host. More specifically, this
+                                turns off PID namespacing, UTS
+                                namespacing and IPC namespacing, and
+                                thus allows the guest to see and
+                                interact more easily with processes
+                                outside of the container. Note that
+                                using this option makes it impossible
+                                to start up a full Operating System in the
+                                container, as an init system cannot
+                                operate in this mode. It is only
+                                useful to run specific programs or
+                                applications this way, without
+                                involving an init
+                                system in the container.</para></listitem>
+                        </varlistentry>
+
                 </variablelist>
 
         </refsect1>
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index 646c6c0..759f9c1 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -118,6 +118,7 @@ static char **arg_bind = NULL;
 static char **arg_bind_ro = NULL;
 static char **arg_setenv = NULL;
 static bool arg_quiet = false;
+static bool arg_share_system = false;
 
 static int help(void) {
 
@@ -138,6 +139,7 @@ static int help(void) {
                "                            Set the SELinux security context to be used by\n"
                "                            API/tmpfs file systems in the container\n"
                "     --private-network      Disable network in container\n"
+               "     --share-system         Share system namespaces with host\n"
                "     --read-only            Mount the root directory read-only\n"
                "     --capability=CAP       In addition to the default, retain specified\n"
                "                            capability\n"
@@ -167,6 +169,7 @@ static int parse_argv(int argc, char *argv[]) {
                 ARG_BIND,
                 ARG_BIND_RO,
                 ARG_SETENV,
+                ARG_SHARE_SYSTEM
         };
 
         static const struct option options[] = {
@@ -189,6 +192,7 @@ static int parse_argv(int argc, char *argv[]) {
                 { "selinux-context",       required_argument, NULL, 'Z'                 },
                 { "selinux-apifs-context", required_argument, NULL, 'L'                 },
                 { "quiet",                 no_argument,       NULL, 'q'                 },
+                { "share-system",          no_argument,       NULL, ARG_SHARE_SYSTEM    },
                 {}
         };
 
@@ -382,6 +386,10 @@ static int parse_argv(int argc, char *argv[]) {
                         arg_quiet = true;
                         break;
 
+                case ARG_SHARE_SYSTEM:
+                        arg_share_system = true;
+                        break;
+
                 case '?':
                         return -EINVAL;
 
@@ -1267,7 +1275,10 @@ int main(int argc, char *argv[]) {
                         goto finish;
                 }
 
-                pid = syscall(__NR_clone, SIGCHLD|CLONE_NEWIPC|CLONE_NEWNS|CLONE_NEWPID|CLONE_NEWUTS|(arg_private_network ? CLONE_NEWNET : 0), NULL);
+                pid = syscall(__NR_clone,
+                              SIGCHLD|CLONE_NEWNS|
+                              (arg_share_system ? 0 : CLONE_NEWIPC|CLONE_NEWPID|CLONE_NEWUTS)|
+                              (arg_private_network ? CLONE_NEWNET : 0), NULL);
                 if (pid < 0) {
                         if (errno == EINVAL)
                                 log_error("clone() failed, do you have namespace support enabled in your kernel? (You need UTS, IPC, PID and NET namespacing built in): %m");

commit deb678f15a6faf9feb29e18954553f5051788056
Author: Lennart Poettering <lennart at poettering.net>
Date:   Mon Feb 10 13:05:28 2014 +0100

    update TODO

diff --git a/TODO b/TODO
index 1a1e889..06c3590 100644
--- a/TODO
+++ b/TODO
@@ -1,10 +1,4 @@
 Bugfixes:
-* killing nspawn with ]]] results in:
-   machine-f20.scope stopping timed out. Killing.
-   Stopped Container f20.
-   Unit machine-f20.scope entered failed state.
-  and it cannot be started again
-
 * enabling an instance unit creates a pointless link, and
   the unit will be started with getty at getty.service:
     $ systemctl enable getty at .service

commit 82adf6af7c72b852449346835f33184a841b4796
Author: Lennart Poettering <lennart at poettering.net>
Date:   Mon Feb 10 12:32:03 2014 +0100

    nspawn,man: use a common vocabulary when referring to selinux security contexts
    
    Let's always call the security labels the same way:
    
      SMACK: "Smack Label"
      SELINUX: "SELinux Security Context"
    
    And the low-level encapsulation is called "seclabel". Now let's hope we
    stick to this vocabulary in future, too, and don't mix "label"s and
    "security contexts" and so on wildly.

diff --git a/man/sd_bus_creds_get_pid.xml b/man/sd_bus_creds_get_pid.xml
index 40de81f..d335331 100644
--- a/man/sd_bus_creds_get_pid.xml
+++ b/man/sd_bus_creds_get_pid.xml
@@ -333,7 +333,7 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>.
     but will check the bounding capabilities mask.</para>
 
     <para><function>sd_bus_creds_get_selinux_context</function> will
-    retrieve the SELinux context of the process.</para>
+    retrieve the SELinux security context (label) of the process.</para>
 
     <para><function>sd_bus_creds_get_audit_session_id</function> will
     retrieve the audit session identifier of the process.</para>
diff --git a/man/systemd-nspawn.xml b/man/systemd-nspawn.xml
index c95a7c0..96ccc5c 100644
--- a/man/systemd-nspawn.xml
+++ b/man/systemd-nspawn.xml
@@ -249,23 +249,23 @@
                         </varlistentry>
 
                         <varlistentry>
-                                <term><option>-L</option></term>
-                                <term><option>--apifs-label=</option></term>
+                                <term><option>-Z</option></term>
+                                <term><option>--selinux-context=</option></term>
 
-                                <listitem><para>Sets the mandatory
-                                access control (MAC/SELinux) file
-                                label to be used by virtual API file
-                                systems in the container.</para>
+                                <listitem><para>Sets the SELinux
+                                security context to be used to label
+                                processes in the container.</para>
                                 </listitem>
                         </varlistentry>
 
                         <varlistentry>
-                                <term><option>-Z</option></term>
-                                <term><option>--process-label=</option></term>
+                                <term><option>-L</option></term>
+                                <term><option>--selinux-apifs-context=</option></term>
 
-                                <listitem><para>Sets the mandatory
-                                access control (MAC/SELinux) label to be used by
-                                processes in the container.</para>
+                                <listitem><para>Sets the SELinux security
+                                context to be used to label files in
+                                the virtual API file systems in the
+                                container.</para>
                                 </listitem>
                         </varlistentry>
 
@@ -495,7 +495,7 @@
                 <programlisting># chcon system_u:object_r:svirt_sandbox_file_t:s0:c0,c1 -R /srv/container
 # systemd-nspawn -L system_u:object_r:svirt_sandbox_file_t:s0:c0,c1 -Z system_u:system_r:svirt_lxc_net_t:s0:c0,c1 -D /srv/container /bin/sh</programlisting>
 
-                <para>This runs a container with SELinux sandbox labels.</para>
+                <para>This runs a container with SELinux sandbox security contexts.</para>
         </refsect1>
 
         <refsect1>
diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml
index ecf48a7..f4caccd 100644
--- a/man/systemd.exec.xml
+++ b/man/systemd.exec.xml
@@ -953,12 +953,16 @@
                         <varlistentry>
                                 <term><varname>SELinuxContext=</varname></term>
 
-                                <listitem><para>Set the SELinux context of the
-                                executed process. If set, this will override the
-                                automated domain transition. However, the policy
-                                still need to autorize the transition. This directive
-                                is ignored if SELinux is disabled. If prefixed by <literal>-</literal>,
-                                all errors will be ignored. See
+                                <listitem><para>Set the SELinux
+                                security context of the executed
+                                process. If set, this will override
+                                the automated domain
+                                transition. However, the policy still
+                                needs to autorize the transition. This
+                                directive is ignored if SELinux is
+                                disabled. If prefixed by
+                                <literal>-</literal>, all errors will
+                                be ignored. See
                                 <citerefentry><refentrytitle>setexeccon</refentrytitle><manvolnum>3</manvolnum></citerefentry>
                                 for details.</para></listitem>
                         </varlistentry>
diff --git a/man/systemd.journal-fields.xml b/man/systemd.journal-fields.xml
index bb89ed5..c93b5da 100644
--- a/man/systemd.journal-fields.xml
+++ b/man/systemd.journal-fields.xml
@@ -244,8 +244,8 @@
                                 <term><varname>_SELINUX_CONTEXT=</varname></term>
                                 <listitem>
                                         <para>The SELinux security
-                                        context of the process the
-                                        journal entry originates
+                                        context (label) of the process
+                                        the journal entry originates
                                         from.</para>
                                 </listitem>
                         </varlistentry>
diff --git a/man/tmpfiles.d.xml b/man/tmpfiles.d.xml
index ec1ae76..a304dd0 100644
--- a/man/tmpfiles.d.xml
+++ b/man/tmpfiles.d.xml
@@ -174,7 +174,7 @@ L    /tmp/foobar -    -    -    -   /dev/null</programlisting>
                                         adjust its access mode, group
                                         and user to the specified
                                         values and reset the SELinux
-                                        label. If it does not exist, do
+                                        security context. If it does not exist, do
                                         nothing.</para></listitem>
                                 </varlistentry>
 
@@ -242,7 +242,7 @@ L    /tmp/foobar -    -    -    -   /dev/null</programlisting>
                                 <varlistentry>
                                         <term><varname>z</varname></term>
                                         <listitem><para>Restore
-                                        SELinux security context label
+                                        SELinux security context
                                         and set ownership and access
                                         mode of a file or directory if
                                         it exists.  Lines of this type
@@ -255,7 +255,7 @@ L    /tmp/foobar -    -    -    -   /dev/null</programlisting>
                                         <term><varname>Z</varname></term>
                                         <listitem><para>Recursively
                                         restore SELinux security
-                                        context label and set
+                                        context and set
                                         ownership and access mode of a
                                         path and all its
                                         subdirectories (if it is a
diff --git a/src/core/execute.c b/src/core/execute.c
index 4370654..b941a02 100644
--- a/src/core/execute.c
+++ b/src/core/execute.c
@@ -2123,7 +2123,6 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) {
                 fprintf(f,
                         "%sSELinuxContext: %s\n",
                         prefix, c->selinux_context);
-
 }
 
 void exec_status_start(ExecStatus *s, pid_t pid) {
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index be8161c..646c6c0 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -80,8 +80,8 @@ static char *arg_directory = NULL;
 static char *arg_user = NULL;
 static sd_id128_t arg_uuid = {};
 static char *arg_machine = NULL;
-static char *arg_process_label = NULL;
-static char *arg_apifs_label = NULL;
+static char *arg_selinux_context = NULL;
+static char *arg_selinux_apifs_context = NULL;
 static const char *arg_slice = NULL;
 static bool arg_private_network = false;
 static bool arg_read_only = false;
@@ -131,10 +131,12 @@ static int help(void) {
                "     --uuid=UUID            Set a specific machine UUID for the container\n"
                "  -M --machine=NAME         Set the machine name for the container\n"
                "  -S --slice=SLICE          Place the container in the specified slice\n"
-               "  -L --apifs-label=LABEL    Set the MAC file label to be used by API/tmpfs file\n"
-               "                            systems in the container\n"
-               "  -Z --process-label=LABEL  Set the MAC label to be used by processes in\n"
-               "                            the container\n"
+               "  -Z --selinux-context=SECLABEL\n"
+               "                            Set the SELinux security context to be used by\n"
+               "                            processes in the container\n"
+               "  -L --selinux-apifs-context=SECLABEL\n"
+               "                            Set the SELinux security context to be used by\n"
+               "                            API/tmpfs file systems in the container\n"
                "     --private-network      Disable network in container\n"
                "     --read-only            Mount the root directory read-only\n"
                "     --capability=CAP       In addition to the default, retain specified\n"
@@ -168,25 +170,25 @@ static int parse_argv(int argc, char *argv[]) {
         };
 
         static const struct option options[] = {
-                { "help",            no_argument,       NULL, 'h'                 },
-                { "version",         no_argument,       NULL, ARG_VERSION         },
-                { "directory",       required_argument, NULL, 'D'                 },
-                { "user",            required_argument, NULL, 'u'                 },
-                { "private-network", no_argument,       NULL, ARG_PRIVATE_NETWORK },
-                { "boot",            no_argument,       NULL, 'b'                 },
-                { "uuid",            required_argument, NULL, ARG_UUID            },
-                { "read-only",       no_argument,       NULL, ARG_READ_ONLY       },
-                { "capability",      required_argument, NULL, ARG_CAPABILITY      },
-                { "drop-capability", required_argument, NULL, ARG_DROP_CAPABILITY },
-                { "link-journal",    required_argument, NULL, ARG_LINK_JOURNAL    },
-                { "bind",            required_argument, NULL, ARG_BIND            },
-                { "bind-ro",         required_argument, NULL, ARG_BIND_RO         },
-                { "machine",         required_argument, NULL, 'M'                 },
-                { "slice",           required_argument, NULL, 'S'                 },
-                { "setenv",          required_argument, NULL, ARG_SETENV          },
-                { "process-label",   required_argument, NULL, 'Z'                 },
-                { "apifs-label",     required_argument, NULL, 'L'                 },
-                { "quiet",           no_argument,       NULL, 'q'                 },
+                { "help",                  no_argument,       NULL, 'h'                 },
+                { "version",               no_argument,       NULL, ARG_VERSION         },
+                { "directory",             required_argument, NULL, 'D'                 },
+                { "user",                  required_argument, NULL, 'u'                 },
+                { "private-network",       no_argument,       NULL, ARG_PRIVATE_NETWORK },
+                { "boot",                  no_argument,       NULL, 'b'                 },
+                { "uuid",                  required_argument, NULL, ARG_UUID            },
+                { "read-only",             no_argument,       NULL, ARG_READ_ONLY       },
+                { "capability",            required_argument, NULL, ARG_CAPABILITY      },
+                { "drop-capability",       required_argument, NULL, ARG_DROP_CAPABILITY },
+                { "link-journal",          required_argument, NULL, ARG_LINK_JOURNAL    },
+                { "bind",                  required_argument, NULL, ARG_BIND            },
+                { "bind-ro",               required_argument, NULL, ARG_BIND_RO         },
+                { "machine",               required_argument, NULL, 'M'                 },
+                { "slice",                 required_argument, NULL, 'S'                 },
+                { "setenv",                required_argument, NULL, ARG_SETENV          },
+                { "selinux-context",       required_argument, NULL, 'Z'                 },
+                { "selinux-apifs-context", required_argument, NULL, 'L'                 },
+                { "quiet",                 no_argument,       NULL, 'q'                 },
                 {}
         };
 
@@ -261,12 +263,12 @@ static int parse_argv(int argc, char *argv[]) {
 
                         break;
 
-                case 'L':
-                        arg_apifs_label = optarg;
+                case 'Z':
+                        arg_selinux_context = optarg;
                         break;
 
-                case 'Z':
-                        arg_process_label = optarg;
+                case 'L':
+                        arg_selinux_apifs_context = optarg;
                         break;
 
                 case ARG_READ_ONLY:
@@ -449,8 +451,9 @@ static int mount_all(const char *dest) {
                 mkdir_p(where, 0755);
 
 #ifdef HAVE_SELINUX
-                if (arg_apifs_label && (streq_ptr(mount_table[k].what, "tmpfs") || streq_ptr(mount_table[k].what, "devpts"))) {
-                        options = strjoin(mount_table[k].options, ",context=\"", arg_apifs_label, "\"", NULL);
+                if (arg_selinux_apifs_context &&
+                    (streq_ptr(mount_table[k].what, "tmpfs") || streq_ptr(mount_table[k].what, "devpts"))) {
+                        options = strjoin(mount_table[k].options, ",context=\"", arg_selinux_apifs_context, "\"", NULL);
                         if (!options)
                                 return log_oom();
 
@@ -1535,9 +1538,9 @@ int main(int argc, char *argv[]) {
                                 env_use = (char**) envp;
 
 #ifdef HAVE_SELINUX
-                        if (arg_process_label)
-                                if (setexeccon(arg_process_label) < 0)
-                                        log_error("setexeccon(\"%s\") failed: %m", arg_process_label);
+                        if (arg_selinux_context)
+                                if (setexeccon(arg_selinux_context) < 0)
+                                        log_error("setexeccon(\"%s\") failed: %m", arg_selinux_context);
 #endif
                         if (arg_boot) {
                                 char **a;

commit 0d3f7bb3a5bc6d5c0712f88a080fed388981bca3
Author: Michael Scherer <misc at zarb.org>
Date:   Thu Feb 6 10:05:18 2014 +0100

    exec: Add support for ignoring errors on SELinuxContext by prefixing it with -, like for others settings.
    
    Also remove call to security_check_context, as this doesn't serve anything, since
    setexeccon will fail anyway.

diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml
index 4281c03..ecf48a7 100644
--- a/man/systemd.exec.xml
+++ b/man/systemd.exec.xml
@@ -956,7 +956,9 @@
                                 <listitem><para>Set the SELinux context of the
                                 executed process. If set, this will override the
                                 automated domain transition. However, the policy
-                                still need to autorize the transition. See
+                                still need to autorize the transition. This directive
+                                is ignored if SELinux is disabled. If prefixed by <literal>-</literal>,
+                                all errors will be ignored. See
                                 <citerefentry><refentrytitle>setexeccon</refentrytitle><manvolnum>3</manvolnum></citerefentry>
                                 for details.</para></listitem>
                         </varlistentry>
diff --git a/src/core/execute.c b/src/core/execute.c
index 474a4af..4370654 100644
--- a/src/core/execute.c
+++ b/src/core/execute.c
@@ -72,6 +72,7 @@
 #include "fileio.h"
 #include "unit.h"
 #include "async.h"
+#include "selinux-util.h"
 
 #define IDLE_TIMEOUT_USEC (5*USEC_PER_SEC)
 #define IDLE_TIMEOUT2_USEC (1*USEC_PER_SEC)
@@ -1570,13 +1571,18 @@ int exec_spawn(ExecCommand *command,
                         }
 #ifdef HAVE_SELINUX
                         if (context->selinux_context && use_selinux()) {
-                                err = security_check_context(context->selinux_context);
-                                if (err < 0) {
-                                        r = EXIT_SELINUX_CONTEXT;
-                                        goto fail_child;
-                                }
-                                err = setexeccon(context->selinux_context);
-                                if (err < 0) {
+                                bool ignore;
+                                char* c;
+
+                                c = context->selinux_context;
+                                if (c[0] == '-') {
+                                        c++;
+                                        ignore = true;
+                                } else
+                                        ignore = false;
+
+                                err = setexeccon(c);
+                                if (err < 0 && !ignore) {
                                         r = EXIT_SELINUX_CONTEXT;
                                         goto fail_child;
                                 }

commit 5c56a259e07661a66e806cc2fbc71de96a75f78e
Author: Michael Scherer <misc at zarb.org>
Date:   Thu Feb 6 10:05:17 2014 +0100

    exec: Ignore the setting SELinuxContext if selinux is not enabled

diff --git a/src/core/execute.c b/src/core/execute.c
index c02c768..474a4af 100644
--- a/src/core/execute.c
+++ b/src/core/execute.c
@@ -1569,7 +1569,7 @@ int exec_spawn(ExecCommand *command,
                                 }
                         }
 #ifdef HAVE_SELINUX
-                        if (context->selinux_context) {
+                        if (context->selinux_context && use_selinux()) {
                                 err = security_check_context(context->selinux_context);
                                 if (err < 0) {
                                         r = EXIT_SELINUX_CONTEXT;

commit 7b52a628f8b43ba521c302a7f32bccf9d0dc8bfd
Author: Michael Scherer <misc at zarb.org>
Date:   Thu Feb 6 10:05:16 2014 +0100

    exec: Add SELinuxContext configuration item
    
    This permit to let system administrators decide of the domain of a service.
    This can be used with templated units to have each service in a différent
    domain ( for example, a per customer database, using MLS or anything ),
    or can be used to force a non selinux enabled system (jvm, erlang, etc)
    to start in a different domain for each service.

diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml
index 7eaf52b..4281c03 100644
--- a/man/systemd.exec.xml
+++ b/man/systemd.exec.xml
@@ -951,6 +951,17 @@
                         </varlistentry>
 
                         <varlistentry>
+                                <term><varname>SELinuxContext=</varname></term>
+
+                                <listitem><para>Set the SELinux context of the
+                                executed process. If set, this will override the
+                                automated domain transition. However, the policy
+                                still need to autorize the transition. See
+                                <citerefentry><refentrytitle>setexeccon</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                                for details.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
                                 <term><varname>IgnoreSIGPIPE=</varname></term>
 
                                 <listitem><para>Takes a boolean
diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c
index 4236b98..db16990 100644
--- a/src/core/dbus-execute.c
+++ b/src/core/dbus-execute.c
@@ -419,6 +419,7 @@ const sd_bus_vtable bus_exec_vtable[] = {
         SD_BUS_PROPERTY("PrivateDevices", "b", bus_property_get_bool, offsetof(ExecContext, private_devices), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("SameProcessGroup", "b", bus_property_get_bool, offsetof(ExecContext, same_pgrp), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("UtmpIdentifier", "s", NULL, offsetof(ExecContext, utmp_id), SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("SELinuxContext", "s", NULL, offsetof(ExecContext, selinux_context), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("IgnoreSIGPIPE", "b", bus_property_get_bool, offsetof(ExecContext, ignore_sigpipe), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("NoNewPrivileges", "b", bus_property_get_bool, offsetof(ExecContext, no_new_privileges), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("SystemCallFilter", "au", property_get_syscall_filter, 0, SD_BUS_VTABLE_PROPERTY_CONST),
diff --git a/src/core/execute.c b/src/core/execute.c
index 91e4352..c02c768 100644
--- a/src/core/execute.c
+++ b/src/core/execute.c
@@ -47,6 +47,10 @@
 #include <security/pam_appl.h>
 #endif
 
+#ifdef HAVE_SELINUX
+#include <selinux/selinux.h>
+#endif
+
 #include "execute.h"
 #include "strv.h"
 #include "macro.h"
@@ -1564,6 +1568,20 @@ int exec_spawn(ExecCommand *command,
                                         goto fail_child;
                                 }
                         }
+#ifdef HAVE_SELINUX
+                        if (context->selinux_context) {
+                                err = security_check_context(context->selinux_context);
+                                if (err < 0) {
+                                        r = EXIT_SELINUX_CONTEXT;
+                                        goto fail_child;
+                                }
+                                err = setexeccon(context->selinux_context);
+                                if (err < 0) {
+                                        r = EXIT_SELINUX_CONTEXT;
+                                        goto fail_child;
+                                }
+                        }
+#endif
                 }
 
                 err = build_environment(context, n_fds, watchdog_usec, home, username, shell, &our_env);
@@ -1722,6 +1740,9 @@ void exec_context_done(ExecContext *c) {
         free(c->utmp_id);
         c->utmp_id = NULL;
 
+        free(c->selinux_context);
+        c->selinux_context = NULL;
+
         free(c->syscall_filter);
         c->syscall_filter = NULL;
 }
@@ -2091,6 +2112,12 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) {
                 fprintf(f,
                         "%sUtmpIdentifier: %s\n",
                         prefix, c->utmp_id);
+
+        if (c->selinux_context)
+                fprintf(f,
+                        "%sSELinuxContext: %s\n",
+                        prefix, c->selinux_context);
+
 }
 
 void exec_status_start(ExecStatus *s, pid_t pid) {
diff --git a/src/core/execute.h b/src/core/execute.h
index 4851152..be811a9 100644
--- a/src/core/execute.h
+++ b/src/core/execute.h
@@ -133,6 +133,8 @@ struct ExecContext {
 
         char *utmp_id;
 
+        char *selinux_context;
+
         char **read_write_dirs, **read_only_dirs, **inaccessible_dirs;
         unsigned long mount_flags;
 
diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4
index 59b2a64..7d40578 100644
--- a/src/core/load-fragment-gperf.gperf.m4
+++ b/src/core/load-fragment-gperf.gperf.m4
@@ -76,7 +76,8 @@ $1.MountFlags,                   config_parse_exec_mount_flags,      0,
 $1.TCPWrapName,                  config_parse_unit_string_printf,    0,                             offsetof($1, exec_context.tcpwrap_name)
 $1.PAMName,                      config_parse_unit_string_printf,    0,                             offsetof($1, exec_context.pam_name)
 $1.IgnoreSIGPIPE,                config_parse_bool,                  0,                             offsetof($1, exec_context.ignore_sigpipe)
-$1.UtmpIdentifier,               config_parse_unit_string_printf,    0,                             offsetof($1, exec_context.utmp_id)'
+$1.UtmpIdentifier,               config_parse_unit_string_printf,    0,                             offsetof($1, exec_context.utmp_id)
+$1.SELinuxContext,               config_parse_unit_string_printf,    0,                             offsetof($1, exec_context.selinux_context)'
 )m4_dnl
 m4_define(`KILL_CONTEXT_CONFIG_ITEMS',
 `$1.SendSIGKILL,                 config_parse_bool,                  0,                             offsetof($1, kill_context.send_sigkill)
diff --git a/src/shared/exit-status.c b/src/shared/exit-status.c
index ef2d63f..70789f5 100644
--- a/src/shared/exit-status.c
+++ b/src/shared/exit-status.c
@@ -130,6 +130,9 @@ const char* exit_status_to_string(ExitStatus status, ExitStatusLevel level) {
 
                 case EXIT_SECCOMP:
                         return "SECCOMP";
+
+                case EXIT_SELINUX_CONTEXT:
+                        return "SELINUX_CONTEXT";
                 }
         }
 
diff --git a/src/shared/exit-status.h b/src/shared/exit-status.h
index 1ecf9d5..e84bfe3 100644
--- a/src/shared/exit-status.h
+++ b/src/shared/exit-status.h
@@ -67,7 +67,8 @@ typedef enum ExitStatus {
         EXIT_NETWORK,
         EXIT_NAMESPACE,
         EXIT_NO_NEW_PRIVILEGES,
-        EXIT_SECCOMP
+        EXIT_SECCOMP,
+        EXIT_SELINUX_CONTEXT
 } ExitStatus;
 
 typedef enum ExitStatusLevel {



More information about the systemd-commits mailing list