summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFabio Kung <fabio.kung@gmail.com>2017-08-01 00:15:18 -0700
committerLennart Poettering <lennart@poettering.net>2017-08-01 09:15:18 +0200
commit7f18ef0a555a3c3cef08e0965dc453fe5954b5a7 (patch)
tree091f4094d318cddc52584ffbafd4ee082f61a4e8
parent6b43d079a251f11ec70ac91579ecc24f3448b963 (diff)
downloadsystemd-7f18ef0a555a3c3cef08e0965dc453fe5954b5a7.tar.gz
core: check which MACs to use before a new mount ns is created (#6498)
/sys is not guaranteed to exist when a new mount namespace is created. It is only mounted under conditions specified by `namespace_info_mount_apivfs`. Checking if the three available MAC LSMs are enabled requires a sysfs mounted at /sys, so the checks are moved to before a new mount ns is created.
-rw-r--r--src/core/execute.c58
1 files changed, 36 insertions, 22 deletions
diff --git a/src/core/execute.c b/src/core/execute.c
index 7481588b08..2b6acb266a 100644
--- a/src/core/execute.c
+++ b/src/core/execute.c
@@ -1903,15 +1903,11 @@ static int setup_smack(
const ExecContext *context,
const ExecCommand *command) {
-#ifdef HAVE_SMACK
int r;
assert(context);
assert(command);
- if (!mac_smack_use())
- return 0;
-
if (context->smack_process_label) {
r = mac_smack_apply_pid(0, context->smack_process_label);
if (r < 0)
@@ -1930,7 +1926,6 @@ static int setup_smack(
return r;
}
#endif
-#endif
return 0;
}
@@ -2300,7 +2295,8 @@ static int exec_child(
const char *home = NULL, *shell = NULL;
dev_t journal_stream_dev = 0;
ino_t journal_stream_ino = 0;
- bool needs_mount_namespace;
+ bool needs_exec_restrictions, needs_mount_namespace,
+ needs_selinux = false, needs_smack = false, needs_apparmor = false;
uid_t uid = UID_INVALID;
gid_t gid = GID_INVALID;
int i, r, ngids = 0;
@@ -2642,7 +2638,9 @@ static int exec_child(
return r;
}
- if ((params->flags & EXEC_APPLY_PERMISSIONS) && !command->privileged) {
+ needs_exec_restrictions = (params->flags & EXEC_APPLY_PERMISSIONS) && !command->privileged;
+
+ if (needs_exec_restrictions) {
if (context->pam_name && username) {
r = setup_pam(context->pam_name, username, uid, gid, context->tty_path, &accum_env, fds, n_fds);
if (r < 0) {
@@ -2650,6 +2648,23 @@ static int exec_child(
return r;
}
}
+
+ /* MAC enablement checks need to be done before a new mount ns is created, as they rely on /sys being
+ * present. The actual MAC context application will happen later, as late as possible, to avoid
+ * impacting our own code paths. */
+
+#ifdef HAVE_SELINUX
+ needs_selinux = mac_selinux_use();
+#endif
+
+#ifdef HAVE_SMACK
+ needs_smack = mac_smack_use();
+#endif
+
+#ifdef HAVE_APPARMOR
+ needs_apparmor = context->apparmor_profile && mac_apparmor_use();
+#endif
+
}
if (context->private_network && runtime && runtime->netns_storage_socket[0] >= 0) {
@@ -2675,7 +2690,7 @@ static int exec_child(
return r;
/* Drop groups as early as possbile */
- if ((params->flags & EXEC_APPLY_PERMISSIONS) && !command->privileged) {
+ if (needs_exec_restrictions) {
r = enforce_groups(context, gid, supplementary_gids, ngids);
if (r < 0) {
*exit_status = EXIT_GROUP;
@@ -2684,12 +2699,7 @@ static int exec_child(
}
#ifdef HAVE_SELINUX
- if ((params->flags & EXEC_APPLY_PERMISSIONS) &&
- mac_selinux_use() &&
- params->selinux_context_net &&
- socket_fd >= 0 &&
- !command->privileged) {
-
+ if (needs_exec_restrictions && needs_selinux && params->selinux_context_net && socket_fd >= 0) {
r = mac_selinux_get_child_mls_label(socket_fd, command->path, context->selinux_context, &mac_selinux_context_net);
if (r < 0) {
*exit_status = EXIT_SELINUX_CONTEXT;
@@ -2722,7 +2732,7 @@ static int exec_child(
return r;
}
- if ((params->flags & EXEC_APPLY_PERMISSIONS) && !command->privileged) {
+ if (needs_exec_restrictions) {
int secure_bits = context->secure_bits;
@@ -2800,7 +2810,7 @@ static int exec_child(
* are restricted. */
#ifdef HAVE_SELINUX
- if (mac_selinux_use()) {
+ if (needs_selinux) {
char *exec_context = mac_selinux_context_net ?: context->selinux_context;
if (exec_context) {
@@ -2814,15 +2824,19 @@ static int exec_child(
}
#endif
- r = setup_smack(context, command);
- if (r < 0) {
- *exit_status = EXIT_SMACK_PROCESS_LABEL;
- *error_message = strdup("Failed to set SMACK process label");
- return r;
+#ifdef HAVE_SMACK
+ if (needs_smack) {
+ r = setup_smack(context, command);
+ if (r < 0) {
+ *exit_status = EXIT_SMACK_PROCESS_LABEL;
+ *error_message = strdup("Failed to set SMACK process label");
+ return r;
+ }
}
+#endif
#ifdef HAVE_APPARMOR
- if (context->apparmor_profile && mac_apparmor_use()) {
+ if (needs_apparmor) {
r = aa_change_onexec(context->apparmor_profile);
if (r < 0 && !context->apparmor_profile_ignore) {
*exit_status = EXIT_APPARMOR_PROFILE;