From 5f8640fb628cb034981e02d741fd9ddf26fdf38d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 17 Feb 2014 16:52:52 +0100 Subject: [PATCH 1/1] core: store and expose SELinuxContext field normalized as bool + string --- src/core/dbus-execute.c | 20 ++++++++++- src/core/execute.c | 18 +++------- src/core/execute.h | 1 + src/core/load-fragment-gperf.gperf.m4 | 2 +- src/core/load-fragment.c | 49 +++++++++++++++++++++++++++ src/core/load-fragment.h | 1 + 6 files changed, 75 insertions(+), 16 deletions(-) diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c index a62f517dc..ff5245a0e 100644 --- a/src/core/dbus-execute.c +++ b/src/core/dbus-execute.c @@ -464,6 +464,24 @@ static int property_get_syscall_errno( return sd_bus_message_append(reply, "i", (int32_t) c->syscall_errno); } +static int property_get_selinux_context( + sd_bus *bus, + const char *path, + const char *interface, + const char *property, + sd_bus_message *reply, + void *userdata, + sd_bus_error *error) { + + ExecContext *c = userdata; + + assert(bus); + assert(reply); + assert(c); + + return sd_bus_message_append(reply, "(bs)", c->selinux_context_ignore, c->selinux_context); +} + const sd_bus_vtable bus_exec_vtable[] = { SD_BUS_VTABLE_START(0), SD_BUS_PROPERTY("Environment", "as", NULL, offsetof(ExecContext, environment), SD_BUS_VTABLE_PROPERTY_CONST), @@ -523,7 +541,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("SELinuxContext", "(bs)", property_get_selinux_context, 0, 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", "(bas)", property_get_syscall_filter, 0, SD_BUS_VTABLE_PROPERTY_CONST), diff --git a/src/core/execute.c b/src/core/execute.c index 06ddd5c91..be15fb95e 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -1572,18 +1572,8 @@ int exec_spawn(ExecCommand *command, #ifdef HAVE_SELINUX if (context->selinux_context && use_selinux()) { - bool ignore; - char* c; - - c = context->selinux_context; - if (c[0] == '-') { - c++; - ignore = true; - } else - ignore = false; - - err = setexeccon(c); - if (err < 0 && !ignore) { + err = setexeccon(context->selinux_context); + if (err < 0 && !context->selinux_context_ignore) { r = EXIT_SELINUX_CONTEXT; goto fail_child; } @@ -2127,8 +2117,8 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) { if (c->selinux_context) fprintf(f, - "%sSELinuxContext: %s\n", - prefix, c->selinux_context); + "%sSELinuxContext: %s%s\n", + prefix, c->selinux_context_ignore ? "-" : "", c->selinux_context); if (c->syscall_filter) { #ifdef HAVE_SECCOMP diff --git a/src/core/execute.h b/src/core/execute.h index 06b6b3fb2..b98ef952e 100644 --- a/src/core/execute.h +++ b/src/core/execute.h @@ -138,6 +138,7 @@ struct ExecContext { char *utmp_id; + bool selinux_context_ignore; char *selinux_context; char **read_write_dirs, **read_only_dirs, **inaccessible_dirs; diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4 index c8add14c8..39fe45896 100644 --- a/src/core/load-fragment-gperf.gperf.m4 +++ b/src/core/load-fragment-gperf.gperf.m4 @@ -83,7 +83,7 @@ $1.TCPWrapName, config_parse_unit_string_printf, 0, $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.SELinuxContext, config_parse_unit_string_printf, 0, offsetof($1, exec_context.selinux_context)' +$1.SELinuxContext, config_parse_exec_selinux_context, 0, offsetof($1, exec_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/core/load-fragment.c b/src/core/load-fragment.c index c92387439..2ee4616a1 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -1143,6 +1143,55 @@ int config_parse_exec_mount_flags(const char *unit, return 0; } +int config_parse_exec_selinux_context( + const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + ExecContext *c = data; + Unit *u = userdata; + bool ignore; + char *k; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + if (isempty(rvalue)) { + free(c->selinux_context); + c->selinux_context = NULL; + c->selinux_context_ignore = false; + return 0; + } + + if (rvalue[0] == '-') { + ignore = true; + rvalue++; + } else + ignore = false; + + r = unit_name_printf(u, rvalue, &k); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, -r, "Failed to resolve specifiers, ignoring: %s", strerror(-r)); + return 0; + } + + free(c->selinux_context); + c->selinux_context = k; + c->selinux_context_ignore = ignore; + + return 0; +} + int config_parse_timer(const char *unit, const char *filename, unsigned line, diff --git a/src/core/load-fragment.h b/src/core/load-fragment.h index 23e9d1131..cc77fccf9 100644 --- a/src/core/load-fragment.h +++ b/src/core/load-fragment.h @@ -87,6 +87,7 @@ int config_parse_blockio_device_weight(const char *unit, const char *filename, u int config_parse_blockio_bandwidth(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_job_mode(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_job_mode_isolate(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_exec_selinux_context(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); /* gperf prototypes */ const struct ConfigPerfItem* load_fragment_gperf_lookup(const char *key, unsigned length); -- 2.30.2