From 1861986a3bf78df26aee37635083cf1507be4b24 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 10 May 2022 18:08:57 +0200 Subject: [PATCH] tree-wide: port various users over to connect_unix_path() Let's make use of our new helper, and thus allow longer paths. --- src/basic/log.c | 30 +++++++----------------- src/core/execute.c | 29 ++++++++--------------- src/coredump/coredump.c | 10 +++----- src/fsck/fsck.c | 13 ++++------ src/libsystemd/sd-journal/journal-send.c | 8 ++----- src/nspawn/nspawn.c | 14 ++++------- src/shared/nscd-flush.c | 20 +++++++--------- src/shared/varlink.c | 24 ++++++++++++------- src/userdb/userdbctl.c | 12 +++------- 9 files changed, 59 insertions(+), 101 deletions(-) diff --git a/src/basic/log.c b/src/basic/log.c index 8f36c1dfad..02fc2c6f92 100644 --- a/src/basic/log.c +++ b/src/basic/log.c @@ -149,12 +149,6 @@ static int create_log_socket(int type) { } static int log_open_syslog(void) { - - static const union sockaddr_union sa = { - .un.sun_family = AF_UNIX, - .un.sun_path = "/dev/log", - }; - int r; if (syslog_fd >= 0) @@ -166,22 +160,21 @@ static int log_open_syslog(void) { goto fail; } - if (connect(syslog_fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0) { + r = connect_unix_path(syslog_fd, AT_FDCWD, "/dev/log"); + if (r < 0) { safe_close(syslog_fd); - /* Some legacy syslog systems still use stream - * sockets. They really shouldn't. But what can we - * do... */ + /* Some legacy syslog systems still use stream sockets. They really shouldn't. But what can + * we do... */ syslog_fd = create_log_socket(SOCK_STREAM); if (syslog_fd < 0) { r = syslog_fd; goto fail; } - if (connect(syslog_fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0) { - r = -errno; + r = connect_unix_path(syslog_fd, AT_FDCWD, "/dev/log"); + if (r < 0) goto fail; - } syslog_is_stream = true; } else @@ -199,12 +192,6 @@ static void log_close_journal(void) { } static int log_open_journal(void) { - - static const union sockaddr_union sa = { - .un.sun_family = AF_UNIX, - .un.sun_path = "/run/systemd/journal/socket", - }; - int r; if (journal_fd >= 0) @@ -216,10 +203,9 @@ static int log_open_journal(void) { goto fail; } - if (connect(journal_fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0) { - r = -errno; + r = connect_unix_path(journal_fd, AT_FDCWD, "/run/systemd/journal/socket"); + if (r < 0) goto fail; - } return 0; diff --git a/src/core/execute.c b/src/core/execute.c index 2762b10287..581c64480e 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -277,8 +277,6 @@ static int connect_journal_socket( uid_t uid, gid_t gid) { - union sockaddr_union sa; - socklen_t sa_len; uid_t olduid = UID_INVALID; gid_t oldgid = GID_INVALID; const char *j; @@ -287,10 +285,6 @@ static int connect_journal_socket( j = log_namespace ? strjoina("/run/systemd/journal.", log_namespace, "/stdout") : "/run/systemd/journal/stdout"; - r = sockaddr_un_set_path(&sa.un, j); - if (r < 0) - return r; - sa_len = r; if (gid_is_valid(gid)) { oldgid = getgid(); @@ -308,10 +302,10 @@ static int connect_journal_socket( } } - r = RET_NERRNO(connect(fd, &sa.sa, sa_len)); + r = connect_unix_path(fd, AT_FDCWD, j); - /* If we fail to restore the uid or gid, things will likely - fail later on. This should only happen if an LSM interferes. */ + /* If we fail to restore the uid or gid, things will likely fail later on. This should only happen if + an LSM interferes. */ if (uid_is_valid(uid)) (void) seteuid(olduid); @@ -389,8 +383,6 @@ 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; - socklen_t sa_len; _cleanup_close_ int fd = -1; int r; @@ -408,18 +400,17 @@ static int acquire_path(const char *path, int flags, mode_t mode) { /* So, it appears the specified path could be an AF_UNIX socket. Let's see if we can connect to it. */ - r = sockaddr_un_set_path(&sa.un, path); - if (r < 0) - return r == -EINVAL ? -ENXIO : r; - sa_len = r; - fd = socket(AF_UNIX, SOCK_STREAM, 0); if (fd < 0) return -errno; - if (connect(fd, &sa.sa, sa_len) < 0) - return errno == EINVAL ? -ENXIO : -errno; /* Propagate initial error if we get EINVAL, i.e. we have - * indication that this wasn't an AF_UNIX socket after all */ + r = connect_unix_path(fd, AT_FDCWD, path); + if (IN_SET(r, -ENOTSOCK, -EINVAL)) + /* Propagate initial error if we get ENOTSOCK or EINVAL, i.e. we have indication that this + * wasn't an AF_UNIX socket after all */ + return -ENXIO; + if (r < 0) + return r; if ((flags & O_ACCMODE) == O_RDONLY) r = shutdown(fd, SHUT_WR); diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c index 003d4f74d1..c9747416ad 100644 --- a/src/coredump/coredump.c +++ b/src/coredump/coredump.c @@ -1055,11 +1055,6 @@ finish: } static int send_iovec(const struct iovec_wrapper *iovw, int input_fd) { - - static const union sockaddr_union sa = { - .un.sun_family = AF_UNIX, - .un.sun_path = "/run/systemd/coredump", - }; _cleanup_close_ int fd = -1; int r; @@ -1070,8 +1065,9 @@ static int send_iovec(const struct iovec_wrapper *iovw, int input_fd) { if (fd < 0) return log_error_errno(errno, "Failed to create coredump socket: %m"); - if (connect(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0) - return log_error_errno(errno, "Failed to connect to coredump service: %m"); + r = connect_unix_path(fd, AT_FDCWD, "/run/systemd/coredump"); + if (r < 0) + return log_error_errno(r, "Failed to connect to coredump service: %m"); for (size_t i = 0; i < iovw->count; i++) { struct msghdr mh = { diff --git a/src/fsck/fsck.c b/src/fsck/fsck.c index 745d01ff50..46ccc9781f 100644 --- a/src/fsck/fsck.c +++ b/src/fsck/fsck.c @@ -226,20 +226,17 @@ static int process_progress(int fd, FILE* console) { } static int fsck_progress_socket(void) { - static const union sockaddr_union sa = { - .un.sun_family = AF_UNIX, - .un.sun_path = "/run/systemd/fsck.progress", - }; - _cleanup_close_ int fd = -1; + int r; 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) - 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); + r = connect_unix_path(fd, AT_FDCWD, "/run/systemd/fsck.progress"); + if (r < 0) + return log_full_errno(IN_SET(r, -ECONNREFUSED, -ENOENT) ? LOG_DEBUG : LOG_WARNING, + r, "Failed to connect to progress socket, ignoring: %m"); return TAKE_FD(fd); } diff --git a/src/libsystemd/sd-journal/journal-send.c b/src/libsystemd/sd-journal/journal-send.c index 1e10ed5524..e1c40702d3 100644 --- a/src/libsystemd/sd-journal/journal-send.c +++ b/src/libsystemd/sd-journal/journal-send.c @@ -408,10 +408,6 @@ _public_ int sd_journal_perror(const char *message) { } _public_ int sd_journal_stream_fd(const char *identifier, int priority, int level_prefix) { - static const union sockaddr_union sa = { - .un.sun_family = AF_UNIX, - .un.sun_path = "/run/systemd/journal/stdout", - }; _cleanup_close_ int fd = -1; char *header; size_t l; @@ -424,9 +420,9 @@ _public_ int sd_journal_stream_fd(const char *identifier, int priority, int leve if (fd < 0) return -errno; - r = connect(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)); + r = connect_unix_path(fd, AT_FDCWD, "/run/systemd/journal/stdout"); if (r < 0) - return -errno; + return r; if (shutdown(fd, SHUT_RD) < 0) return -errno; diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index c5fd978395..8e3c6522e4 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -5387,12 +5387,6 @@ static int initialize_rlimits(void) { } static int cant_be_in_netns(void) { - union sockaddr_union sa = { - .un = { - .sun_family = AF_UNIX, - .sun_path = "/run/udev/control", - }, - }; char udev_path[STRLEN("/proc//ns/net") + DECIMAL_STR_MAX(pid_t)]; _cleanup_free_ char *udev_ns = NULL, *our_ns = NULL; _cleanup_close_ int fd = -1; @@ -5410,13 +5404,13 @@ static int cant_be_in_netns(void) { if (fd < 0) return log_error_errno(errno, "Failed to allocate udev control socket: %m"); - if (connect(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0) { - - if (errno == ENOENT || ERRNO_IS_DISCONNECT(errno)) + r = connect_unix_path(fd, AT_FDCWD, "/run/udev/control"); + if (r < 0) { + if (r == -ENOENT || ERRNO_IS_DISCONNECT(r)) return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Sorry, but --image= requires access to the host's /run/ hierarchy, since we need access to udev."); - return log_error_errno(errno, "Failed to connect socket to udev control socket: %m"); + return log_error_errno(r, "Failed to connect socket to udev control socket: %m"); } r = getpeercred(fd, &ucred); diff --git a/src/shared/nscd-flush.c b/src/shared/nscd-flush.c index 95dfe24b22..9b0ba2d67a 100644 --- a/src/shared/nscd-flush.c +++ b/src/shared/nscd-flush.c @@ -1,4 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include #include #include "fd-util.h" @@ -18,17 +20,12 @@ struct nscdInvalidateRequest { char dbname[]; }; -static const union sockaddr_union nscd_sa = { - .un.sun_family = AF_UNIX, - .un.sun_path = "/run/nscd/socket", -}; - static int nscd_flush_cache_one(const char *database, usec_t end) { size_t req_size, has_written = 0, has_read = 0, l; struct nscdInvalidateRequest *req; _cleanup_close_ int fd = -1; int32_t resp; - int events; + int events, r; assert(database); @@ -60,11 +57,12 @@ static int nscd_flush_cache_one(const char *database, usec_t end) { * nice way to connect() to a server synchronously with a time limit that would also cover dealing with the * backlog limit. After all SO_RCVTIMEO and SR_SNDTIMEO don't apply to connect(), and alarm() is frickin' ugly * and not really reasonably usable from threads-aware code.) */ - if (connect(fd, &nscd_sa.sa, SOCKADDR_UN_LEN(nscd_sa.un)) < 0) { - if (errno == EAGAIN) - return log_debug_errno(errno, "nscd is overloaded (backlog limit reached) and refuses to take further connections: %m"); - if (errno != EINPROGRESS) - return log_debug_errno(errno, "Failed to connect to nscd socket: %m"); + r = connect_unix_path(fd, AT_FDCWD, "/run/nscd/socket"); + if (r < 0) { + if (r == -EAGAIN) + return log_debug_errno(r, "nscd is overloaded (backlog limit reached) and refuses to take further connections: %m"); + if (r != -EINPROGRESS) + return log_debug_errno(r, "Failed to connect to nscd socket: %m"); /* Continue in case of EINPROGRESS, but don't bother with send() or recv() until being notified that * establishing the connection is complete. */ diff --git a/src/shared/varlink.c b/src/shared/varlink.c index bae2031d0c..104bd5717f 100644 --- a/src/shared/varlink.c +++ b/src/shared/varlink.c @@ -271,17 +271,11 @@ static int varlink_new(Varlink **ret) { int varlink_connect_address(Varlink **ret, const char *address) { _cleanup_(varlink_unrefp) Varlink *v = NULL; union sockaddr_union sockaddr; - socklen_t sockaddr_len; int r; assert_return(ret, -EINVAL); assert_return(address, -EINVAL); - r = sockaddr_un_set_path(&sockaddr.un, address); - if (r < 0) - return log_debug_errno(r, "Failed to set socket address '%s': %m", address); - sockaddr_len = r; - r = varlink_new(&v); if (r < 0) return log_debug_errno(r, "Failed to create varlink object: %m"); @@ -292,9 +286,21 @@ int varlink_connect_address(Varlink **ret, const char *address) { v->fd = fd_move_above_stdio(v->fd); - if (connect(v->fd, &sockaddr.sa, sockaddr_len) < 0) { - if (!IN_SET(errno, EAGAIN, EINPROGRESS)) - return log_debug_errno(errno, "Failed to connect to %s: %m", address); + r = sockaddr_un_set_path(&sockaddr.un, address); + if (r < 0) { + if (r != -ENAMETOOLONG) + return log_debug_errno(r, "Failed to set socket address '%s': %m", address); + + /* This is a file system path, and too long to fit into sockaddr_un. Let's connect via O_PATH + * to this socket. */ + + r = connect_unix_path(v->fd, AT_FDCWD, address); + } else + r = RET_NERRNO(connect(v->fd, &sockaddr.sa, r)); + + if (r < 0) { + if (!IN_SET(r, -EAGAIN, -EINPROGRESS)) + return log_debug_errno(r, "Failed to connect to %s: %m", address); v->connecting = true; /* We are asynchronously connecting, i.e. the connect() is being * processed in the background. As long as that's the case the socket diff --git a/src/userdb/userdbctl.c b/src/userdb/userdbctl.c index eddbe765b0..1930fb916b 100644 --- a/src/userdb/userdbctl.c +++ b/src/userdb/userdbctl.c @@ -942,25 +942,19 @@ static int display_services(int argc, char *argv[], void *userdata) { FOREACH_DIRENT(de, d, return -errno) { _cleanup_free_ char *j = NULL, *no = NULL; - union sockaddr_union sockaddr; - socklen_t sockaddr_len; _cleanup_close_ int fd = -1; j = path_join("/run/systemd/userdb/", de->d_name); if (!j) return log_oom(); - r = sockaddr_un_set_path(&sockaddr.un, j); - if (r < 0) - return log_error_errno(r, "Path %s does not fit in AF_UNIX socket address: %m", j); - sockaddr_len = r; - fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0); if (fd < 0) return log_error_errno(errno, "Failed to allocate AF_UNIX/SOCK_STREAM socket: %m"); - if (connect(fd, &sockaddr.sa, sockaddr_len) < 0) { - no = strjoin("No (", errno_to_name(errno), ")"); + r = connect_unix_path(fd, dirfd(d), de->d_name); + if (r < 0) { + no = strjoin("No (", errno_to_name(r), ")"); if (!no) return log_oom(); }