diff --git a/man/systemd.socket.xml b/man/systemd.socket.xml index b669e7d15d..1600656fdb 100644 --- a/man/systemd.socket.xml +++ b/man/systemd.socket.xml @@ -629,10 +629,12 @@ resulting SELinux context originate from either the target binary that is effectively triggered by socket unit or from the value of the SELinuxContext= option. - This configuration option only affects sockets with - Accept= mode set to - yes. Also note that this option is useful - only when MLS/MCS SELinux policy is deployed. Defaults to + This configuration option applies only when activated service + is passed in single socket file descriptor, i.e. service + instances that have standard input connected to a socket or + services triggered by exactly one socket unit. Also note + that this option is useful only when MLS/MCS SELinux policy + is deployed. Defaults to false. diff --git a/src/core/execute.c b/src/core/execute.c index af24f9f713..2a337b55a2 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -4345,11 +4345,22 @@ static int exec_child( } #if HAVE_SELINUX - if (needs_sandboxing && use_selinux && params->selinux_context_net && socket_fd >= 0) { - r = mac_selinux_get_child_mls_label(socket_fd, executable, context->selinux_context, &mac_selinux_context_net); - if (r < 0) { - *exit_status = EXIT_SELINUX_CONTEXT; - return log_unit_error_errno(unit, r, "Failed to determine SELinux context: %m"); + if (needs_sandboxing && use_selinux && params->selinux_context_net) { + int fd = -1; + + if (socket_fd >= 0) + fd = socket_fd; + else if (params->n_socket_fds == 1) + /* If stdin is not connected to a socket but we are triggered by exactly one socket unit then we + * use context from that fd to compute the label. */ + fd = params->fds[0]; + + if (fd >= 0) { + r = mac_selinux_get_child_mls_label(fd, executable, context->selinux_context, &mac_selinux_context_net); + if (r < 0) { + *exit_status = EXIT_SELINUX_CONTEXT; + return log_unit_error_errno(unit, r, "Failed to determine SELinux context: %m"); + } } } #endif