From 15a3e96f9220c931507456764902ff05d7171318 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 15 Oct 2018 13:58:31 +0200 Subject: [PATCH] tree-wide: port various users over to sockaddr_un_set_path() CID 1396140 CID 1396141 --- src/core/dbus.c | 22 +++++-------- src/core/execute.c | 28 ++++++++-------- src/core/manager.c | 14 ++++---- src/fsck/fsck.c | 13 +++----- src/journal/journald-server.c | 24 ++++---------- src/libsystemd/sd-bus/test-bus-watch-bind.c | 10 +++--- src/libsystemd/sd-daemon/sd-daemon.c | 24 ++++---------- src/login/pam_systemd.c | 12 +++---- src/reply-password/reply-password.c | 11 ++++--- src/shared/ask-password-api.c | 33 ++++++++----------- src/socket-proxy/socket-proxyd.c | 19 +++++------ .../tty-ask-password-agent.c | 12 ++++--- 12 files changed, 93 insertions(+), 129 deletions(-) diff --git a/src/core/dbus.c b/src/core/dbus.c index d4b74bbd3b..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,12 +989,9 @@ 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) { @@ -1005,11 +999,11 @@ int bus_init_private(Manager *m) { 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) sockaddr_un_unlink(&sa.un); 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 9c8b7107d4..3bef345957 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -872,10 +872,9 @@ 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, - }; + union sockaddr_union sa = {}; static const int one = 1; + int salen; /* First free all secondary fields */ m->notify_socket = mfree(m->notify_socket); @@ -891,13 +890,16 @@ 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); - 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)); if (r < 0) 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/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/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/login/pam_systemd.c b/src/login/pam_systemd.c index 90ccbd7a83..8fc436c9d9 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/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/shared/ask-password-api.c b/src/shared/ask-password-api.c index 682dc754fc..2581fca013 100644 --- a/src/shared/ask-password-api.c +++ b/src/shared/ask-password-api.c @@ -451,41 +451,36 @@ 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) 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/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;