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