84b277
From f71db1f834f639a16a38e7314ba7ca0dd0d060d8 Mon Sep 17 00:00:00 2001
84b277
From: Lennart Poettering <lennart@poettering.net>
84b277
Date: Mon, 17 Feb 2014 16:52:52 +0100
84b277
Subject: [PATCH] core: store and expose SELinuxContext field normalized as
84b277
 bool + string
84b277
84b277
Conflicts:
84b277
        src/core/dbus-execute.c
84b277
        src/core/execute.c
84b277
        src/core/load-fragment.h
84b277
84b277
(cherry picked from commit 5f8640fb628cb034981e02d741fd9ddf26fdf38d)
84b277
84b277
Related: #1113790
84b277
---
84b277
 src/core/dbus-execute.c               | 26 ++++++++++++++++++-
84b277
 src/core/execute.c                    | 18 +++----------
84b277
 src/core/execute.h                    |  1 +
84b277
 src/core/load-fragment-gperf.gperf.m4 |  2 +-
84b277
 src/core/load-fragment.c              | 48 +++++++++++++++++++++++++++++++++++
84b277
 src/core/load-fragment.h              |  1 +
84b277
 6 files changed, 80 insertions(+), 16 deletions(-)
84b277
84b277
diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c
84b277
index 97d75fa..8162f1c 100644
84b277
--- a/src/core/dbus-execute.c
84b277
+++ b/src/core/dbus-execute.c
84b277
@@ -372,6 +372,30 @@ static int bus_execute_append_syscall_filter(DBusMessageIter *i, const char *pro
84b277
         return 0;
84b277
 }
84b277
 
84b277
+static int bus_execute_append_selinux_context(DBusMessageIter *i, const char *property, void *data) {
84b277
+        ExecContext *c = data;
84b277
+        dbus_bool_t selinux_context_ignore;
84b277
+        const char *selinux_context = NULL;
84b277
+
84b277
+        assert(i);
84b277
+        assert(property);
84b277
+        assert(c);
84b277
+
84b277
+        selinux_context = c->selinux_context;
84b277
+        if (!selinux_context)
84b277
+                selinux_context = "";
84b277
+
84b277
+        selinux_context_ignore = c->selinux_context_ignore;
84b277
+
84b277
+        if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &selinux_context_ignore))
84b277
+                return -ENOMEM;
84b277
+
84b277
+        if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &selinux_context))
84b277
+                return -ENOMEM;
84b277
+
84b277
+        return 0;
84b277
+}
84b277
+
84b277
 const BusProperty bus_exec_context_properties[] = {
84b277
         { "Environment",              bus_property_append_strv,             "as", offsetof(ExecContext, environment),            true },
84b277
         { "EnvironmentFiles",         bus_execute_append_env_files,      "a(sb)", offsetof(ExecContext, environment_files),      true },
84b277
@@ -429,7 +453,7 @@ const BusProperty bus_exec_context_properties[] = {
84b277
         { "PrivateNetwork",           bus_property_append_bool,              "b", offsetof(ExecContext, private_network)              },
84b277
         { "SameProcessGroup",         bus_property_append_bool,              "b", offsetof(ExecContext, same_pgrp)                    },
84b277
         { "UtmpIdentifier",           bus_property_append_string,            "s", offsetof(ExecContext, utmp_id),                true },
84b277
-        { "SELinuxContext",           bus_property_append_string,            "s", offsetof(ExecContext, selinux_context),        true },
84b277
+        { "SELinuxContext",           bus_execute_append_selinux_context, "(bs)", 0                                                   },
84b277
         { "IgnoreSIGPIPE",            bus_property_append_bool,              "b", offsetof(ExecContext, ignore_sigpipe)               },
84b277
         { "NoNewPrivileges",          bus_property_append_bool,              "b", offsetof(ExecContext, no_new_privileges)            },
84b277
         { "SystemCallFilter",         bus_execute_append_syscall_filter,    "au", 0                                                   },
84b277
diff --git a/src/core/execute.c b/src/core/execute.c
84b277
index 9fc5090..a20301d 100644
84b277
--- a/src/core/execute.c
84b277
+++ b/src/core/execute.c
84b277
@@ -1474,18 +1474,8 @@ int exec_spawn(ExecCommand *command,
84b277
                         }
84b277
 #ifdef HAVE_SELINUX
84b277
                         if (context->selinux_context && use_selinux()) {
84b277
-                                bool ignore;
84b277
-                                char* c;
84b277
-
84b277
-                                c = context->selinux_context;
84b277
-                                if (c[0] == '-') {
84b277
-                                        c++;
84b277
-                                        ignore = true;
84b277
-                                } else
84b277
-                                        ignore = false;
84b277
-
84b277
-                                err = setexeccon(c);
84b277
-                                if (err < 0 && !ignore) {
84b277
+                                err = setexeccon(context->selinux_context);
84b277
+                                if (err < 0 && !context->selinux_context_ignore) {
84b277
                                         r = EXIT_SELINUX_CONTEXT;
84b277
                                         goto fail_child;
84b277
                                 }
84b277
@@ -2097,8 +2087,8 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) {
84b277
 
84b277
         if (c->selinux_context)
84b277
                 fprintf(f,
84b277
-                        "%sSELinuxContext: %s\n",
84b277
-                        prefix, c->selinux_context);
84b277
+                        "%sSELinuxContext: %s%s\n",
84b277
+                        prefix, c->selinux_context_ignore ? "-" : "", c->selinux_context);
84b277
 
84b277
 }
84b277
 
84b277
diff --git a/src/core/execute.h b/src/core/execute.h
84b277
index 92ac8dd..2452126 100644
84b277
--- a/src/core/execute.h
84b277
+++ b/src/core/execute.h
84b277
@@ -124,6 +124,7 @@ struct ExecContext {
84b277
 
84b277
         char *utmp_id;
84b277
 
84b277
+        bool selinux_context_ignore;
84b277
         char *selinux_context;
84b277
 
84b277
         char **read_write_dirs, **read_only_dirs, **inaccessible_dirs;
84b277
diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4
84b277
index 935f04e..759fbd8 100644
84b277
--- a/src/core/load-fragment-gperf.gperf.m4
84b277
+++ b/src/core/load-fragment-gperf.gperf.m4
84b277
@@ -76,7 +76,7 @@ $1.TCPWrapName,                  config_parse_unit_string_printf,    0,
84b277
 $1.PAMName,                      config_parse_unit_string_printf,    0,                             offsetof($1, exec_context.pam_name)
84b277
 $1.IgnoreSIGPIPE,                config_parse_bool,                  0,                             offsetof($1, exec_context.ignore_sigpipe)
84b277
 $1.UtmpIdentifier,               config_parse_unit_string_printf,    0,                             offsetof($1, exec_context.utmp_id)
84b277
-$1.SELinuxContext,               config_parse_unit_string_printf,    0,                             offsetof($1, exec_context.selinux_context)'
84b277
+$1.SELinuxContext,               config_parse_exec_selinux_context,  0,                             offsetof($1, exec_context)'
84b277
 )m4_dnl
84b277
 m4_define(`KILL_CONTEXT_CONFIG_ITEMS',
84b277
 `$1.SendSIGKILL,                 config_parse_bool,                  0,                             offsetof($1, kill_context.send_sigkill)
84b277
diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c
84b277
index f01843d..8e6e428 100644
84b277
--- a/src/core/load-fragment.c
84b277
+++ b/src/core/load-fragment.c
84b277
@@ -1139,6 +1139,54 @@ int config_parse_exec_mount_flags(const char *unit,
84b277
         return 0;
84b277
 }
84b277
 
84b277
+int config_parse_exec_selinux_context(
84b277
+                const char *unit,
84b277
+                const char *filename,
84b277
+                unsigned line,
84b277
+                const char *section,
84b277
+                const char *lvalue,
84b277
+                int ltype,
84b277
+                const char *rvalue,
84b277
+                void *data,
84b277
+                void *userdata) {
84b277
+
84b277
+        ExecContext *c = data;
84b277
+        Unit *u = userdata;
84b277
+        bool ignore;
84b277
+        char *k;
84b277
+        int r;
84b277
+
84b277
+        assert(filename);
84b277
+        assert(lvalue);
84b277
+        assert(rvalue);
84b277
+        assert(data);
84b277
+
84b277
+        if (isempty(rvalue)) {
84b277
+                free(c->selinux_context);
84b277
+                c->selinux_context = NULL;
84b277
+                c->selinux_context_ignore = false;
84b277
+                return 0;
84b277
+        }
84b277
+
84b277
+        if (rvalue[0] == '-') {
84b277
+                ignore = true;
84b277
+                rvalue++;
84b277
+        } else
84b277
+                ignore = false;
84b277
+
84b277
+        r = unit_name_printf(u, rvalue, &k);
84b277
+        if (r < 0) {
84b277
+                log_syntax(unit, LOG_ERR, filename, line, -r, "Failed to resolve specifiers, ignoring: %s", strerror(-r));
84b277
+                return 0;
84b277
+        }
84b277
+
84b277
+        free(c->selinux_context);
84b277
+        c->selinux_context = k;
84b277
+        c->selinux_context_ignore = ignore;
84b277
+
84b277
+        return 0;
84b277
+}
84b277
+
84b277
 int config_parse_timer(const char *unit,
84b277
                        const char *filename,
84b277
                        unsigned line,
84b277
diff --git a/src/core/load-fragment.h b/src/core/load-fragment.h
84b277
index 90e5e3a..de48436 100644
84b277
--- a/src/core/load-fragment.h
84b277
+++ b/src/core/load-fragment.h
84b277
@@ -83,6 +83,7 @@ int config_parse_device_allow(const char *unit, const char *filename, unsigned l
84b277
 int config_parse_blockio_weight(const char *unit, const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
84b277
 int config_parse_blockio_device_weight(const char *unit, const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
84b277
 int config_parse_blockio_bandwidth(const char *unit, const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
84b277
+int config_parse_exec_selinux_context(const char *unit, const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
84b277
 
84b277
 /* gperf prototypes */
84b277
 const struct ConfigPerfItem* load_fragment_gperf_lookup(const char *key, unsigned length);