X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fcore%2Fsocket.c;h=6ba8338d8b26ef00d905b779c45bf77e960e5483;hb=f1f00dbb7f3741b30d4a26b1a8b65ec46ff1fde3;hp=68e21e60ac9356dd032d97e39ccde62b9442a540;hpb=9fa95f8539a380e93f760956bc6982e57f5bf3af;p=elogind.git diff --git a/src/core/socket.c b/src/core/socket.c index 68e21e60a..6ba8338d8 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -489,7 +489,8 @@ static void socket_dump(Unit *u, FILE *f, const char *prefix) { "%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), @@ -504,7 +505,8 @@ static void socket_dump(Unit *u, FILE *f, const char *prefix) { 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, @@ -805,6 +807,8 @@ static void socket_close_fds(Socket *s) { } static void socket_apply_socket_options(Socket *s, int fd) { + int r; + assert(s); assert(fd >= 0); @@ -892,7 +896,7 @@ static void socket_apply_socket_options(Socket *s, int fd) { 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)); @@ -918,27 +922,34 @@ static void socket_apply_socket_options(Socket *s, int fd) { 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( @@ -956,7 +967,7 @@ 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; @@ -979,7 +990,7 @@ static int fifo_address_create( goto fail; } - label_context_clear(); + mac_selinux_create_file_clear(); if (fstat(fd, &st) < 0) { r = -errno; @@ -999,7 +1010,7 @@ static int fifo_address_create( return 0; fail: - label_context_clear(); + mac_selinux_create_file_clear(); safe_close(fd); return r; @@ -1109,7 +1120,7 @@ static int socket_symlink(Socket *s) { return 0; STRV_FOREACH(i, s->symlinks) - symlink(p, *i); + symlink_label(p, *i); return 0; } @@ -1130,16 +1141,31 @@ static int socket_open_fds(Socket *s) { 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; @@ -1198,12 +1224,13 @@ static int socket_open_fds(Socket *s) { 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; } @@ -1551,7 +1578,8 @@ static void socket_enter_signal(Socket *s, SocketState state, SocketResult f) { 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); @@ -1821,7 +1849,7 @@ static void socket_enter_running(Socket *s, int cfd) { 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;