"%sPassCredentials: %s\n"
"%sPassSecurity: %s\n"
"%sTCPCongestion: %s\n"
- "%sRemoveOnStop: %s\n",
+ "%sRemoveOnStop: %s\n"
+ "%sSELinuxContextFromNet: %s\n",
prefix, socket_state_to_string(s->state),
prefix, socket_result_to_string(s->result),
prefix, socket_address_bind_ipv6_only_to_string(s->bind_ipv6_only),
prefix, yes_no(s->pass_cred),
prefix, yes_no(s->pass_sec),
prefix, strna(s->tcp_congestion),
- prefix, yes_no(s->remove_on_stop));
+ prefix, yes_no(s->remove_on_stop),
+ prefix, yes_no(s->selinux_context_from_net));
if (s->control_pid > 0)
fprintf(f,
}
static void socket_apply_socket_options(Socket *s, int fd) {
+ int r;
+
assert(s);
assert(fd >= 0);
log_warning_unit(UNIT(s)->id, "IP_TOS failed: %m");
if (s->ip_ttl >= 0) {
- int r, x;
+ int x;
r = setsockopt(fd, IPPROTO_IP, IP_TTL, &s->ip_ttl, sizeof(s->ip_ttl));
log_warning_unit(UNIT(s)->id, "SO_REUSEPORT failed: %m");
}
- if (s->smack_ip_in)
- if (smack_label_ip_in_fd(fd, s->smack_ip_in) < 0)
- log_error_unit(UNIT(s)->id, "smack_label_ip_in_fd: %m");
+ if (s->smack_ip_in) {
+ r = mac_smack_apply_ip_in_fd(fd, s->smack_ip_in);
+ if (r < 0)
+ log_error_unit(UNIT(s)->id, "mac_smack_apply_ip_in_fd: %s", strerror(-r));
+ }
- if (s->smack_ip_out)
- if (smack_label_ip_out_fd(fd, s->smack_ip_out) < 0)
- log_error_unit(UNIT(s)->id, "smack_label_ip_out_fd: %m");
+ if (s->smack_ip_out) {
+ r = mac_smack_apply_ip_out_fd(fd, s->smack_ip_out);
+ if (r < 0)
+ log_error_unit(UNIT(s)->id, "mac_smack_apply_ip_out_fd: %s", strerror(-r));
+ }
}
static void socket_apply_fifo_options(Socket *s, int fd) {
+ int r;
+
assert(s);
assert(fd >= 0);
if (s->pipe_size > 0)
if (fcntl(fd, F_SETPIPE_SZ, s->pipe_size) < 0)
- log_warning_unit(UNIT(s)->id,
- "F_SETPIPE_SZ: %m");
+ log_warning_unit(UNIT(s)->id, "F_SETPIPE_SZ: %m");
- if (s->smack)
- if (smack_label_fd(fd, s->smack) < 0)
- log_error_unit(UNIT(s)->id, "smack_label_fd: %m");
+ if (s->smack) {
+ r = mac_smack_apply_fd(fd, s->smack);
+ if (r < 0)
+ log_error_unit(UNIT(s)->id, "mac_smack_apply_fd: %s", strerror(-r));
+ }
}
static int fifo_address_create(
mkdir_parents_label(path, directory_mode);
- r = label_context_set(path, S_IFIFO);
+ r = mac_selinux_create_file_prepare(path, S_IFIFO);
if (r < 0)
goto fail;
goto fail;
}
- label_context_clear();
+ mac_selinux_create_file_clear();
if (fstat(fd, &st) < 0) {
r = -errno;
return 0;
fail:
- label_context_clear();
+ mac_selinux_create_file_clear();
safe_close(fd);
return r;
return 0;
STRV_FOREACH(i, s->symlinks)
- symlink(p, *i);
+ symlink_label(p, *i);
return 0;
}
if (p->type == SOCKET_SOCKET) {
if (!know_label) {
-
- r = socket_instantiate_service(s);
- if (r < 0)
- return r;
-
- if (UNIT_ISSET(s->service) &&
- SERVICE(UNIT_DEREF(s->service))->exec_command[SERVICE_EXEC_START]) {
- r = label_get_create_label_from_exe(SERVICE(UNIT_DEREF(s->service))->exec_command[SERVICE_EXEC_START]->path, &label);
- if (r < 0 && r != -EPERM)
- return r;
+ /* Figure out label, if we don't it know
+ * yet. We do it once, for the first
+ * socket where we need this and
+ * remember it for the rest. */
+
+ if (s->selinux_context_from_net) {
+ /* Get it from the network label */
+
+ r = mac_selinux_get_our_label(&label);
+ if (r < 0 && r != -EOPNOTSUPP)
+ goto rollback;
+
+ } else {
+ /* Get it from the executable we are about to start */
+
+ r = socket_instantiate_service(s);
+ if (r < 0)
+ goto rollback;
+
+ if (UNIT_ISSET(s->service) &&
+ SERVICE(UNIT_DEREF(s->service))->exec_command[SERVICE_EXEC_START]) {
+ r = mac_selinux_get_create_label_from_exe(SERVICE(UNIT_DEREF(s->service))->exec_command[SERVICE_EXEC_START]->path, &label);
+ if (r < 0 && r != -EPERM && r != -EOPNOTSUPP)
+ goto rollback;
+ }
}
know_label = true;
assert_not_reached("Unknown port type");
}
- label_free(label);
+ mac_selinux_free(label);
return 0;
rollback:
socket_close_fds(s);
- label_free(label);
+ mac_selinux_free(label);
+
return r;
}
_cleanup_free_ char **argv = NULL;
pid_t pid;
int r;
+ ExecParameters exec_params = {
+ .apply_permissions = true,
+ .apply_chroot = true,
+ .apply_tty_stdin = true,
+ };
assert(s);
assert(c);
if (r < 0)
goto fail;
+ exec_params.argv = argv;
+ exec_params.environment = UNIT(s)->manager->environment;
+ exec_params.confirm_spawn = UNIT(s)->manager->confirm_spawn;
+ exec_params.cgroup_supported = UNIT(s)->manager->cgroup_supported;
+ exec_params.cgroup_path = UNIT(s)->cgroup_path;
+ exec_params.runtime_prefix = manager_get_runtime_prefix(UNIT(s)->manager);
+ exec_params.unit_id = UNIT(s)->id;
+
r = exec_spawn(c,
- argv,
&s->exec_context,
- NULL, 0,
- UNIT(s)->manager->environment,
- true,
- true,
- true,
- UNIT(s)->manager->confirm_spawn,
- UNIT(s)->manager->cgroup_supported,
- UNIT(s)->cgroup_path,
- manager_get_runtime_prefix(UNIT(s)->manager),
- UNIT(s)->id,
- 0,
- NULL,
+ &exec_params,
s->exec_runtime,
&pid);
if (r < 0)
r = unit_kill_context(
UNIT(s),
&s->kill_context,
- state != SOCKET_STOP_PRE_SIGTERM && state != SOCKET_FINAL_SIGTERM,
+ (state != SOCKET_STOP_PRE_SIGTERM && state != SOCKET_FINAL_SIGTERM) ?
+ KILL_KILL : KILL_TERMINATE,
-1,
s->control_pid,
false);
unit_choose_id(UNIT(service), name);
- r = service_set_socket_fd(service, cfd, s);
+ r = service_set_socket_fd(service, cfd, s, s->selinux_context_from_net);
if (r < 0)
goto fail;