diff options
| -rw-r--r-- | man/systemd.exec.xml | 29 | ||||
| -rw-r--r-- | src/core/dbus-execute.c | 19 | ||||
| -rw-r--r-- | src/core/execute.c | 11 | ||||
| -rw-r--r-- | src/core/execute.h | 3 | ||||
| -rw-r--r-- | src/core/load-fragment-gperf.gperf.m4 | 7 | ||||
| -rw-r--r-- | src/core/load-fragment.c | 50 | ||||
| -rw-r--r-- | src/core/load-fragment.h | 1 | ||||
| -rw-r--r-- | src/shared/exit-status.h | 1 | ||||
| -rw-r--r-- | src/shared/smack-util.c | 20 | ||||
| -rw-r--r-- | src/shared/smack-util.h | 1 | 
10 files changed, 140 insertions, 2 deletions
| diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml index e9af4abd6d..0747d0e1f9 100644 --- a/man/systemd.exec.xml +++ b/man/systemd.exec.xml @@ -1138,6 +1138,35 @@                          </varlistentry>                          <varlistentry> +                                <term><varname>SmackProcessLabel=</varname></term> + +                                <listitem><para>Takes a +                                <option>SMACK64</option> security +                                label as argument. The process +                                executed by the unit will be started +                                under this label and SMACK will decide +                                whether the processes is allowed to +                                run or not based on it. The process +                                will continue to run under the label +                                specified here unless the executable +                                has its own +                                <option>SMACK64EXEC</option> label, in +                                which case the process will transition +                                to run under that label. When not +                                specified, the label that systemd is +                                running under is used. This directive +                                is ignored if SMACK is +                                disabled.</para> + +                                <para>The value may be prefixed by +                                <literal>-</literal>, in which case +                                all errors will be ignored. An empty +                                value may be specified to unset +                                previous assignments.</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 9276da4cdc..bbcd6106ad 100644 --- a/src/core/dbus-execute.c +++ b/src/core/dbus-execute.c @@ -508,6 +508,24 @@ static int property_get_apparmor_profile(          return sd_bus_message_append(reply, "(bs)", c->apparmor_profile_ignore, c->apparmor_profile);  } +static int property_get_smack_process_label( +                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->smack_process_label_ignore, c->smack_process_label); +} +  static int property_get_personality(                  sd_bus *bus,                  const char *path, @@ -636,6 +654,7 @@ const sd_bus_vtable bus_exec_vtable[] = {          SD_BUS_PROPERTY("UtmpIdentifier", "s", NULL, offsetof(ExecContext, utmp_id), SD_BUS_VTABLE_PROPERTY_CONST),          SD_BUS_PROPERTY("SELinuxContext", "(bs)", property_get_selinux_context, 0, SD_BUS_VTABLE_PROPERTY_CONST),          SD_BUS_PROPERTY("AppArmorProfile", "(bs)", property_get_apparmor_profile, 0, SD_BUS_VTABLE_PROPERTY_CONST), +        SD_BUS_PROPERTY("SmackProcessLabel", "(bs)", property_get_smack_process_label, 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 5cfd4a1f97..e6c19993ae 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -83,6 +83,7 @@  #include "af-list.h"  #include "mkdir.h"  #include "apparmor-util.h" +#include "smack-util.h"  #include "bus-kernel.h"  #include "label.h" @@ -1618,6 +1619,16 @@ static int exec_child(ExecCommand *command,                          }                  } +#ifdef HAVE_SMACK +                if (context->smack_process_label) { +                        err = mac_smack_apply_pid(0, context->smack_process_label); +                        if (err < 0) { +                                *error = EXIT_SMACK_PROCESS_LABEL; +                                return err; +                        } +                } +#endif +                  if (context->user) {                          err = enforce_user(context, uid);                          if (err < 0) { diff --git a/src/core/execute.h b/src/core/execute.h index b16a24d0c6..5ed750534d 100644 --- a/src/core/execute.h +++ b/src/core/execute.h @@ -142,6 +142,9 @@ struct ExecContext {          bool apparmor_profile_ignore;          char *apparmor_profile; +        bool smack_process_label_ignore; +        char *smack_process_label; +          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 1d2debe70f..a94b805b4b 100644 --- a/src/core/load-fragment-gperf.gperf.m4 +++ b/src/core/load-fragment-gperf.gperf.m4 @@ -95,8 +95,11 @@ m4_ifdef(`HAVE_SELINUX',  `$1.SELinuxContext,              config_parse_exec_selinux_context,  0,                             offsetof($1, exec_context)',  `$1.SELinuxContext,              config_parse_warn_compat,           0,                             0')  m4_ifdef(`HAVE_APPARMOR', -`$1.AppArmorProfile,              config_parse_exec_apparmor_profile,0,                             offsetof($1, exec_context)', -`$1.AppArmorProfile,              config_parse_warn_compat,          0,                             0')' +`$1.AppArmorProfile,             config_parse_exec_apparmor_profile, 0,                             offsetof($1, exec_context)', +`$1.AppArmorProfile,             config_parse_warn_compat,           0,                             0') +m4_ifdef(`HAVE_SMACK', +`$1.SmackProcessLabel,           config_parse_exec_smack_process_label, 0,                          offsetof($1, exec_context)', +`$1.SmackProcessLabel,           config_parse_warn_compat,           0,                             0')'  )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 2ee16bdef9..4309121649 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -1313,6 +1313,56 @@ int config_parse_exec_apparmor_profile(          return 0;  } +int config_parse_exec_smack_process_label( +                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->smack_process_label); +                c->smack_process_label = NULL; +                c->smack_process_label_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->smack_process_label); +        c->smack_process_label = k; +        c->smack_process_label_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 65100c9bd7..a799c9a690 100644 --- a/src/core/load-fragment.h +++ b/src/core/load-fragment.h @@ -94,6 +94,7 @@ int config_parse_job_mode_isolate(const char *unit, const char *filename, unsign  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);  int config_parse_personality(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_apparmor_profile(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_smack_process_label(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_address_families(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_runtime_directory(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_set_status(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); diff --git a/src/shared/exit-status.h b/src/shared/exit-status.h index f719580426..1d774f25dc 100644 --- a/src/shared/exit-status.h +++ b/src/shared/exit-status.h @@ -78,6 +78,7 @@ typedef enum ExitStatus {          EXIT_MAKE_STARTER,          EXIT_CHOWN,          EXIT_BUS_ENDPOINT, +        EXIT_SMACK_PROCESS_LABEL,  } ExitStatus;  typedef enum ExitStatusLevel { diff --git a/src/shared/smack-util.c b/src/shared/smack-util.c index a8dccd1554..b6c96435ce 100644 --- a/src/shared/smack-util.c +++ b/src/shared/smack-util.c @@ -25,6 +25,7 @@  #include "util.h"  #include "path-util.h" +#include "fileio.h"  #include "smack-util.h"  #define SMACK_FLOOR_LABEL "_" @@ -123,6 +124,25 @@ int mac_smack_apply_ip_in_fd(int fd, const char *label) {          return r;  } +int mac_smack_apply_pid(pid_t pid, const char *label) { +        int r = 0; +        const char *p; + +        assert(label); + +#ifdef HAVE_SMACK +        if (!mac_smack_use()) +                return 0; + +        p = procfs_file_alloca(pid, "attr/current"); +        r = write_string_file(p, label); +        if (r < 0) +                return r; +#endif + +        return r; +} +  int mac_smack_fix(const char *path, bool ignore_enoent, bool ignore_erofs) {          int r = 0; diff --git a/src/shared/smack-util.h b/src/shared/smack-util.h index 68778da38b..50f55b1f4b 100644 --- a/src/shared/smack-util.h +++ b/src/shared/smack-util.h @@ -31,5 +31,6 @@ int mac_smack_fix(const char *path, bool ignore_enoent, bool ignore_erofs);  int mac_smack_apply(const char *path, const char *label);  int mac_smack_apply_fd(int fd, const char *label); +int mac_smack_apply_pid(pid_t pid, const char *label);  int mac_smack_apply_ip_in_fd(int fd, const char *label);  int mac_smack_apply_ip_out_fd(int fd, const char *label); | 
