diff --git a/src/basic/alloc-util.h b/src/basic/alloc-util.h index ebe42889ea..2a6deb12ca 100644 --- a/src/basic/alloc-util.h +++ b/src/basic/alloc-util.h @@ -46,6 +46,21 @@ static inline void *mfree(void *memory) { void* memdup(const void *p, size_t l) _alloc_(2); void* memdup_suffix0(const void *p, size_t l) _alloc_(2); +#define memdupa(p, l) \ + ({ \ + void *_q_; \ + _q_ = alloca(l); \ + memcpy(_q_, p, l); \ + }) + +#define memdupa_suffix0(p, l) \ + ({ \ + void *_q_; \ + _q_ = alloca(l + 1); \ + ((uint8_t*) _q_)[l] = 0; \ + memcpy(_q_, p, l); \ + }) + static inline void freep(void *p) { free(*(void**) p); } diff --git a/src/basic/socket-label.c b/src/basic/socket-label.c index 35e14e567c..2698d59aea 100644 --- a/src/basic/socket-label.c +++ b/src/basic/socket-label.c @@ -35,7 +35,7 @@ int socket_address_listen( _cleanup_close_ int fd = -1; const char *p; - int r, one; + int r; assert(a); @@ -74,26 +74,22 @@ int socket_address_listen( return -errno; if (reuse_port) { - one = 1; - if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &one, sizeof(one)) < 0) + if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &const_int_one, sizeof(const_int_one)) < 0) log_warning_errno(errno, "SO_REUSEPORT failed: %m"); } if (free_bind) { - one = 1; - if (setsockopt(fd, IPPROTO_IP, IP_FREEBIND, &one, sizeof(one)) < 0) + if (setsockopt(fd, IPPROTO_IP, IP_FREEBIND, &const_int_one, sizeof(const_int_one)) < 0) log_warning_errno(errno, "IP_FREEBIND failed: %m"); } if (transparent) { - one = 1; - if (setsockopt(fd, IPPROTO_IP, IP_TRANSPARENT, &one, sizeof(one)) < 0) + if (setsockopt(fd, IPPROTO_IP, IP_TRANSPARENT, &const_int_one, sizeof(const_int_one)) < 0) log_warning_errno(errno, "IP_TRANSPARENT failed: %m"); } } - one = 1; - if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)) < 0) + if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &const_int_one, sizeof(const_int_one)) < 0) return -errno; p = socket_address_get_path(a); diff --git a/src/basic/socket-util.c b/src/basic/socket-util.c index 4e8b2baf82..dd22d30fca 100644 --- a/src/basic/socket-util.c +++ b/src/basic/socket-util.c @@ -57,8 +57,9 @@ int socket_address_parse(SocketAddress *a, const char *s) { assert(a); assert(s); - zero(*a); - a->type = SOCK_STREAM; + *a = (SocketAddress) { + .type = SOCK_STREAM, + }; if (*s == '[') { uint16_t port; @@ -96,7 +97,9 @@ int socket_address_parse(SocketAddress *a, const char *s) { size_t l; l = strlen(s); - if (l >= sizeof(a->sockaddr.un.sun_path)) + if (l >= sizeof(a->sockaddr.un.sun_path)) /* Note that we refuse non-NUL-terminated sockets when + * parsing (the kernel itself is less strict here in what it + * accepts) */ return -EINVAL; a->sockaddr.un.sun_family = AF_UNIX; @@ -108,7 +111,11 @@ int socket_address_parse(SocketAddress *a, const char *s) { size_t l; l = strlen(s+1); - if (l >= sizeof(a->sockaddr.un.sun_path) - 1) + if (l >= sizeof(a->sockaddr.un.sun_path) - 1) /* Note that we refuse non-NUL-terminate sockets here + * when parsing, even though abstract namespace sockets + * explicitly allow embedded NUL bytes and don't consider + * them special. But it's simply annoying to debug such + * sockets. */ return -EINVAL; a->sockaddr.un.sun_family = AF_UNIX; @@ -286,19 +293,28 @@ int socket_address_verify(const SocketAddress *a) { case AF_UNIX: if (a->size < offsetof(struct sockaddr_un, sun_path)) return -EINVAL; + if (a->size > sizeof(struct sockaddr_un)+1) /* Allow one extra byte, since getsockname() on Linux will + * append a NUL byte if we have path sockets that are above + * sun_path' full size */ + return -EINVAL; - if (a->size > offsetof(struct sockaddr_un, sun_path)) { + if (a->size > offsetof(struct sockaddr_un, sun_path) && + a->sockaddr.un.sun_path[0] != 0) { /* Only validate file system sockets here */ - if (a->sockaddr.un.sun_path[0] != 0) { - char *e; - - /* path */ - e = memchr(a->sockaddr.un.sun_path, 0, sizeof(a->sockaddr.un.sun_path)); - if (!e) - return -EINVAL; + const char *e; + e = memchr(a->sockaddr.un.sun_path, 0, sizeof(a->sockaddr.un.sun_path)); + if (e) { + /* If there's an embedded NUL byte, make sure the size of the socket addresses matches it */ if (a->size != offsetof(struct sockaddr_un, sun_path) + (e - a->sockaddr.un.sun_path) + 1) return -EINVAL; + } else { + /* If there's no embedded NUL byte, then then the size needs to match the whole + * structure or the structure with one extra NUL byte suffixed. (Yeah, Linux is awful, + * and considers both equivalent: getsockname() even extends sockaddr_un beyond its + * size if the path is non NUL terminated.)*/ + if (!IN_SET(a->size, sizeof(a->sockaddr.un.sun_path), sizeof(a->sockaddr.un.sun_path)+1)) + return -EINVAL; } } @@ -482,6 +498,10 @@ const char* socket_address_get_path(const SocketAddress *a) { if (a->sockaddr.un.sun_path[0] == 0) return NULL; + /* Note that this is only safe because we know that there's an extra NUL byte after the sockaddr_un + * structure. On Linux AF_UNIX file system socket addresses don't have to be NUL terminated if they take up the + * full sun_path space. */ + assert_cc(sizeof(union sockaddr_union) >= sizeof(struct sockaddr_un)+1); return a->sockaddr.un.sun_path; } @@ -747,21 +767,6 @@ int socknameinfo_pretty(union sockaddr_union *sa, socklen_t salen, char **_ret) return 0; } -int socket_address_unlink(SocketAddress *a) { - assert(a); - - if (socket_address_family(a) != AF_UNIX) - return 0; - - if (a->sockaddr.un.sun_path[0] == 0) - return 0; - - if (unlink(a->sockaddr.un.sun_path) < 0) - return -errno; - - return 1; -} - static const char* const netlink_family_table[] = { [NETLINK_ROUTE] = "route", [NETLINK_FIREWALL] = "firewall", @@ -1246,3 +1251,71 @@ int socket_ioctl_fd(void) { return fd; } + +int sockaddr_un_unlink(const struct sockaddr_un *sa) { + const char *p, * nul; + + assert(sa); + + if (sa->sun_family != AF_UNIX) + return -EPROTOTYPE; + + if (sa->sun_path[0] == 0) /* Nothing to do for abstract sockets */ + return 0; + + /* The path in .sun_path is not necessarily NUL terminated. Let's fix that. */ + nul = memchr(sa->sun_path, 0, sizeof(sa->sun_path)); + if (nul) + p = sa->sun_path; + else + p = memdupa_suffix0(sa->sun_path, sizeof(sa->sun_path)); + + if (unlink(p) < 0) + return -errno; + + return 1; +} + +int sockaddr_un_set_path(struct sockaddr_un *ret, const char *path) { + size_t l; + + assert(ret); + assert(path); + + /* Initialize ret->sun_path from the specified argument. This will interpret paths starting with '@' as + * abstract namespace sockets, and those starting with '/' as regular filesystem sockets. It won't accept + * anything else (i.e. no relative paths), to avoid ambiguities. Note that this function cannot be used to + * reference paths in the abstract namespace that include NUL bytes in the name. */ + + l = strlen(path); + if (l == 0) + return -EINVAL; + if (!IN_SET(path[0], '/', '@')) + return -EINVAL; + if (path[1] == 0) + return -EINVAL; + + /* Don't allow paths larger than the space in sockaddr_un. Note that we are a tiny bit more restrictive than + * the kernel is: we insist on NUL termination (both for abstract namespace and regular file system socket + * addresses!), which the kernel doesn't. We do this to reduce chance of incompatibility with other apps that + * do not expect non-NUL terminated file system path*/ + if (l+1 > sizeof(ret->sun_path)) + return -EINVAL; + + *ret = (struct sockaddr_un) { + .sun_family = AF_UNIX, + }; + + if (path[0] == '@') { + /* Abstract namespace socket */ + memcpy(ret->sun_path + 1, path + 1, l); /* copy *with* trailing NUL byte */ + return (int) (offsetof(struct sockaddr_un, sun_path) + l); /* 🔥 *don't* 🔥 include trailing NUL in size */ + + } else { + assert(path[0] == '/'); + + /* File system socket */ + memcpy(ret->sun_path, path, l + 1); /* copy *with* trailing NUL byte */ + return (int) (offsetof(struct sockaddr_un, sun_path) + l + 1); /* include trailing NUL in size */ + } +} diff --git a/src/basic/socket-util.h b/src/basic/socket-util.h index 82781a0de1..d2e00f2f64 100644 --- a/src/basic/socket-util.h +++ b/src/basic/socket-util.h @@ -71,7 +71,12 @@ int socket_address_parse_and_warn(SocketAddress *a, const char *s); int socket_address_parse_netlink(SocketAddress *a, const char *s); int socket_address_print(const SocketAddress *a, char **p); int socket_address_verify(const SocketAddress *a) _pure_; -int socket_address_unlink(SocketAddress *a); + +int sockaddr_un_unlink(const struct sockaddr_un *sa); + +static inline int socket_address_unlink(const SocketAddress *a) { + return socket_address_family(a) == AF_UNIX ? sockaddr_un_unlink(&a->sockaddr.un) : 0; +} bool socket_address_can_accept(const SocketAddress *a) _pure_; @@ -179,7 +184,9 @@ struct cmsghdr* cmsg_find(struct msghdr *mh, int level, int type, socklen_t leng offsetof(struct sockaddr_un, sun_path) + \ (_sa->sun_path[0] == 0 ? \ 1 + strnlen(_sa->sun_path+1, sizeof(_sa->sun_path)-1) : \ - strnlen(_sa->sun_path, sizeof(_sa->sun_path))); \ + strnlen(_sa->sun_path, sizeof(_sa->sun_path))+1); \ }) int socket_ioctl_fd(void); + +int sockaddr_un_set_path(struct sockaddr_un *ret, const char *path); diff --git a/src/basic/strxcpyx.c b/src/basic/strxcpyx.c index 6277f56b80..9210277cde 100644 --- a/src/basic/strxcpyx.c +++ b/src/basic/strxcpyx.c @@ -31,12 +31,11 @@ size_t strpcpy(char **dest, size_t size, const char *src) { if (size > 1) *dest = mempcpy(*dest, src, size-1); size = 0; - } else { - if (len > 0) { - *dest = mempcpy(*dest, src, len); - size -= len; - } + } else if (len > 0) { + *dest = mempcpy(*dest, src, len); + size -= len; } + *dest[0] = '\0'; return size; } @@ -56,9 +55,8 @@ size_t strpcpyf(char **dest, size_t size, const char *src, ...) { if (i < (int)size) { *dest += i; size -= i; - } else { + } else size = 0; - } va_end(va); return size; } @@ -73,7 +71,7 @@ size_t strpcpyl(char **dest, size_t size, const char *src, ...) { do { size = strpcpy(dest, size, src); src = va_arg(va, char *); - } while (src != NULL); + } while (src); va_end(va); return size; } @@ -100,7 +98,7 @@ size_t strscpyl(char *dest, size_t size, const char *src, ...) { do { size = strpcpy(&s, size, src); src = va_arg(va, char *); - } while (src != NULL); + } while (src); va_end(va); return size; diff --git a/src/basic/util.c b/src/basic/util.c index 0da963f4af..c4c66cca53 100644 --- a/src/basic/util.c +++ b/src/basic/util.c @@ -51,6 +51,9 @@ int saved_argc = 0; char **saved_argv = NULL; static int saved_in_initrd = -1; +const int const_int_zero = 0; +const int const_int_one = 1; + size_t page_size(void) { static thread_local size_t pgsz = 0; long r; diff --git a/src/basic/util.h b/src/basic/util.h index 8cba4ed726..32d9380bd9 100644 --- a/src/basic/util.h +++ b/src/basic/util.h @@ -232,3 +232,6 @@ int version(void); int str_verscmp(const char *s1, const char *s2); void disable_coredumps(void); + +extern const int const_int_zero; +extern const int const_int_one; diff --git a/src/core/dbus.c b/src/core/dbus.c index bf5917696e..3ffb53cb6e 100644 --- a/src/core/dbus.c +++ b/src/core/dbus.c @@ -974,12 +974,9 @@ int bus_init_system(Manager *m) { int bus_init_private(Manager *m) { _cleanup_close_ int fd = -1; - union sockaddr_union sa = { - .un.sun_family = AF_UNIX - }; + union sockaddr_union sa = {}; sd_event_source *s; - socklen_t salen; - int r; + int r, salen; assert(m); @@ -992,27 +989,24 @@ int bus_init_private(Manager *m) { if (getpid_cached() != 1) return 0; - strcpy(sa.un.sun_path, "/run/systemd/private"); - salen = SOCKADDR_UN_LEN(sa.un); + salen = sockaddr_un_set_path(&sa.un, "/run/systemd/private"); } else { - size_t left = sizeof(sa.un.sun_path); - char *p = sa.un.sun_path; - const char *e; + const char *e, *joined; e = secure_getenv("XDG_RUNTIME_DIR"); if (!e) { - log_error("Failed to determine XDG_RUNTIME_DIR"); + log_error("XDG_RUNTIME_DIR is not set, refusing."); return -EHOSTDOWN; } - left = strpcpy(&p, left, e); - left = strpcpy(&p, left, "/systemd/private"); - - salen = sizeof(sa.un) - left; + joined = strjoina(e, "/systemd/private"); + salen = sockaddr_un_set_path(&sa.un, joined); } + if (salen < 0) + return log_error_errno(salen, "Can't set path for AF_UNIX socket to bind to: %m"); (void) mkdir_parents_label(sa.un.sun_path, 0755); - (void) unlink(sa.un.sun_path); + (void) sockaddr_un_unlink(&sa.un); fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0); if (fd < 0) @@ -1035,9 +1029,8 @@ int bus_init_private(Manager *m) { (void) sd_event_source_set_description(s, "bus-connection"); - m->private_listen_fd = fd; + m->private_listen_fd = TAKE_FD(fd); m->private_listen_event_source = s; - fd = -1; log_debug("Successfully created private D-Bus server."); diff --git a/src/core/execute.c b/src/core/execute.c index 0ef5d2d212..b6896a0a77 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -379,10 +379,9 @@ static int open_terminal_as(const char *path, int flags, int nfd) { } static int acquire_path(const char *path, int flags, mode_t mode) { - union sockaddr_union sa = { - .sa.sa_family = AF_UNIX, - }; - int fd, r; + union sockaddr_union sa = {}; + _cleanup_close_ int fd = -1; + int r, salen; assert(path); @@ -391,11 +390,11 @@ static int acquire_path(const char *path, int flags, mode_t mode) { fd = open(path, flags|O_NOCTTY, mode); if (fd >= 0) - return fd; + return TAKE_FD(fd); if (errno != ENXIO) /* ENXIO is returned when we try to open() an AF_UNIX file system socket on Linux */ return -errno; - if (strlen(path) > sizeof(sa.un.sun_path)) /* Too long, can't be a UNIX socket */ + if (strlen(path) >= sizeof(sa.un.sun_path)) /* Too long, can't be a UNIX socket */ return -ENXIO; /* So, it appears the specified path could be an AF_UNIX socket. Let's see if we can connect to it. */ @@ -404,25 +403,24 @@ static int acquire_path(const char *path, int flags, mode_t mode) { if (fd < 0) return -errno; - strncpy(sa.un.sun_path, path, sizeof(sa.un.sun_path)); - if (connect(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0) { - safe_close(fd); + salen = sockaddr_un_set_path(&sa.un, path); + if (salen < 0) + return salen; + + if (connect(fd, &sa.sa, salen) < 0) return errno == EINVAL ? -ENXIO : -errno; /* Propagate initial error if we get EINVAL, i.e. we have * indication that his wasn't an AF_UNIX socket after all */ - } if ((flags & O_ACCMODE) == O_RDONLY) r = shutdown(fd, SHUT_WR); else if ((flags & O_ACCMODE) == O_WRONLY) r = shutdown(fd, SHUT_RD); else - return fd; - if (r < 0) { - safe_close(fd); + return TAKE_FD(fd); + if (r < 0) return -errno; - } - return fd; + return TAKE_FD(fd); } static int fixup_input( diff --git a/src/core/manager.c b/src/core/manager.c index 971faef90a..7b6a84108a 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -872,10 +872,8 @@ static int manager_setup_notify(Manager *m) { if (m->notify_fd < 0) { _cleanup_close_ int fd = -1; - union sockaddr_union sa = { - .sa.sa_family = AF_UNIX, - }; - static const int one = 1; + union sockaddr_union sa = {}; + int salen; /* First free all secondary fields */ m->notify_socket = mfree(m->notify_socket); @@ -891,15 +889,18 @@ static int manager_setup_notify(Manager *m) { if (!m->notify_socket) return log_oom(); + salen = sockaddr_un_set_path(&sa.un, m->notify_socket); + if (salen < 0) + return log_error_errno(salen, "Notify socket '%s' not valid for AF_UNIX socket address, refusing.", m->notify_socket); + (void) mkdir_parents_label(m->notify_socket, 0755); - (void) unlink(m->notify_socket); + (void) sockaddr_un_unlink(&sa.un); - strncpy(sa.un.sun_path, m->notify_socket, sizeof(sa.un.sun_path)); - r = bind(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)); + r = bind(fd, &sa.sa, salen); if (r < 0) - return log_error_errno(errno, "bind(%s) failed: %m", sa.un.sun_path); + return log_error_errno(errno, "bind(%s) failed: %m", m->notify_socket); - r = setsockopt(fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one)); + r = setsockopt(fd, SOL_SOCKET, SO_PASSCRED, &const_int_one, sizeof(const_int_one)); if (r < 0) return log_error_errno(errno, "SO_PASSCRED failed: %m"); @@ -970,7 +971,7 @@ static int manager_setup_cgroups_agent(Manager *m) { fd_inc_rcvbuf(fd, CGROUPS_AGENT_RCVBUF_SIZE); - (void) unlink(sa.un.sun_path); + (void) sockaddr_un_unlink(&sa.un); /* Only allow root to connect to this socket */ RUN_WITH_UMASK(0077) @@ -978,8 +979,7 @@ static int manager_setup_cgroups_agent(Manager *m) { if (r < 0) return log_error_errno(errno, "bind(%s) failed: %m", sa.un.sun_path); - m->cgroups_agent_fd = fd; - fd = -1; + m->cgroups_agent_fd = TAKE_FD(fd); } if (!m->cgroups_agent_event_source) { diff --git a/src/core/socket.c b/src/core/socket.c index 06e9956157..f0f6a83a19 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -1014,8 +1014,7 @@ static void socket_apply_socket_options(Socket *s, int fd) { assert(fd >= 0); if (s->keep_alive) { - int one = 1; - if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &one, sizeof(one)) < 0) + if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &const_int_one, sizeof(const_int_one)) < 0) log_unit_warning_errno(UNIT(s), errno, "SO_KEEPALIVE failed: %m"); } @@ -1044,32 +1043,27 @@ static void socket_apply_socket_options(Socket *s, int fd) { } if (s->no_delay) { - int one = 1; - if (s->socket_protocol == IPPROTO_SCTP) { - if (setsockopt(fd, SOL_SCTP, SCTP_NODELAY, &one, sizeof(one)) < 0) + if (setsockopt(fd, SOL_SCTP, SCTP_NODELAY, &const_int_one, sizeof(const_int_one)) < 0) log_unit_warning_errno(UNIT(s), errno, "SCTP_NODELAY failed: %m"); } else { - if (setsockopt(fd, SOL_TCP, TCP_NODELAY, &one, sizeof(one)) < 0) + if (setsockopt(fd, SOL_TCP, TCP_NODELAY, &const_int_one, sizeof(const_int_one)) < 0) log_unit_warning_errno(UNIT(s), errno, "TCP_NODELAY failed: %m"); } } if (s->broadcast) { - int one = 1; - if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &one, sizeof(one)) < 0) + if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &const_int_one, sizeof(const_int_one)) < 0) log_unit_warning_errno(UNIT(s), errno, "SO_BROADCAST failed: %m"); } if (s->pass_cred) { - int one = 1; - if (setsockopt(fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one)) < 0) + if (setsockopt(fd, SOL_SOCKET, SO_PASSCRED, &const_int_one, sizeof(const_int_one)) < 0) log_unit_warning_errno(UNIT(s), errno, "SO_PASSCRED failed: %m"); } if (s->pass_sec) { - int one = 1; - if (setsockopt(fd, SOL_SOCKET, SO_PASSSEC, &one, sizeof(one)) < 0) + if (setsockopt(fd, SOL_SOCKET, SO_PASSSEC, &const_int_one, sizeof(const_int_one)) < 0) log_unit_warning_errno(UNIT(s), errno, "SO_PASSSEC failed: %m"); } diff --git a/src/fsck/fsck.c b/src/fsck/fsck.c index 132714fddd..9030708db0 100644 --- a/src/fsck/fsck.c +++ b/src/fsck/fsck.c @@ -247,20 +247,17 @@ static int fsck_progress_socket(void) { .un.sun_path = "/run/systemd/fsck.progress", }; - int fd, r; + _cleanup_close_ int fd = -1; fd = socket(AF_UNIX, SOCK_STREAM, 0); if (fd < 0) return log_warning_errno(errno, "socket(): %m"); - if (connect(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0) { - r = log_full_errno(IN_SET(errno, ECONNREFUSED, ENOENT) ? LOG_DEBUG : LOG_WARNING, - errno, "Failed to connect to progress socket %s, ignoring: %m", sa.un.sun_path); - safe_close(fd); - return r; - } + if (connect(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0) + return log_full_errno(IN_SET(errno, ECONNREFUSED, ENOENT) ? LOG_DEBUG : LOG_WARNING, + errno, "Failed to connect to progress socket %s, ignoring: %m", sa.un.sun_path); - return fd; + return TAKE_FD(fd); } int main(int argc, char *argv[]) { diff --git a/src/import/importd.c b/src/import/importd.c index 04563fb098..7dd00b7545 100644 --- a/src/import/importd.c +++ b/src/import/importd.c @@ -584,7 +584,6 @@ static int manager_new(Manager **ret) { .un.sun_family = AF_UNIX, .un.sun_path = "/run/systemd/import/notify", }; - static const int one = 1; int r; assert(ret); @@ -608,12 +607,12 @@ static int manager_new(Manager **ret) { return -errno; (void) mkdir_parents_label(sa.un.sun_path, 0755); - (void) unlink(sa.un.sun_path); + (void) sockaddr_un_unlink(&sa.un); if (bind(m->notify_fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0) return -errno; - if (setsockopt(m->notify_fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one)) < 0) + if (setsockopt(m->notify_fd, SOL_SOCKET, SO_PASSCRED, &const_int_one, sizeof(const_int_one)) < 0) return -errno; r = sd_event_add_io(m->event, &m->notify_event_source, m->notify_fd, EPOLLIN, manager_on_notify, m); diff --git a/src/journal/journald-audit.c b/src/journal/journald-audit.c index 68d889b5fb..0e0465d879 100644 --- a/src/journal/journald-audit.c +++ b/src/journal/journald-audit.c @@ -497,7 +497,6 @@ static int enable_audit(int fd, bool b) { } int server_open_audit(Server *s) { - static const int one = 1; int r; if (s->audit_fd < 0) { @@ -528,7 +527,7 @@ int server_open_audit(Server *s) { } else (void) fd_nonblock(s->audit_fd, true); - r = setsockopt(s->audit_fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one)); + r = setsockopt(s->audit_fd, SOL_SOCKET, SO_PASSCRED, &const_int_one, sizeof(const_int_one)); if (r < 0) return log_error_errno(errno, "Failed to set SO_PASSCRED on audit socket: %m"); diff --git a/src/journal/journald-native.c b/src/journal/journald-native.c index 44610a4b3b..208758785d 100644 --- a/src/journal/journald-native.c +++ b/src/journal/journald-native.c @@ -443,7 +443,6 @@ int server_open_native_socket(Server*s) { .un.sun_family = AF_UNIX, .un.sun_path = "/run/systemd/journal/socket", }; - static const int one = 1; int r; assert(s); @@ -453,7 +452,7 @@ int server_open_native_socket(Server*s) { if (s->native_fd < 0) return log_error_errno(errno, "socket() failed: %m"); - (void) unlink(sa.un.sun_path); + (void) sockaddr_un_unlink(&sa.un); r = bind(s->native_fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)); if (r < 0) @@ -463,19 +462,19 @@ int server_open_native_socket(Server*s) { } else (void) fd_nonblock(s->native_fd, true); - r = setsockopt(s->native_fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one)); + r = setsockopt(s->native_fd, SOL_SOCKET, SO_PASSCRED, &const_int_one, sizeof(const_int_one)); if (r < 0) return log_error_errno(errno, "SO_PASSCRED failed: %m"); #if HAVE_SELINUX if (mac_selinux_use()) { - r = setsockopt(s->native_fd, SOL_SOCKET, SO_PASSSEC, &one, sizeof(one)); + r = setsockopt(s->native_fd, SOL_SOCKET, SO_PASSSEC, &const_int_one, sizeof(const_int_one)); if (r < 0) log_warning_errno(errno, "SO_PASSSEC failed: %m"); } #endif - r = setsockopt(s->native_fd, SOL_SOCKET, SO_TIMESTAMP, &one, sizeof(one)); + r = setsockopt(s->native_fd, SOL_SOCKET, SO_TIMESTAMP, &const_int_one, sizeof(const_int_one)); if (r < 0) return log_error_errno(errno, "SO_TIMESTAMP failed: %m"); diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c index 4f63907ebf..c980b7564b 100644 --- a/src/journal/journald-server.c +++ b/src/journal/journald-server.c @@ -1595,11 +1595,9 @@ static int dispatch_watchdog(sd_event_source *es, uint64_t usec, void *userdata) } static int server_connect_notify(Server *s) { - union sockaddr_union sa = { - .un.sun_family = AF_UNIX, - }; + union sockaddr_union sa = {}; const char *e; - int r; + int r, salen; assert(s); assert(s->notify_fd < 0); @@ -1628,15 +1626,9 @@ static int server_connect_notify(Server *s) { if (!e) return 0; - if (!IN_SET(e[0], '@', '/') || e[1] == 0) { - log_error("NOTIFY_SOCKET set to an invalid value: %s", e); - return -EINVAL; - } - - if (strlen(e) > sizeof(sa.un.sun_path)) { - log_error("NOTIFY_SOCKET path too long: %s", e); - return -EINVAL; - } + salen = sockaddr_un_set_path(&sa.un, e); + if (salen < 0) + return log_error_errno(salen, "NOTIFY_SOCKET set to invalid value '%s': %m", e); s->notify_fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0); if (s->notify_fd < 0) @@ -1644,11 +1636,7 @@ static int server_connect_notify(Server *s) { (void) fd_inc_sndbuf(s->notify_fd, NOTIFY_SNDBUF_SIZE); - strncpy(sa.un.sun_path, e, sizeof(sa.un.sun_path)); - if (sa.un.sun_path[0] == '@') - sa.un.sun_path[0] = 0; - - r = connect(s->notify_fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)); + r = connect(s->notify_fd, &sa.sa, salen); if (r < 0) return log_error_errno(errno, "Failed to connect to notify socket: %m"); diff --git a/src/journal/journald-stream.c b/src/journal/journald-stream.c index 267e63f4a2..502bd6f51b 100644 --- a/src/journal/journald-stream.c +++ b/src/journal/journald-stream.c @@ -793,7 +793,7 @@ int server_open_stdout_socket(Server *s) { if (s->stdout_fd < 0) return log_error_errno(errno, "socket() failed: %m"); - (void) unlink(sa.un.sun_path); + (void) sockaddr_un_unlink(&sa.un); r = bind(s->stdout_fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)); if (r < 0) diff --git a/src/journal/journald-syslog.c b/src/journal/journald-syslog.c index 46cc110f1c..e347f8bf5d 100644 --- a/src/journal/journald-syslog.c +++ b/src/journal/journald-syslog.c @@ -447,7 +447,6 @@ int server_open_syslog_socket(Server *s) { .un.sun_family = AF_UNIX, .un.sun_path = "/run/systemd/journal/dev-log", }; - static const int one = 1; int r; assert(s); @@ -457,7 +456,7 @@ int server_open_syslog_socket(Server *s) { if (s->syslog_fd < 0) return log_error_errno(errno, "socket() failed: %m"); - (void) unlink(sa.un.sun_path); + (void) sockaddr_un_unlink(&sa.un); r = bind(s->syslog_fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)); if (r < 0) @@ -467,19 +466,19 @@ int server_open_syslog_socket(Server *s) { } else (void) fd_nonblock(s->syslog_fd, true); - r = setsockopt(s->syslog_fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one)); + r = setsockopt(s->syslog_fd, SOL_SOCKET, SO_PASSCRED, &const_int_one, sizeof(const_int_one)); if (r < 0) return log_error_errno(errno, "SO_PASSCRED failed: %m"); #if HAVE_SELINUX if (mac_selinux_use()) { - r = setsockopt(s->syslog_fd, SOL_SOCKET, SO_PASSSEC, &one, sizeof(one)); + r = setsockopt(s->syslog_fd, SOL_SOCKET, SO_PASSSEC, &const_int_one, sizeof(const_int_one)); if (r < 0) log_warning_errno(errno, "SO_PASSSEC failed: %m"); } #endif - r = setsockopt(s->syslog_fd, SOL_SOCKET, SO_TIMESTAMP, &one, sizeof(one)); + r = setsockopt(s->syslog_fd, SOL_SOCKET, SO_TIMESTAMP, &const_int_one, sizeof(const_int_one)); if (r < 0) return log_error_errno(errno, "SO_TIMESTAMP failed: %m"); diff --git a/src/libsystemd-network/dhcp-network.c b/src/libsystemd-network/dhcp-network.c index cf59f14958..aa92376ee8 100644 --- a/src/libsystemd-network/dhcp-network.c +++ b/src/libsystemd-network/dhcp-network.c @@ -78,7 +78,7 @@ static int _bind_raw_socket(int ifindex, union sockaddr_union *link, .filter = filter }; _cleanup_close_ int s = -1; - int r, on = 1; + int r; assert(ifindex > 0); assert(link); @@ -87,7 +87,7 @@ static int _bind_raw_socket(int ifindex, union sockaddr_union *link, if (s < 0) return -errno; - r = setsockopt(s, SOL_PACKET, PACKET_AUXDATA, &on, sizeof(on)); + r = setsockopt(s, SOL_PACKET, PACKET_AUXDATA, &const_int_one, sizeof(const_int_one)); if (r < 0) return -errno; @@ -149,7 +149,7 @@ int dhcp_network_bind_udp_socket(int ifindex, be32_t address, uint16_t port) { }; _cleanup_close_ int s = -1; char ifname[IF_NAMESIZE] = ""; - int r, on = 1, tos = IPTOS_CLASS_CS6; + int r, tos = IPTOS_CLASS_CS6; s = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0); if (s < 0) @@ -159,7 +159,7 @@ int dhcp_network_bind_udp_socket(int ifindex, be32_t address, uint16_t port) { if (r < 0) return -errno; - r = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); + r = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &const_int_one, sizeof(const_int_one)); if (r < 0) return -errno; @@ -173,16 +173,16 @@ int dhcp_network_bind_udp_socket(int ifindex, be32_t address, uint16_t port) { } if (address == INADDR_ANY) { - r = setsockopt(s, IPPROTO_IP, IP_PKTINFO, &on, sizeof(on)); + r = setsockopt(s, IPPROTO_IP, IP_PKTINFO, &const_int_one, sizeof(const_int_one)); if (r < 0) return -errno; - r = setsockopt(s, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)); + r = setsockopt(s, SOL_SOCKET, SO_BROADCAST, &const_int_one, sizeof(const_int_one)); if (r < 0) return -errno; } else { - r = setsockopt(s, IPPROTO_IP, IP_FREEBIND, &on, sizeof(on)); + r = setsockopt(s, IPPROTO_IP, IP_FREEBIND, &const_int_one, sizeof(const_int_one)); if (r < 0) return -errno; } diff --git a/src/libsystemd-network/dhcp6-network.c b/src/libsystemd-network/dhcp6-network.c index 78cd383669..406b1efca4 100644 --- a/src/libsystemd-network/dhcp6-network.c +++ b/src/libsystemd-network/dhcp6-network.c @@ -25,7 +25,7 @@ int dhcp6_network_bind_udp_socket(int index, struct in6_addr *local_address) { .in6.sin6_scope_id = index, }; _cleanup_close_ int s = -1; - int r, off = 0, on = 1; + int r; assert(index > 0); assert(local_address); @@ -36,15 +36,15 @@ int dhcp6_network_bind_udp_socket(int index, struct in6_addr *local_address) { if (s < 0) return -errno; - r = setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)); + r = setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &const_int_one, sizeof(const_int_one)); if (r < 0) return -errno; - r = setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &off, sizeof(off)); + r = setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &const_int_zero, sizeof(const_int_zero)); if (r < 0) return -errno; - r = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); + r = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &const_int_one, sizeof(const_int_one)); if (r < 0) return -errno; diff --git a/src/libsystemd-network/icmp6-util.c b/src/libsystemd-network/icmp6-util.c index 8bee24e568..c27a92c6ca 100644 --- a/src/libsystemd-network/icmp6-util.c +++ b/src/libsystemd-network/icmp6-util.c @@ -33,7 +33,7 @@ static int icmp6_bind_router_message(const struct icmp6_filter *filter, int index = mreq->ipv6mr_interface; _cleanup_close_ int s = -1; char ifname[IF_NAMESIZE] = ""; - static const int zero = 0, one = 1, hops = 255; + static const int hops = 255; int r; s = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC | SOCK_NONBLOCK, IPPROTO_ICMPV6); @@ -56,7 +56,7 @@ static int icmp6_bind_router_message(const struct icmp6_filter *filter, if (r < 0) return -errno; - r = setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &zero, sizeof(zero)); + r = setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &const_int_zero, sizeof(const_int_zero)); if (r < 0) return -errno; @@ -68,11 +68,11 @@ static int icmp6_bind_router_message(const struct icmp6_filter *filter, if (r < 0) return -errno; - r = setsockopt(s, SOL_IPV6, IPV6_RECVHOPLIMIT, &one, sizeof(one)); + r = setsockopt(s, SOL_IPV6, IPV6_RECVHOPLIMIT, &const_int_one, sizeof(const_int_one)); if (r < 0) return -errno; - r = setsockopt(s, SOL_SOCKET, SO_TIMESTAMP, &one, sizeof(one)); + r = setsockopt(s, SOL_SOCKET, SO_TIMESTAMP, &const_int_one, sizeof(const_int_one)); if (r < 0) return -errno; diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c index 1437df6cf3..85558d9c05 100644 --- a/src/libsystemd/sd-bus/sd-bus.c +++ b/src/libsystemd/sd-bus/sd-bus.c @@ -730,20 +730,28 @@ static int parse_unix_address(sd_bus *b, const char **p, char **guid) { if (path) { l = strlen(path); - if (l > sizeof(b->sockaddr.un.sun_path)) + if (l >= sizeof(b->sockaddr.un.sun_path)) /* We insist on NUL termination */ return -E2BIG; - b->sockaddr.un.sun_family = AF_UNIX; - strncpy(b->sockaddr.un.sun_path, path, sizeof(b->sockaddr.un.sun_path)); - b->sockaddr_size = offsetof(struct sockaddr_un, sun_path) + l; - } else if (abstract) { + b->sockaddr.un = (struct sockaddr_un) { + .sun_family = AF_UNIX, + }; + + memcpy(b->sockaddr.un.sun_path, path, l); + b->sockaddr_size = offsetof(struct sockaddr_un, sun_path) + l + 1; + + } else { + assert(abstract); + l = strlen(abstract); - if (l > sizeof(b->sockaddr.un.sun_path) - 1) + if (l >= sizeof(b->sockaddr.un.sun_path) - 1) /* We insist on NUL termination */ return -E2BIG; - b->sockaddr.un.sun_family = AF_UNIX; - b->sockaddr.un.sun_path[0] = 0; - strncpy(b->sockaddr.un.sun_path+1, abstract, sizeof(b->sockaddr.un.sun_path)-1); + b->sockaddr.un = (struct sockaddr_un) { + .sun_family = AF_UNIX, + }; + + memcpy(b->sockaddr.un.sun_path+1, abstract, l); b->sockaddr_size = offsetof(struct sockaddr_un, sun_path) + 1 + l; } @@ -964,9 +972,11 @@ static int parse_container_unix_address(sd_bus *b, const char **p, char **guid) } else b->nspid = 0; - b->sockaddr.un.sun_family = AF_UNIX; - /* Note that we use the old /var/run prefix here, to increase compatibility with really old containers */ - strncpy(b->sockaddr.un.sun_path, "/var/run/dbus/system_bus_socket", sizeof(b->sockaddr.un.sun_path)); + b->sockaddr.un = (struct sockaddr_un) { + .sun_family = AF_UNIX, + /* Note that we use the old /var/run prefix here, to increase compatibility with really old containers */ + .sun_path = "/var/run/dbus/system_bus_socket", + }; b->sockaddr_size = SOCKADDR_UN_LEN(b->sockaddr.un); b->is_local = false; diff --git a/src/libsystemd/sd-bus/test-bus-watch-bind.c b/src/libsystemd/sd-bus/test-bus-watch-bind.c index 1796feaa2f..40879b8537 100644 --- a/src/libsystemd/sd-bus/test-bus-watch-bind.c +++ b/src/libsystemd/sd-bus/test-bus-watch-bind.c @@ -40,10 +40,9 @@ static const sd_bus_vtable vtable[] = { static void* thread_server(void *p) { _cleanup_free_ char *suffixed = NULL, *suffixed2 = NULL, *d = NULL; _cleanup_close_ int fd = -1; - union sockaddr_union u = { - .un.sun_family = AF_UNIX, - }; + union sockaddr_union u = {}; const char *path = p; + int salen; log_debug("Initializing server"); @@ -66,12 +65,13 @@ static void* thread_server(void *p) { assert_se(symlink(basename(suffixed), suffixed2) >= 0); (void) usleep(100 * USEC_PER_MSEC); - strncpy(u.un.sun_path, path, sizeof(u.un.sun_path)); + salen = sockaddr_un_set_path(&u.un, path); + assert_se(salen >= 0); fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0); assert_se(fd >= 0); - assert_se(bind(fd, &u.sa, SOCKADDR_UN_LEN(u.un)) >= 0); + assert_se(bind(fd, &u.sa, salen) >= 0); usleep(100 * USEC_PER_MSEC); assert_se(listen(fd, SOMAXCONN) >= 0); diff --git a/src/libsystemd/sd-daemon/sd-daemon.c b/src/libsystemd/sd-daemon/sd-daemon.c index c8b5c67d18..44c1d312e1 100644 --- a/src/libsystemd/sd-daemon/sd-daemon.c +++ b/src/libsystemd/sd-daemon/sd-daemon.c @@ -444,9 +444,7 @@ _public_ int sd_pid_notify_with_fds( const int *fds, unsigned n_fds) { - union sockaddr_union sockaddr = { - .sa.sa_family = AF_UNIX, - }; + union sockaddr_union sockaddr = {}; struct iovec iovec = { .iov_base = (char*) state, }; @@ -459,7 +457,7 @@ _public_ int sd_pid_notify_with_fds( struct cmsghdr *cmsg = NULL; const char *e; bool send_ucred; - int r; + int r, salen; if (!state) { r = -EINVAL; @@ -475,14 +473,9 @@ _public_ int sd_pid_notify_with_fds( if (!e) return 0; - /* Must be an abstract socket, or an absolute path */ - if (!IN_SET(e[0], '@', '/') || e[1] == 0) { - r = -EINVAL; - goto finish; - } - - if (strlen(e) > sizeof(sockaddr.un.sun_path)) { - r = -EINVAL; + salen = sockaddr_un_set_path(&sockaddr.un, e); + if (salen < 0) { + r = salen; goto finish; } @@ -495,12 +488,7 @@ _public_ int sd_pid_notify_with_fds( (void) fd_inc_sndbuf(fd, SNDBUF_SIZE); iovec.iov_len = strlen(state); - - strncpy(sockaddr.un.sun_path, e, sizeof(sockaddr.un.sun_path)); - if (sockaddr.un.sun_path[0] == '@') - sockaddr.un.sun_path[0] = 0; - - msghdr.msg_namelen = SOCKADDR_UN_LEN(sockaddr.un); + msghdr.msg_namelen = salen; send_ucred = (pid != 0 && pid != getpid_cached()) || diff --git a/src/libsystemd/sd-netlink/netlink-socket.c b/src/libsystemd/sd-netlink/netlink-socket.c index f103cbedea..c18fd5890e 100644 --- a/src/libsystemd/sd-netlink/netlink-socket.c +++ b/src/libsystemd/sd-netlink/netlink-socket.c @@ -88,9 +88,9 @@ static int broadcast_groups_get(sd_netlink *nl) { int socket_bind(sd_netlink *nl) { socklen_t addrlen; - int r, one = 1; + int r; - r = setsockopt(nl->fd, SOL_NETLINK, NETLINK_PKTINFO, &one, sizeof(one)); + r = setsockopt(nl->fd, SOL_NETLINK, NETLINK_PKTINFO, &const_int_one, sizeof(const_int_one)); if (r < 0) return -errno; diff --git a/src/libudev/libudev-monitor.c b/src/libudev/libudev-monitor.c index ea44308351..50c3925058 100644 --- a/src/libudev/libudev-monitor.c +++ b/src/libudev/libudev-monitor.c @@ -337,7 +337,6 @@ int udev_monitor_allow_unicast_sender(struct udev_monitor *udev_monitor, struct * Returns: 0 on success, otherwise a negative error value. */ _public_ int udev_monitor_enable_receiving(struct udev_monitor *udev_monitor) { - const int on = 1; int r; assert_return(udev_monitor, -EINVAL); @@ -358,7 +357,7 @@ _public_ int udev_monitor_enable_receiving(struct udev_monitor *udev_monitor) { return log_debug_errno(r, "Failed to set address: %m"); /* enable receiving of sender credentials */ - if (setsockopt(udev_monitor->sock, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on)) < 0) + if (setsockopt(udev_monitor->sock, SOL_SOCKET, SO_PASSCRED, &const_int_one, sizeof(const_int_one)) < 0) return log_debug_errno(errno, "Failed to set socket option SO_PASSCRED: %m"); return 0; diff --git a/src/login/pam_systemd.c b/src/login/pam_systemd.c index 99c253df4a..e2b2281c6b 100644 --- a/src/login/pam_systemd.c +++ b/src/login/pam_systemd.c @@ -140,13 +140,11 @@ static int socket_from_display(const char *display, char **path) { } static int get_seat_from_display(const char *display, const char **seat, uint32_t *vtnr) { - union sockaddr_union sa = { - .un.sun_family = AF_UNIX, - }; + union sockaddr_union sa = {}; _cleanup_free_ char *p = NULL, *tty = NULL; _cleanup_close_ int fd = -1; struct ucred ucred; - int v, r; + int v, r, salen; assert(display); assert(vtnr); @@ -160,13 +158,15 @@ static int get_seat_from_display(const char *display, const char **seat, uint32_ r = socket_from_display(display, &p); if (r < 0) return r; - strncpy(sa.un.sun_path, p, sizeof(sa.un.sun_path)); + salen = sockaddr_un_set_path(&sa.un, p); + if (salen < 0) + return salen; fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0); if (fd < 0) return -errno; - if (connect(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0) + if (connect(fd, &sa.sa, salen) < 0) return -errno; r = getpeercred(fd, &ucred); diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 134c4c3b5d..fb360a6f4f 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -2812,10 +2812,10 @@ static int inner_child( } static int setup_sd_notify_child(void) { - static const int one = 1; - int fd = -1; + _cleanup_close_ int fd = -1; union sockaddr_union sa = { - .sa.sa_family = AF_UNIX, + .un.sun_family = AF_UNIX, + .un.sun_path = NSPAWN_NOTIFY_SOCKET_PATH, }; int r; @@ -2824,28 +2824,21 @@ static int setup_sd_notify_child(void) { return log_error_errno(errno, "Failed to allocate notification socket: %m"); (void) mkdir_parents(NSPAWN_NOTIFY_SOCKET_PATH, 0755); - (void) unlink(NSPAWN_NOTIFY_SOCKET_PATH); + (void) sockaddr_un_unlink(&sa.un); - strncpy(sa.un.sun_path, NSPAWN_NOTIFY_SOCKET_PATH, sizeof(sa.un.sun_path)); r = bind(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)); - if (r < 0) { - safe_close(fd); - return log_error_errno(errno, "bind(%s) failed: %m", sa.un.sun_path); - } + if (r < 0) + return log_error_errno(errno, "bind(" NSPAWN_NOTIFY_SOCKET_PATH ") failed: %m"); r = userns_lchown(NSPAWN_NOTIFY_SOCKET_PATH, 0, 0); - if (r < 0) { - safe_close(fd); + if (r < 0) return log_error_errno(r, "Failed to chown " NSPAWN_NOTIFY_SOCKET_PATH ": %m"); - } - r = setsockopt(fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one)); - if (r < 0) { - safe_close(fd); + r = setsockopt(fd, SOL_SOCKET, SO_PASSCRED, &const_int_one, sizeof(const_int_one)); + if (r < 0) return log_error_errno(errno, "SO_PASSCRED failed: %m"); - } - return fd; + return TAKE_FD(fd); } static int outer_child( diff --git a/src/reply-password/reply-password.c b/src/reply-password/reply-password.c index efb68a354f..84176184af 100644 --- a/src/reply-password/reply-password.c +++ b/src/reply-password/reply-password.c @@ -14,17 +14,18 @@ #include "util.h" static int send_on_socket(int fd, const char *socket_name, const void *packet, size_t size) { - union sockaddr_union sa = { - .un.sun_family = AF_UNIX, - }; + union sockaddr_union sa = {}; + int salen; assert(fd >= 0); assert(socket_name); assert(packet); - strncpy(sa.un.sun_path, socket_name, sizeof(sa.un.sun_path)); + salen = sockaddr_un_set_path(&sa.un, socket_name); + if (salen < 0) + return log_error_errno(salen, "Specified socket path for AF_UNIX socket invalid, refusing: %s", socket_name); - if (sendto(fd, packet, size, MSG_NOSIGNAL, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0) + if (sendto(fd, packet, size, MSG_NOSIGNAL, &sa.sa, salen) < 0) return log_error_errno(errno, "Failed to send: %m"); return 0; diff --git a/src/resolve/resolved-dns-scope.c b/src/resolve/resolved-dns-scope.c index 5ceb954410..57af95c41f 100644 --- a/src/resolve/resolved-dns-scope.c +++ b/src/resolve/resolved-dns-scope.c @@ -313,7 +313,6 @@ static int dns_scope_socket( _cleanup_close_ int fd = -1; union sockaddr_union sa; socklen_t salen; - static const int one = 1; int r, ifindex; assert(s); @@ -379,7 +378,7 @@ static int dns_scope_socket( return -errno; if (type == SOCK_STREAM) { - r = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one)); + r = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &const_int_one, sizeof(const_int_one)); if (r < 0) return -errno; } @@ -402,11 +401,11 @@ static int dns_scope_socket( /* RFC 4795, section 2.5 requires the TTL to be set to 1 */ if (sa.sa.sa_family == AF_INET) { - r = setsockopt(fd, IPPROTO_IP, IP_TTL, &one, sizeof(one)); + r = setsockopt(fd, IPPROTO_IP, IP_TTL, &const_int_one, sizeof(const_int_one)); if (r < 0) return -errno; } else if (sa.sa.sa_family == AF_INET6) { - r = setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &one, sizeof(one)); + r = setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &const_int_one, sizeof(const_int_one)); if (r < 0) return -errno; } diff --git a/src/resolve/resolved-dns-stub.c b/src/resolve/resolved-dns-stub.c index 5ddf13081e..5f87a790c6 100644 --- a/src/resolve/resolved-dns-stub.c +++ b/src/resolve/resolved-dns-stub.c @@ -392,7 +392,6 @@ static int on_dns_stub_packet(sd_event_source *s, int fd, uint32_t revents, void } static int manager_dns_stub_udp_fd(Manager *m) { - static const int one = 1; union sockaddr_union sa = { .in.sin_family = AF_INET, .in.sin_port = htobe16(53), @@ -408,13 +407,13 @@ static int manager_dns_stub_udp_fd(Manager *m) { if (fd < 0) return -errno; - if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof one) < 0) + if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &const_int_one, sizeof const_int_one) < 0) return -errno; - if (setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &one, sizeof one) < 0) + if (setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &const_int_one, sizeof const_int_one) < 0) return -errno; - if (setsockopt(fd, IPPROTO_IP, IP_RECVTTL, &one, sizeof one) < 0) + if (setsockopt(fd, IPPROTO_IP, IP_RECVTTL, &const_int_one, sizeof const_int_one) < 0) return -errno; /* Make sure no traffic from outside the local host can leak to onto this socket */ @@ -479,7 +478,6 @@ static int on_dns_stub_stream(sd_event_source *s, int fd, uint32_t revents, void } static int manager_dns_stub_tcp_fd(Manager *m) { - static const int one = 1; union sockaddr_union sa = { .in.sin_family = AF_INET, .in.sin_addr.s_addr = htobe32(INADDR_DNS_STUB), @@ -495,16 +493,16 @@ static int manager_dns_stub_tcp_fd(Manager *m) { if (fd < 0) return -errno; - if (setsockopt(fd, IPPROTO_IP, IP_TTL, &one, sizeof one) < 0) + if (setsockopt(fd, IPPROTO_IP, IP_TTL, &const_int_one, sizeof const_int_one) < 0) return -errno; - if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof one) < 0) + if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &const_int_one, sizeof const_int_one) < 0) return -errno; - if (setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &one, sizeof one) < 0) + if (setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &const_int_one, sizeof const_int_one) < 0) return -errno; - if (setsockopt(fd, IPPROTO_IP, IP_RECVTTL, &one, sizeof one) < 0) + if (setsockopt(fd, IPPROTO_IP, IP_RECVTTL, &const_int_one, sizeof const_int_one) < 0) return -errno; /* Make sure no traffic from outside the local host can leak to onto this socket */ diff --git a/src/resolve/resolved-llmnr.c b/src/resolve/resolved-llmnr.c index 2f2a1a15ec..a6100c3b00 100644 --- a/src/resolve/resolved-llmnr.c +++ b/src/resolve/resolved-llmnr.c @@ -115,7 +115,7 @@ int manager_llmnr_ipv4_udp_fd(Manager *m) { .in.sin_family = AF_INET, .in.sin_port = htobe16(LLMNR_PORT), }; - static const int one = 1, pmtu = IP_PMTUDISC_DONT, ttl = 255; + static const int pmtu = IP_PMTUDISC_DONT, ttl = 255; int r; assert(m); @@ -140,19 +140,19 @@ int manager_llmnr_ipv4_udp_fd(Manager *m) { goto fail; } - r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_MULTICAST_LOOP, &one, sizeof(one)); + r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_MULTICAST_LOOP, &const_int_one, sizeof(const_int_one)); if (r < 0) { r = log_error_errno(errno, "LLMNR-IPv4(UDP): Failed to set IP_MULTICAST_LOOP: %m"); goto fail; } - r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_PKTINFO, &one, sizeof(one)); + r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_PKTINFO, &const_int_one, sizeof(const_int_one)); if (r < 0) { r = log_error_errno(errno, "LLMNR-IPv4(UDP): Failed to set IP_PKTINFO: %m"); goto fail; } - r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_RECVTTL, &one, sizeof(one)); + r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_RECVTTL, &const_int_one, sizeof(const_int_one)); if (r < 0) { r = log_error_errno(errno, "LLMNR-IPv4(UDP): Failed to set IP_RECVTTL: %m"); goto fail; @@ -176,7 +176,7 @@ int manager_llmnr_ipv4_udp_fd(Manager *m) { log_warning("LLMNR-IPv4(UDP): There appears to be another LLMNR responder running, or previously systemd-resolved crashed with some outstanding transfers."); /* try again with SO_REUSEADDR */ - r = setsockopt(m->llmnr_ipv4_udp_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)); + r = setsockopt(m->llmnr_ipv4_udp_fd, SOL_SOCKET, SO_REUSEADDR, &const_int_one, sizeof(const_int_one)); if (r < 0) { r = log_error_errno(errno, "LLMNR-IPv4(UDP): Failed to set SO_REUSEADDR: %m"); goto fail; @@ -189,7 +189,7 @@ int manager_llmnr_ipv4_udp_fd(Manager *m) { } } else { /* enable SO_REUSEADDR for the case that the user really wants multiple LLMNR responders */ - r = setsockopt(m->llmnr_ipv4_udp_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)); + r = setsockopt(m->llmnr_ipv4_udp_fd, SOL_SOCKET, SO_REUSEADDR, &const_int_one, sizeof(const_int_one)); if (r < 0) { r = log_error_errno(errno, "LLMNR-IPv4(UDP): Failed to set SO_REUSEADDR: %m"); goto fail; @@ -214,7 +214,7 @@ int manager_llmnr_ipv6_udp_fd(Manager *m) { .in6.sin6_family = AF_INET6, .in6.sin6_port = htobe16(LLMNR_PORT), }; - static const int one = 1, ttl = 255; + static const int ttl = 255; int r; assert(m); @@ -239,25 +239,25 @@ int manager_llmnr_ipv6_udp_fd(Manager *m) { goto fail; } - r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &one, sizeof(one)); + r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &const_int_one, sizeof(const_int_one)); if (r < 0) { r = log_error_errno(errno, "LLMNR-IPv6(UDP): Failed to set IPV6_MULTICAST_LOOP: %m"); goto fail; } - r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_V6ONLY, &one, sizeof(one)); + r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_V6ONLY, &const_int_one, sizeof(const_int_one)); if (r < 0) { r = log_error_errno(errno, "LLMNR-IPv6(UDP): Failed to set IPV6_V6ONLY: %m"); goto fail; } - r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &one, sizeof(one)); + r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &const_int_one, sizeof(const_int_one)); if (r < 0) { r = log_error_errno(errno, "LLMNR-IPv6(UDP): Failed to set IPV6_RECVPKTINFO: %m"); goto fail; } - r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &one, sizeof(one)); + r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &const_int_one, sizeof(const_int_one)); if (r < 0) { r = log_error_errno(errno, "LLMNR-IPv6(UDP): Failed to set IPV6_RECVHOPLIMIT: %m"); goto fail; @@ -274,7 +274,7 @@ int manager_llmnr_ipv6_udp_fd(Manager *m) { log_warning("LLMNR-IPv6(UDP): There appears to be another LLMNR responder running, or previously systemd-resolved crashed with some outstanding transfers."); /* try again with SO_REUSEADDR */ - r = setsockopt(m->llmnr_ipv6_udp_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)); + r = setsockopt(m->llmnr_ipv6_udp_fd, SOL_SOCKET, SO_REUSEADDR, &const_int_one, sizeof(const_int_one)); if (r < 0) { r = log_error_errno(errno, "LLMNR-IPv6(UDP): Failed to set SO_REUSEADDR: %m"); goto fail; @@ -287,7 +287,7 @@ int manager_llmnr_ipv6_udp_fd(Manager *m) { } } else { /* enable SO_REUSEADDR for the case that the user really wants multiple LLMNR responders */ - r = setsockopt(m->llmnr_ipv6_udp_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)); + r = setsockopt(m->llmnr_ipv6_udp_fd, SOL_SOCKET, SO_REUSEADDR, &const_int_one, sizeof(const_int_one)); if (r < 0) { r = log_error_errno(errno, "LLMNR-IPv6(UDP): Failed to set SO_REUSEADDR: %m"); goto fail; @@ -355,7 +355,7 @@ int manager_llmnr_ipv4_tcp_fd(Manager *m) { .in.sin_family = AF_INET, .in.sin_port = htobe16(LLMNR_PORT), }; - static const int one = 1, pmtu = IP_PMTUDISC_DONT; + static const int pmtu = IP_PMTUDISC_DONT; int r; assert(m); @@ -368,19 +368,19 @@ int manager_llmnr_ipv4_tcp_fd(Manager *m) { return log_error_errno(errno, "LLMNR-IPv4(TCP): Failed to create socket: %m"); /* RFC 4795, section 2.5. requires setting the TTL of TCP streams to 1 */ - r = setsockopt(m->llmnr_ipv4_tcp_fd, IPPROTO_IP, IP_TTL, &one, sizeof(one)); + r = setsockopt(m->llmnr_ipv4_tcp_fd, IPPROTO_IP, IP_TTL, &const_int_one, sizeof(const_int_one)); if (r < 0) { r = log_error_errno(errno, "LLMNR-IPv4(TCP): Failed to set IP_TTL: %m"); goto fail; } - r = setsockopt(m->llmnr_ipv4_tcp_fd, IPPROTO_IP, IP_PKTINFO, &one, sizeof(one)); + r = setsockopt(m->llmnr_ipv4_tcp_fd, IPPROTO_IP, IP_PKTINFO, &const_int_one, sizeof(const_int_one)); if (r < 0) { r = log_error_errno(errno, "LLMNR-IPv4(TCP): Failed to set IP_PKTINFO: %m"); goto fail; } - r = setsockopt(m->llmnr_ipv4_tcp_fd, IPPROTO_IP, IP_RECVTTL, &one, sizeof(one)); + r = setsockopt(m->llmnr_ipv4_tcp_fd, IPPROTO_IP, IP_RECVTTL, &const_int_one, sizeof(const_int_one)); if (r < 0) { r = log_error_errno(errno, "LLMNR-IPv4(TCP): Failed to set IP_RECVTTL: %m"); goto fail; @@ -404,7 +404,7 @@ int manager_llmnr_ipv4_tcp_fd(Manager *m) { log_warning("LLMNR-IPv4(TCP): There appears to be another LLMNR responder running, or previously systemd-resolved crashed with some outstanding transfers."); /* try again with SO_REUSEADDR */ - r = setsockopt(m->llmnr_ipv4_tcp_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)); + r = setsockopt(m->llmnr_ipv4_tcp_fd, SOL_SOCKET, SO_REUSEADDR, &const_int_one, sizeof(const_int_one)); if (r < 0) { r = log_error_errno(errno, "LLMNR-IPv4(TCP): Failed to set SO_REUSEADDR: %m"); goto fail; @@ -417,7 +417,7 @@ int manager_llmnr_ipv4_tcp_fd(Manager *m) { } } else { /* enable SO_REUSEADDR for the case that the user really wants multiple LLMNR responders */ - r = setsockopt(m->llmnr_ipv4_tcp_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)); + r = setsockopt(m->llmnr_ipv4_tcp_fd, SOL_SOCKET, SO_REUSEADDR, &const_int_one, sizeof(const_int_one)); if (r < 0) { r = log_error_errno(errno, "LLMNR-IPv4(TCP): Failed to set SO_REUSEADDR: %m"); goto fail; @@ -448,7 +448,6 @@ int manager_llmnr_ipv6_tcp_fd(Manager *m) { .in6.sin6_family = AF_INET6, .in6.sin6_port = htobe16(LLMNR_PORT), }; - static const int one = 1; int r; assert(m); @@ -461,25 +460,25 @@ int manager_llmnr_ipv6_tcp_fd(Manager *m) { return log_error_errno(errno, "LLMNR-IPv6(TCP): Failed to create socket: %m"); /* RFC 4795, section 2.5. requires setting the TTL of TCP streams to 1 */ - r = setsockopt(m->llmnr_ipv6_tcp_fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &one, sizeof(one)); + r = setsockopt(m->llmnr_ipv6_tcp_fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &const_int_one, sizeof(const_int_one)); if (r < 0) { r = log_error_errno(errno, "LLMNR-IPv6(TCP): Failed to set IPV6_UNICAST_HOPS: %m"); goto fail; } - r = setsockopt(m->llmnr_ipv6_tcp_fd, IPPROTO_IPV6, IPV6_V6ONLY, &one, sizeof(one)); + r = setsockopt(m->llmnr_ipv6_tcp_fd, IPPROTO_IPV6, IPV6_V6ONLY, &const_int_one, sizeof(const_int_one)); if (r < 0) { r = log_error_errno(errno, "LLMNR-IPv6(TCP): Failed to set IPV6_V6ONLY: %m"); goto fail; } - r = setsockopt(m->llmnr_ipv6_tcp_fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &one, sizeof(one)); + r = setsockopt(m->llmnr_ipv6_tcp_fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &const_int_one, sizeof(const_int_one)); if (r < 0) { r = log_error_errno(errno, "LLMNR-IPv6(TCP): Failed to set IPV6_RECVPKTINFO: %m"); goto fail; } - r = setsockopt(m->llmnr_ipv6_tcp_fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &one, sizeof(one)); + r = setsockopt(m->llmnr_ipv6_tcp_fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &const_int_one, sizeof(const_int_one)); if (r < 0) { r = log_error_errno(errno, "LLMNR-IPv6(TCP): Failed to set IPV6_RECVHOPLIMIT: %m"); goto fail; @@ -496,7 +495,7 @@ int manager_llmnr_ipv6_tcp_fd(Manager *m) { log_warning("LLMNR-IPv6(TCP): There appears to be another LLMNR responder running, or previously systemd-resolved crashed with some outstanding transfers."); /* try again with SO_REUSEADDR */ - r = setsockopt(m->llmnr_ipv6_tcp_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)); + r = setsockopt(m->llmnr_ipv6_tcp_fd, SOL_SOCKET, SO_REUSEADDR, &const_int_one, sizeof(const_int_one)); if (r < 0) { r = log_error_errno(errno, "LLMNR-IPv6(TCP): Failed to set SO_REUSEADDR: %m"); goto fail; @@ -509,7 +508,7 @@ int manager_llmnr_ipv6_tcp_fd(Manager *m) { } } else { /* enable SO_REUSEADDR for the case that the user really wants multiple LLMNR responders */ - r = setsockopt(m->llmnr_ipv6_tcp_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)); + r = setsockopt(m->llmnr_ipv6_tcp_fd, SOL_SOCKET, SO_REUSEADDR, &const_int_one, sizeof(const_int_one)); if (r < 0) { r = log_error_errno(errno, "LLMNR-IPv6(TCP): Failed to set SO_REUSEADDR: %m"); goto fail; diff --git a/src/resolve/resolved-mdns.c b/src/resolve/resolved-mdns.c index 32868180ce..feee66c85c 100644 --- a/src/resolve/resolved-mdns.c +++ b/src/resolve/resolved-mdns.c @@ -339,7 +339,7 @@ int manager_mdns_ipv4_fd(Manager *m) { .in.sin_family = AF_INET, .in.sin_port = htobe16(MDNS_PORT), }; - static const int one = 1, pmtu = IP_PMTUDISC_DONT, ttl = 255; + static const int pmtu = IP_PMTUDISC_DONT, ttl = 255; int r; assert(m); @@ -363,19 +363,19 @@ int manager_mdns_ipv4_fd(Manager *m) { goto fail; } - r = setsockopt(m->mdns_ipv4_fd, IPPROTO_IP, IP_MULTICAST_LOOP, &one, sizeof(one)); + r = setsockopt(m->mdns_ipv4_fd, IPPROTO_IP, IP_MULTICAST_LOOP, &const_int_one, sizeof(const_int_one)); if (r < 0) { r = log_error_errno(errno, "mDNS-IPv4: Failed to set IP_MULTICAST_LOOP: %m"); goto fail; } - r = setsockopt(m->mdns_ipv4_fd, IPPROTO_IP, IP_PKTINFO, &one, sizeof(one)); + r = setsockopt(m->mdns_ipv4_fd, IPPROTO_IP, IP_PKTINFO, &const_int_one, sizeof(const_int_one)); if (r < 0) { r = log_error_errno(errno, "mDNS-IPv4: Failed to set IP_PKTINFO: %m"); goto fail; } - r = setsockopt(m->mdns_ipv4_fd, IPPROTO_IP, IP_RECVTTL, &one, sizeof(one)); + r = setsockopt(m->mdns_ipv4_fd, IPPROTO_IP, IP_RECVTTL, &const_int_one, sizeof(const_int_one)); if (r < 0) { r = log_error_errno(errno, "mDNS-IPv4: Failed to set IP_RECVTTL: %m"); goto fail; @@ -400,7 +400,7 @@ int manager_mdns_ipv4_fd(Manager *m) { log_warning("mDNS-IPv4: There appears to be another mDNS responder running, or previously systemd-resolved crashed with some outstanding transfers."); /* try again with SO_REUSEADDR */ - r = setsockopt(m->mdns_ipv4_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)); + r = setsockopt(m->mdns_ipv4_fd, SOL_SOCKET, SO_REUSEADDR, &const_int_one, sizeof(const_int_one)); if (r < 0) { r = log_error_errno(errno, "mDNS-IPv4: Failed to set SO_REUSEADDR: %m"); goto fail; @@ -413,7 +413,7 @@ int manager_mdns_ipv4_fd(Manager *m) { } } else { /* enable SO_REUSEADDR for the case that the user really wants multiple mDNS responders */ - r = setsockopt(m->mdns_ipv4_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)); + r = setsockopt(m->mdns_ipv4_fd, SOL_SOCKET, SO_REUSEADDR, &const_int_one, sizeof(const_int_one)); if (r < 0) { r = log_error_errno(errno, "mDNS-IPv4: Failed to set SO_REUSEADDR: %m"); goto fail; @@ -436,7 +436,7 @@ int manager_mdns_ipv6_fd(Manager *m) { .in6.sin6_family = AF_INET6, .in6.sin6_port = htobe16(MDNS_PORT), }; - static const int one = 1, ttl = 255; + static const int ttl = 255; int r; assert(m); @@ -461,25 +461,25 @@ int manager_mdns_ipv6_fd(Manager *m) { goto fail; } - r = setsockopt(m->mdns_ipv6_fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &one, sizeof(one)); + r = setsockopt(m->mdns_ipv6_fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &const_int_one, sizeof(const_int_one)); if (r < 0) { r = log_error_errno(errno, "mDNS-IPv6: Failed to set IPV6_MULTICAST_LOOP: %m"); goto fail; } - r = setsockopt(m->mdns_ipv6_fd, IPPROTO_IPV6, IPV6_V6ONLY, &one, sizeof(one)); + r = setsockopt(m->mdns_ipv6_fd, IPPROTO_IPV6, IPV6_V6ONLY, &const_int_one, sizeof(const_int_one)); if (r < 0) { r = log_error_errno(errno, "mDNS-IPv6: Failed to set IPV6_V6ONLY: %m"); goto fail; } - r = setsockopt(m->mdns_ipv6_fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &one, sizeof(one)); + r = setsockopt(m->mdns_ipv6_fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &const_int_one, sizeof(const_int_one)); if (r < 0) { r = log_error_errno(errno, "mDNS-IPv6: Failed to set IPV6_RECVPKTINFO: %m"); goto fail; } - r = setsockopt(m->mdns_ipv6_fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &one, sizeof(one)); + r = setsockopt(m->mdns_ipv6_fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &const_int_one, sizeof(const_int_one)); if (r < 0) { r = log_error_errno(errno, "mDNS-IPv6: Failed to set IPV6_RECVHOPLIMIT: %m"); goto fail; @@ -497,7 +497,7 @@ int manager_mdns_ipv6_fd(Manager *m) { log_warning("mDNS-IPv6: There appears to be another mDNS responder running, or previously systemd-resolved crashed with some outstanding transfers."); /* try again with SO_REUSEADDR */ - r = setsockopt(m->mdns_ipv6_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)); + r = setsockopt(m->mdns_ipv6_fd, SOL_SOCKET, SO_REUSEADDR, &const_int_one, sizeof(const_int_one)); if (r < 0) { r = log_error_errno(errno, "mDNS-IPv6: Failed to set SO_REUSEADDR: %m"); goto fail; @@ -510,7 +510,7 @@ int manager_mdns_ipv6_fd(Manager *m) { } } else { /* enable SO_REUSEADDR for the case that the user really wants multiple mDNS responders */ - r = setsockopt(m->mdns_ipv6_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)); + r = setsockopt(m->mdns_ipv6_fd, SOL_SOCKET, SO_REUSEADDR, &const_int_one, sizeof(const_int_one)); if (r < 0) { r = log_error_errno(errno, "mDNS-IPv6: Failed to set SO_REUSEADDR: %m"); goto fail; diff --git a/src/shared/ask-password-api.c b/src/shared/ask-password-api.c index 682dc754fc..681fd0d618 100644 --- a/src/shared/ask-password-api.c +++ b/src/shared/ask-password-api.c @@ -451,41 +451,35 @@ finish: return r; } -static int create_socket(char **name) { - union sockaddr_union sa = { - .un.sun_family = AF_UNIX, - }; +static int create_socket(char **ret) { + _cleanup_free_ char *path = NULL; + union sockaddr_union sa = {}; _cleanup_close_ int fd = -1; - static const int one = 1; - char *c; - int r; + int salen; - assert(name); + assert(ret); fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0); if (fd < 0) return -errno; - snprintf(sa.un.sun_path, sizeof(sa.un.sun_path)-1, "/run/systemd/ask-password/sck.%" PRIx64, random_u64()); + if (asprintf(&path, "/run/systemd/ask-password/sck.%" PRIx64, random_u64()) < 0) + return -ENOMEM; + + salen = sockaddr_un_set_path(&sa.un, path); + if (salen < 0) + return salen; RUN_WITH_UMASK(0177) { - if (bind(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0) + if (bind(fd, &sa.sa, salen) < 0) return -errno; } - if (setsockopt(fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one)) < 0) + if (setsockopt(fd, SOL_SOCKET, SO_PASSCRED, &const_int_one, sizeof(const_int_one)) < 0) return -errno; - c = strdup(sa.un.sun_path); - if (!c) - return -ENOMEM; - - *name = c; - - r = fd; - fd = -1; - - return r; + *ret = TAKE_PTR(path); + return TAKE_FD(fd); } int ask_password_agent( diff --git a/src/socket-proxy/socket-proxyd.c b/src/socket-proxy/socket-proxyd.c index 4c60d97c39..227378edaa 100644 --- a/src/socket-proxy/socket-proxyd.c +++ b/src/socket-proxy/socket-proxyd.c @@ -378,17 +378,16 @@ static int resolve_remote(Connection *c) { const char *node, *service; int r; - if (path_is_absolute(arg_remote_host)) { - sa.un.sun_family = AF_UNIX; - strncpy(sa.un.sun_path, arg_remote_host, sizeof(sa.un.sun_path)); - return connection_start(c, &sa.sa, SOCKADDR_UN_LEN(sa.un)); - } + if (IN_SET(arg_remote_host[0], '/', '@')) { + int salen; - if (arg_remote_host[0] == '@') { - sa.un.sun_family = AF_UNIX; - sa.un.sun_path[0] = 0; - strncpy(sa.un.sun_path+1, arg_remote_host+1, sizeof(sa.un.sun_path)-1); - return connection_start(c, &sa.sa, SOCKADDR_UN_LEN(sa.un)); + salen = sockaddr_un_set_path(&sa.un, arg_remote_host); + if (salen < 0) { + log_error_errno(salen, "Specified address doesn't fit in an AF_UNIX address, refusing: %m"); + goto fail; + } + + return connection_start(c, &sa.sa, salen); } service = strrchr(arg_remote_host, ':'); diff --git a/src/test/test-socket-util.c b/src/test/test-socket-util.c index df18a2a83c..0de29c2235 100644 --- a/src/test/test-socket-util.c +++ b/src/test/test-socket-util.c @@ -405,7 +405,7 @@ static void test_sockaddr_un_len(void) { .sun_path = "\0foobar", }; - assert_se(SOCKADDR_UN_LEN(fs) == offsetof(struct sockaddr_un, sun_path) + strlen(fs.sun_path)); + assert_se(SOCKADDR_UN_LEN(fs) == offsetof(struct sockaddr_un, sun_path) + strlen(fs.sun_path) + 1); assert_se(SOCKADDR_UN_LEN(abstract) == offsetof(struct sockaddr_un, sun_path) + 1 + strlen(abstract.sun_path + 1)); } diff --git a/src/timesync/timesyncd-manager.c b/src/timesync/timesyncd-manager.c index 5a3d478d73..f33a32afc0 100644 --- a/src/timesync/timesyncd-manager.c +++ b/src/timesync/timesyncd-manager.c @@ -630,7 +630,6 @@ static int manager_receive_response(sd_event_source *source, int fd, uint32_t re static int manager_listen_setup(Manager *m) { union sockaddr_union addr = {}; static const int tos = IPTOS_LOWDELAY; - static const int on = 1; int r; assert(m); @@ -651,7 +650,7 @@ static int manager_listen_setup(Manager *m) { if (r < 0) return -errno; - r = setsockopt(m->server_socket, SOL_SOCKET, SO_TIMESTAMPNS, &on, sizeof(on)); + r = setsockopt(m->server_socket, SOL_SOCKET, SO_TIMESTAMPNS, &const_int_one, sizeof(const_int_one)); if (r < 0) return -errno; diff --git a/src/tty-ask-password-agent/tty-ask-password-agent.c b/src/tty-ask-password-agent/tty-ask-password-agent.c index 690c7b0de9..6c6f3be08c 100644 --- a/src/tty-ask-password-agent/tty-ask-password-agent.c +++ b/src/tty-ask-password-agent/tty-ask-password-agent.c @@ -235,14 +235,18 @@ finish: static int send_passwords(const char *socket_name, char **passwords) { _cleanup_free_ char *packet = NULL; _cleanup_close_ int socket_fd = -1; - union sockaddr_union sa = { .un.sun_family = AF_UNIX }; + union sockaddr_union sa = {}; size_t packet_length = 1; char **p, *d; ssize_t n; - int r; + int r, salen; assert(socket_name); + salen = sockaddr_un_set_path(&sa.un, socket_name); + if (salen < 0) + return salen; + STRV_FOREACH(p, passwords) packet_length += strlen(*p) + 1; @@ -262,9 +266,7 @@ static int send_passwords(const char *socket_name, char **passwords) { goto finish; } - strncpy(sa.un.sun_path, socket_name, sizeof(sa.un.sun_path)); - - n = sendto(socket_fd, packet, packet_length, MSG_NOSIGNAL, &sa.sa, SOCKADDR_UN_LEN(sa.un)); + n = sendto(socket_fd, packet, packet_length, MSG_NOSIGNAL, &sa.sa, salen); if (n < 0) { r = log_debug_errno(errno, "sendto(): %m"); goto finish; diff --git a/src/udev/udev-ctrl.c b/src/udev/udev-ctrl.c index 64024100fe..bde8b63dde 100644 --- a/src/udev/udev-ctrl.c +++ b/src/udev/udev-ctrl.c @@ -73,7 +73,6 @@ struct udev_ctrl_connection { struct udev_ctrl *udev_ctrl_new_from_fd(int fd) { struct udev_ctrl *uctrl; - const int on = 1; int r; uctrl = new0(struct udev_ctrl, 1); @@ -97,12 +96,15 @@ struct udev_ctrl *udev_ctrl_new_from_fd(int fd) { * FIXME: remove it as soon as we can depend on this: * http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=90c6bd34f884cd9cee21f1d152baf6c18bcac949 */ - r = setsockopt(uctrl->sock, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on)); + r = setsockopt(uctrl->sock, SOL_SOCKET, SO_PASSCRED, &const_int_one, sizeof(const_int_one)); if (r < 0) log_warning_errno(errno, "could not set SO_PASSCRED: %m"); - uctrl->saddr.un.sun_family = AF_LOCAL; - strscpy(uctrl->saddr.un.sun_path, sizeof(uctrl->saddr.un.sun_path), "/run/udev/control"); + uctrl->saddr.un = (struct sockaddr_un) { + .sun_family = AF_UNIX, + .sun_path = "/run/udev/control", + }; + uctrl->addrlen = SOCKADDR_UN_LEN(uctrl->saddr.un); return uctrl; } @@ -117,7 +119,7 @@ int udev_ctrl_enable_receiving(struct udev_ctrl *uctrl) { if (!uctrl->bound) { err = bind(uctrl->sock, &uctrl->saddr.sa, uctrl->addrlen); if (err < 0 && errno == EADDRINUSE) { - unlink(uctrl->saddr.un.sun_path); + (void) sockaddr_un_unlink(&uctrl->saddr.un); err = bind(uctrl->sock, &uctrl->saddr.sa, uctrl->addrlen); } @@ -148,7 +150,7 @@ int udev_ctrl_cleanup(struct udev_ctrl *uctrl) { if (uctrl == NULL) return 0; if (uctrl->cleanup_socket) - unlink(uctrl->saddr.un.sun_path); + sockaddr_un_unlink(&uctrl->saddr.un); return 0; } @@ -161,7 +163,6 @@ int udev_ctrl_get_fd(struct udev_ctrl *uctrl) { struct udev_ctrl_connection *udev_ctrl_get_connection(struct udev_ctrl *uctrl) { struct udev_ctrl_connection *conn; struct ucred ucred = {}; - const int on = 1; int r; conn = new(struct udev_ctrl_connection, 1); @@ -189,15 +190,14 @@ struct udev_ctrl_connection *udev_ctrl_get_connection(struct udev_ctrl *uctrl) { } /* enable receiving of the sender credentials in the messages */ - r = setsockopt(conn->sock, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on)); + r = setsockopt(conn->sock, SOL_SOCKET, SO_PASSCRED, &const_int_one, sizeof(const_int_one)); if (r < 0) log_warning_errno(errno, "could not set SO_PASSCRED: %m"); udev_ctrl_ref(uctrl); return conn; err: - if (conn->sock >= 0) - close(conn->sock); + safe_close(conn->sock); return mfree(conn); } diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c index 4d87754042..d3156859fa 100644 --- a/src/udev/udev-rules.c +++ b/src/udev/udev-rules.c @@ -1392,17 +1392,12 @@ static void add_rule(struct udev_rules *rules, char *line, rule_add_key(&rule_tmp, TK_A_DB_PERSIST, op, NULL, NULL); pos = strstr(value, "nowatch"); - if (pos != NULL) { - const int off = 0; - - rule_add_key(&rule_tmp, TK_A_INOTIFY_WATCH, op, NULL, &off); - } else { + if (pos) + rule_add_key(&rule_tmp, TK_A_INOTIFY_WATCH, op, NULL, &const_int_zero); + else { pos = strstr(value, "watch"); - if (pos != NULL) { - const int on = 1; - - rule_add_key(&rule_tmp, TK_A_INOTIFY_WATCH, op, NULL, &on); - } + if (pos) + rule_add_key(&rule_tmp, TK_A_INOTIFY_WATCH, op, NULL, &const_int_one); } pos = strstr(value, "static_node="); diff --git a/src/udev/udevd.c b/src/udev/udevd.c index 4f77243c15..06a122bd6a 100644 --- a/src/udev/udevd.c +++ b/src/udev/udevd.c @@ -1508,7 +1508,7 @@ static int parse_argv(int argc, char *argv[]) { static int manager_new(Manager **ret, int fd_ctrl, int fd_uevent, const char *cgroup) { _cleanup_(manager_freep) Manager *manager = NULL; - int r, fd_worker, one = 1; + int r, fd_worker; assert(ret); assert(fd_ctrl >= 0); @@ -1548,7 +1548,7 @@ static int manager_new(Manager **ret, int fd_ctrl, int fd_uevent, const char *cg fd_worker = manager->worker_watch[READ_END]; - r = setsockopt(fd_worker, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one)); + r = setsockopt(fd_worker, SOL_SOCKET, SO_PASSCRED, &const_int_one, sizeof(const_int_one)); if (r < 0) return log_error_errno(errno, "could not enable SO_PASSCRED: %m");