summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWaLyong Cho <walyong.cho@samsung.com>2014-11-24 20:46:20 +0900
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2014-11-24 10:20:53 -0500
commit2ca620c4ed28c01f285d869d0b22f22a360957da (patch)
treeb4807e97bf97f36c5b28fbe84c96a34864e6b972
parent8086ffacdb1bfec5ec115d24626538bda6cc372e (diff)
smack: introduce new SmackProcessLabel option
In service file, if the file has some of special SMACK label in ExecStart= and systemd has no permission for the special SMACK label then permission error will occurred. To resolve this, systemd should be able to set its SMACK label to something accessible of ExecStart=. So introduce new SmackProcessLabel. If label is specified with SmackProcessLabel= then the child systemd will set its label to that. To successfully execute the ExecStart=, accessible label should be specified with SmackProcessLabel=. Additionally, by SMACK policy, if the file in ExecStart= has no SMACK64EXEC then the executed process will have given label by SmackProcessLabel=. But if the file has SMACK64EXEC then the SMACK64EXEC label will be overridden. [zj: reword man page]
-rw-r--r--man/systemd.exec.xml29
-rw-r--r--src/core/dbus-execute.c19
-rw-r--r--src/core/execute.c11
-rw-r--r--src/core/execute.h3
-rw-r--r--src/core/load-fragment-gperf.gperf.m47
-rw-r--r--src/core/load-fragment.c50
-rw-r--r--src/core/load-fragment.h1
-rw-r--r--src/shared/exit-status.h1
-rw-r--r--src/shared/smack-util.c20
-rw-r--r--src/shared/smack-util.h1
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);