diff --git a/src/basic/socket-util.c b/src/basic/socket-util.c index 568072a492..c98cd35d54 100644 --- a/src/basic/socket-util.c +++ b/src/basic/socket-util.c @@ -669,26 +669,6 @@ static const char* const netlink_family_table[] = { DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(netlink_family, int, INT_MAX); -static const char* const socket_address_bind_ipv6_only_table[_SOCKET_ADDRESS_BIND_IPV6_ONLY_MAX] = { - [SOCKET_ADDRESS_DEFAULT] = "default", - [SOCKET_ADDRESS_BOTH] = "both", - [SOCKET_ADDRESS_IPV6_ONLY] = "ipv6-only" -}; - -DEFINE_STRING_TABLE_LOOKUP(socket_address_bind_ipv6_only, SocketAddressBindIPv6Only); - -SocketAddressBindIPv6Only socket_address_bind_ipv6_only_or_bool_from_string(const char *n) { - int r; - - r = parse_boolean(n); - if (r > 0) - return SOCKET_ADDRESS_IPV6_ONLY; - if (r == 0) - return SOCKET_ADDRESS_BOTH; - - return socket_address_bind_ipv6_only_from_string(n); -} - bool sockaddr_equal(const union sockaddr_union *a, const union sockaddr_union *b) { assert(a); assert(b); diff --git a/src/basic/socket-util.h b/src/basic/socket-util.h index 6e937ffee9..b8cb834131 100644 --- a/src/basic/socket-util.h +++ b/src/basic/socket-util.h @@ -53,14 +53,6 @@ typedef struct SocketAddress { int protocol; } SocketAddress; -typedef enum SocketAddressBindIPv6Only { - SOCKET_ADDRESS_DEFAULT, - SOCKET_ADDRESS_BOTH, - SOCKET_ADDRESS_IPV6_ONLY, - _SOCKET_ADDRESS_BIND_IPV6_ONLY_MAX, - _SOCKET_ADDRESS_BIND_IPV6_ONLY_INVALID = -EINVAL, -} SocketAddressBindIPv6Only; - #define socket_address_family(a) ((a)->sockaddr.sa.sa_family) const char* socket_address_type_to_string(int t) _const_; @@ -74,19 +66,6 @@ static inline int socket_address_unlink(const SocketAddress *a) { bool socket_address_can_accept(const SocketAddress *a) _pure_; -int socket_address_listen( - const SocketAddress *a, - int flags, - int backlog, - SocketAddressBindIPv6Only only, - const char *bind_to_device, - bool reuse_port, - bool free_bind, - bool transparent, - mode_t directory_mode, - mode_t socket_mode, - const char *label); - int socket_address_verify(const SocketAddress *a, bool strict) _pure_; int socket_address_print(const SocketAddress *a, char **p); bool socket_address_matches_fd(const SocketAddress *a, int fd); @@ -108,10 +87,6 @@ int getsockname_pretty(int fd, char **ret); int socknameinfo_pretty(const struct sockaddr *sa, socklen_t salen, char **_ret); -const char* socket_address_bind_ipv6_only_to_string(SocketAddressBindIPv6Only b) _const_; -SocketAddressBindIPv6Only socket_address_bind_ipv6_only_from_string(const char *s) _pure_; -SocketAddressBindIPv6Only socket_address_bind_ipv6_only_or_bool_from_string(const char *s); - int netlink_family_to_string_alloc(int b, char **s); int netlink_family_from_string(const char *s) _pure_; diff --git a/src/core/socket.c b/src/core/socket.c index c8e737eaa7..3bb0149e62 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -1504,7 +1504,7 @@ static int socket_determine_selinux_label(Socket *s, char **ret) { static int socket_address_listen_do( Socket *s, const SocketAddress *address, - const char *label) { + const char *selinux_label) { assert(s); assert(address); @@ -1520,7 +1520,8 @@ static int socket_address_listen_do( s->transparent, s->directory_mode, s->socket_mode, - label); + selinux_label, + s->smack); } #define log_address_error_errno(u, address, error, fmt) \ diff --git a/src/core/socket.h b/src/core/socket.h index cec10dece9..74356e2325 100644 --- a/src/core/socket.h +++ b/src/core/socket.h @@ -6,6 +6,7 @@ #include "execute.h" #include "list.h" #include "pidref.h" +#include "socket-label.h" #include "socket-util.h" #include "unit.h" diff --git a/src/shared/socket-label.c b/src/shared/socket-label.c index 0e41f2674e..e16f9537a6 100644 --- a/src/shared/socket-label.c +++ b/src/shared/socket-label.c @@ -8,10 +8,34 @@ #include "fs-util.h" #include "log.h" #include "mkdir-label.h" +#include "parse-util.h" #include "selinux-util.h" +#include "smack-util.h" +#include "socket-label.h" #include "socket-util.h" +#include "string-table.h" #include "umask-util.h" +static const char* const socket_address_bind_ipv6_only_table[_SOCKET_ADDRESS_BIND_IPV6_ONLY_MAX] = { + [SOCKET_ADDRESS_DEFAULT] = "default", + [SOCKET_ADDRESS_BOTH] = "both", + [SOCKET_ADDRESS_IPV6_ONLY] = "ipv6-only" +}; + +DEFINE_STRING_TABLE_LOOKUP(socket_address_bind_ipv6_only, SocketAddressBindIPv6Only); + +SocketAddressBindIPv6Only socket_address_bind_ipv6_only_or_bool_from_string(const char *n) { + int r; + + r = parse_boolean(n); + if (r > 0) + return SOCKET_ADDRESS_IPV6_ONLY; + if (r == 0) + return SOCKET_ADDRESS_BOTH; + + return socket_address_bind_ipv6_only_from_string(n); +} + int socket_address_listen( const SocketAddress *a, int flags, @@ -23,7 +47,8 @@ int socket_address_listen( bool transparent, mode_t directory_mode, mode_t socket_mode, - const char *label) { + const char *selinux_label, + const char *smack_label) { _cleanup_close_ int fd = -EBADF; const char *p; @@ -38,20 +63,26 @@ int socket_address_listen( if (socket_address_family(a) == AF_INET6 && !socket_ipv6_is_supported()) return -EAFNOSUPPORT; - if (label) { - r = mac_selinux_create_socket_prepare(label); + if (selinux_label) { + r = mac_selinux_create_socket_prepare(selinux_label); if (r < 0) return r; } fd = RET_NERRNO(socket(socket_address_family(a), a->type | flags, a->protocol)); - if (label) + if (selinux_label) mac_selinux_create_socket_clear(); if (fd < 0) return fd; + if (smack_label) { + r = mac_smack_apply_fd(fd, SMACK_ATTR_ACCESS, smack_label); + if (r < 0) + log_warning_errno(r, "Failed to apply SMACK label for socket FD, ignoring: %m"); + } + if (socket_address_family(a) == AF_INET6 && only != SOCKET_ADDRESS_DEFAULT) { r = setsockopt_int(fd, IPPROTO_IPV6, IPV6_V6ONLY, only == SOCKET_ADDRESS_IPV6_ONLY); if (r < 0) @@ -107,6 +138,11 @@ int socket_address_listen( if (r < 0) return r; } + if (smack_label) { + r = mac_smack_apply(p, SMACK_ATTR_ACCESS, smack_label); + if (r < 0) + log_warning_errno(r, "Failed to apply SMACK label for socket path, ignoring: %m"); + } } else { if (bind(fd, &a->sockaddr.sa, a->size) < 0) return -errno; diff --git a/src/shared/socket-label.h b/src/shared/socket-label.h new file mode 100644 index 0000000000..cfcb20f187 --- /dev/null +++ b/src/shared/socket-label.h @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include "shared-forward.h" + +typedef enum SocketAddressBindIPv6Only { + SOCKET_ADDRESS_DEFAULT, + SOCKET_ADDRESS_BOTH, + SOCKET_ADDRESS_IPV6_ONLY, + _SOCKET_ADDRESS_BIND_IPV6_ONLY_MAX, + _SOCKET_ADDRESS_BIND_IPV6_ONLY_INVALID = -EINVAL, +} SocketAddressBindIPv6Only; + +const char* socket_address_bind_ipv6_only_to_string(SocketAddressBindIPv6Only b) _const_; +SocketAddressBindIPv6Only socket_address_bind_ipv6_only_from_string(const char *s) _pure_; +SocketAddressBindIPv6Only socket_address_bind_ipv6_only_or_bool_from_string(const char *s); + +int socket_address_listen( + const SocketAddress *a, + int flags, + int backlog, + SocketAddressBindIPv6Only only, + const char *bind_to_device, + bool reuse_port, + bool free_bind, + bool transparent, + mode_t directory_mode, + mode_t socket_mode, + const char *selinux_label, + const char *smack_label); diff --git a/src/shared/socket-netlink.c b/src/shared/socket-netlink.c index 771bf2f799..885606b6e0 100644 --- a/src/shared/socket-netlink.c +++ b/src/shared/socket-netlink.c @@ -15,6 +15,7 @@ #include "netlink-sock-diag.h" #include "netlink-util.h" #include "parse-util.h" +#include "socket-label.h" #include "socket-netlink.h" #include "socket-util.h" #include "string-util.h" @@ -183,8 +184,18 @@ int make_socket_fd(int log_level, const char* address, int type, int flags) { a.type = type; - fd = socket_address_listen(&a, type | flags, SOMAXCONN_DELUXE, SOCKET_ADDRESS_DEFAULT, - NULL, false, false, false, 0755, 0644, NULL); + fd = socket_address_listen( + &a, + type | flags, + SOMAXCONN_DELUXE, SOCKET_ADDRESS_DEFAULT, + /* bind_to_device= */ NULL, + /* reuse_port= */ false, + /* free_bind= */ false, + /* transparent= */ false, + 0755, + 0644, + /* selinux_label= */ NULL, + /* smack_label= */ NULL); if (fd < 0 || log_get_max_level() >= log_level) { _cleanup_free_ char *p = NULL; diff --git a/src/test/test-tables.c b/src/test/test-tables.c index 41b6cd6136..95ceb0e5ae 100644 --- a/src/test/test-tables.c +++ b/src/test/test-tables.c @@ -29,6 +29,7 @@ #include "service.h" #include "show-status.h" #include "socket.h" +#include "socket-label.h" #include "socket-util.h" #include "swap.h" #include "test-tables.h"