mirror of
https://github.com/Dasharo/systemd.git
synced 2026-03-06 15:02:31 -08:00
tree-wide: introduce new SOCKADDR_UN_LEN() macro, and use it everywhere
The macro determines the right length of a AF_UNIX "struct sockaddr_un" to pass to connect() or bind(). It automatically figures out if the socket refers to an abstract namespace socket, or a socket in the file system, and properly handles the full length of the path field. This macro is not only safer, but also simpler to use, than the usual offsetof() + strlen() logic.
This commit is contained in:
@@ -165,7 +165,7 @@ static int log_open_syslog(void) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (connect(syslog_fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)) < 0) {
|
||||
if (connect(syslog_fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0) {
|
||||
safe_close(syslog_fd);
|
||||
|
||||
/* Some legacy syslog systems still use stream
|
||||
@@ -177,7 +177,7 @@ static int log_open_syslog(void) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (connect(syslog_fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)) < 0) {
|
||||
if (connect(syslog_fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0) {
|
||||
r = -errno;
|
||||
goto fail;
|
||||
}
|
||||
@@ -215,7 +215,7 @@ static int log_open_journal(void) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (connect(journal_fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)) < 0) {
|
||||
if (connect(journal_fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0) {
|
||||
r = -errno;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@@ -137,3 +137,14 @@ ssize_t next_datagram_size_fd(int fd);
|
||||
|
||||
#define CMSG_FOREACH(cmsg, mh) \
|
||||
for ((cmsg) = CMSG_FIRSTHDR(mh); (cmsg); (cmsg) = CMSG_NXTHDR((mh), (cmsg)))
|
||||
|
||||
/* Covers only file system and abstract AF_UNIX socket addresses, but not unnamed socket addresses. */
|
||||
#define SOCKADDR_UN_LEN(sa) \
|
||||
({ \
|
||||
const struct sockaddr_un *_sa = &(sa); \
|
||||
assert(_sa->sun_family == AF_UNIX); \
|
||||
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))); \
|
||||
})
|
||||
|
||||
@@ -52,7 +52,7 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
l = strlen(argv[1]);
|
||||
|
||||
n = sendto(fd, argv[1], l, 0, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path));
|
||||
n = sendto(fd, argv[1], l, 0, &sa.sa, SOCKADDR_UN_LEN(sa.un));
|
||||
if (n < 0) {
|
||||
log_debug_errno(errno, "Failed to send cgroups agent message: %m");
|
||||
return EXIT_FAILURE;
|
||||
|
||||
@@ -975,7 +975,7 @@ static int bus_init_private(Manager *m) {
|
||||
return 0;
|
||||
|
||||
strcpy(sa.un.sun_path, "/run/systemd/private");
|
||||
salen = offsetof(union sockaddr_union, un.sun_path) + strlen("/run/systemd/private");
|
||||
salen = SOCKADDR_UN_LEN(sa.un);
|
||||
} else {
|
||||
size_t left = sizeof(sa.un.sun_path);
|
||||
char *p = sa.un.sun_path;
|
||||
|
||||
@@ -271,7 +271,7 @@ static int connect_journal_socket(int fd, uid_t uid, gid_t gid) {
|
||||
}
|
||||
}
|
||||
|
||||
r = connect(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path));
|
||||
r = connect(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un));
|
||||
if (r < 0)
|
||||
r = -errno;
|
||||
|
||||
|
||||
@@ -705,7 +705,7 @@ static int manager_setup_notify(Manager *m) {
|
||||
(void) unlink(m->notify_socket);
|
||||
|
||||
strncpy(sa.un.sun_path, m->notify_socket, sizeof(sa.un.sun_path)-1);
|
||||
r = bind(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path));
|
||||
r = bind(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un));
|
||||
if (r < 0)
|
||||
return log_error_errno(errno, "bind(%s) failed: %m", sa.un.sun_path);
|
||||
|
||||
@@ -782,7 +782,7 @@ static int manager_setup_cgroups_agent(Manager *m) {
|
||||
|
||||
/* Only allow root to connect to this socket */
|
||||
RUN_WITH_UMASK(0077)
|
||||
r = bind(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path));
|
||||
r = bind(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un));
|
||||
if (r < 0)
|
||||
return log_error_errno(errno, "bind(%s) failed: %m", sa.un.sun_path);
|
||||
|
||||
@@ -2245,11 +2245,10 @@ void manager_send_unit_audit(Manager *m, Unit *u, int type, bool success) {
|
||||
}
|
||||
|
||||
void manager_send_unit_plymouth(Manager *m, Unit *u) {
|
||||
union sockaddr_union sa = PLYMOUTH_SOCKET;
|
||||
|
||||
int n = 0;
|
||||
static const union sockaddr_union sa = PLYMOUTH_SOCKET;
|
||||
_cleanup_free_ char *message = NULL;
|
||||
_cleanup_close_ int fd = -1;
|
||||
int n = 0;
|
||||
|
||||
/* Don't generate plymouth events if the service was already
|
||||
* started and we're just deserializing */
|
||||
@@ -2275,7 +2274,7 @@ void manager_send_unit_plymouth(Manager *m, Unit *u) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (connect(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + 1 + strlen(sa.un.sun_path+1)) < 0) {
|
||||
if (connect(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0) {
|
||||
|
||||
if (!IN_SET(errno, EPIPE, EAGAIN, ENOENT, ECONNREFUSED, ECONNRESET, ECONNABORTED))
|
||||
log_error_errno(errno, "connect() failed: %m");
|
||||
|
||||
@@ -847,7 +847,7 @@ static int send_iovec(const struct iovec iovec[], size_t n_iovec, int input_fd)
|
||||
if (fd < 0)
|
||||
return log_error_errno(errno, "Failed to create coredump socket: %m");
|
||||
|
||||
if (connect(fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path)) < 0)
|
||||
if (connect(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0)
|
||||
return log_error_errno(errno, "Failed to connect to coredump service: %m");
|
||||
|
||||
for (i = 0; i < n_iovec; i++) {
|
||||
|
||||
@@ -262,7 +262,7 @@ static int fsck_progress_socket(void) {
|
||||
if (fd < 0)
|
||||
return log_warning_errno(errno, "socket(): %m");
|
||||
|
||||
if (connect(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)) < 0) {
|
||||
if (connect(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0) {
|
||||
r = log_full_errno(errno == ECONNREFUSED || errno == ENOENT ? LOG_DEBUG : LOG_WARNING,
|
||||
errno, "Failed to connect to progress socket %s, ignoring: %m", sa.un.sun_path);
|
||||
safe_close(fd);
|
||||
|
||||
@@ -677,7 +677,7 @@ static int manager_new(Manager **ret) {
|
||||
(void) mkdir_parents_label(sa.un.sun_path, 0755);
|
||||
(void) unlink(sa.un.sun_path);
|
||||
|
||||
if (bind(m->notify_fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path)) < 0)
|
||||
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)
|
||||
|
||||
@@ -208,13 +208,13 @@ _public_ int sd_journal_sendv(const struct iovec *iov, int n) {
|
||||
struct iovec *w;
|
||||
uint64_t *l;
|
||||
int i, j = 0;
|
||||
struct sockaddr_un sa = {
|
||||
.sun_family = AF_UNIX,
|
||||
.sun_path = "/run/systemd/journal/socket",
|
||||
static const union sockaddr_union sa = {
|
||||
.un.sun_family = AF_UNIX,
|
||||
.un.sun_path = "/run/systemd/journal/socket",
|
||||
};
|
||||
struct msghdr mh = {
|
||||
.msg_name = &sa,
|
||||
.msg_namelen = offsetof(struct sockaddr_un, sun_path) + strlen(sa.sun_path),
|
||||
.msg_name = (struct sockaddr*) &sa.sa,
|
||||
.msg_namelen = SOCKADDR_UN_LEN(sa.un),
|
||||
};
|
||||
ssize_t k;
|
||||
bool have_syslog_identifier = false;
|
||||
@@ -392,7 +392,7 @@ _public_ int sd_journal_perror(const char *message) {
|
||||
}
|
||||
|
||||
_public_ int sd_journal_stream_fd(const char *identifier, int priority, int level_prefix) {
|
||||
union sockaddr_union sa = {
|
||||
static const union sockaddr_union sa = {
|
||||
.un.sun_family = AF_UNIX,
|
||||
.un.sun_path = "/run/systemd/journal/stdout",
|
||||
};
|
||||
@@ -408,7 +408,7 @@ _public_ int sd_journal_stream_fd(const char *identifier, int priority, int leve
|
||||
if (fd < 0)
|
||||
return -errno;
|
||||
|
||||
r = connect(fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path));
|
||||
r = connect(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un));
|
||||
if (r < 0)
|
||||
return -errno;
|
||||
|
||||
|
||||
@@ -448,24 +448,24 @@ void server_process_native_file(
|
||||
}
|
||||
|
||||
int server_open_native_socket(Server*s) {
|
||||
|
||||
static const union sockaddr_union sa = {
|
||||
.un.sun_family = AF_UNIX,
|
||||
.un.sun_path = "/run/systemd/journal/socket",
|
||||
};
|
||||
static const int one = 1;
|
||||
int r;
|
||||
|
||||
assert(s);
|
||||
|
||||
if (s->native_fd < 0) {
|
||||
union sockaddr_union sa = {
|
||||
.un.sun_family = AF_UNIX,
|
||||
.un.sun_path = "/run/systemd/journal/socket",
|
||||
};
|
||||
|
||||
s->native_fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
|
||||
if (s->native_fd < 0)
|
||||
return log_error_errno(errno, "socket() failed: %m");
|
||||
|
||||
unlink(sa.un.sun_path);
|
||||
(void) unlink(sa.un.sun_path);
|
||||
|
||||
r = bind(s->native_fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path));
|
||||
r = bind(s->native_fd, &sa.sa, SOCKADDR_UN_LEN(sa.un));
|
||||
if (r < 0)
|
||||
return log_error_errno(errno, "bind(%s) failed: %m", sa.un.sun_path);
|
||||
|
||||
|
||||
@@ -1696,7 +1696,7 @@ static int server_connect_notify(Server *s) {
|
||||
if (sa.un.sun_path[0] == '@')
|
||||
sa.un.sun_path[0] = 0;
|
||||
|
||||
r = connect(s->notify_fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(e));
|
||||
r = connect(s->notify_fd, &sa.sa, SOCKADDR_UN_LEN(sa.un));
|
||||
if (r < 0)
|
||||
return log_error_errno(errno, "Failed to connect to notify socket: %m");
|
||||
|
||||
|
||||
@@ -700,23 +700,22 @@ fail:
|
||||
}
|
||||
|
||||
int server_open_stdout_socket(Server *s) {
|
||||
static const union sockaddr_union sa = {
|
||||
.un.sun_family = AF_UNIX,
|
||||
.un.sun_path = "/run/systemd/journal/stdout",
|
||||
};
|
||||
int r;
|
||||
|
||||
assert(s);
|
||||
|
||||
if (s->stdout_fd < 0) {
|
||||
union sockaddr_union sa = {
|
||||
.un.sun_family = AF_UNIX,
|
||||
.un.sun_path = "/run/systemd/journal/stdout",
|
||||
};
|
||||
|
||||
s->stdout_fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
|
||||
if (s->stdout_fd < 0)
|
||||
return log_error_errno(errno, "socket() failed: %m");
|
||||
|
||||
unlink(sa.un.sun_path);
|
||||
(void) unlink(sa.un.sun_path);
|
||||
|
||||
r = bind(s->stdout_fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path));
|
||||
r = bind(s->stdout_fd, &sa.sa, SOCKADDR_UN_LEN(sa.un));
|
||||
if (r < 0)
|
||||
return log_error_errno(errno, "bind(%s) failed: %m", sa.un.sun_path);
|
||||
|
||||
|
||||
@@ -52,8 +52,7 @@ static void forward_syslog_iovec(Server *s, const struct iovec *iovec, unsigned
|
||||
.msg_iov = (struct iovec *) iovec,
|
||||
.msg_iovlen = n_iovec,
|
||||
.msg_name = (struct sockaddr*) &sa.sa,
|
||||
.msg_namelen = offsetof(union sockaddr_union, un.sun_path)
|
||||
+ strlen("/run/systemd/journal/syslog"),
|
||||
.msg_namelen = SOCKADDR_UN_LEN(sa.un),
|
||||
};
|
||||
struct cmsghdr *cmsg;
|
||||
union {
|
||||
@@ -383,24 +382,24 @@ void server_process_syslog_message(
|
||||
}
|
||||
|
||||
int server_open_syslog_socket(Server *s) {
|
||||
|
||||
static const union sockaddr_union sa = {
|
||||
.un.sun_family = AF_UNIX,
|
||||
.un.sun_path = "/run/systemd/journal/dev-log",
|
||||
};
|
||||
static const int one = 1;
|
||||
int r;
|
||||
|
||||
assert(s);
|
||||
|
||||
if (s->syslog_fd < 0) {
|
||||
static const union sockaddr_union sa = {
|
||||
.un.sun_family = AF_UNIX,
|
||||
.un.sun_path = "/run/systemd/journal/dev-log",
|
||||
};
|
||||
|
||||
s->syslog_fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
|
||||
if (s->syslog_fd < 0)
|
||||
return log_error_errno(errno, "socket() failed: %m");
|
||||
|
||||
unlink(sa.un.sun_path);
|
||||
(void) unlink(sa.un.sun_path);
|
||||
|
||||
r = bind(s->syslog_fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path));
|
||||
r = bind(s->syslog_fd, &sa.sa, SOCKADDR_UN_LEN(sa.un));
|
||||
if (r < 0)
|
||||
return log_error_errno(errno, "bind(%s) failed: %m", sa.un.sun_path);
|
||||
|
||||
@@ -437,6 +436,7 @@ int server_open_syslog_socket(Server *s) {
|
||||
|
||||
void server_maybe_warn_forward_syslog_missed(Server *s) {
|
||||
usec_t n;
|
||||
|
||||
assert(s);
|
||||
|
||||
if (s->n_forward_syslog_missed <= 0)
|
||||
|
||||
@@ -836,7 +836,7 @@ static int parse_container_unix_address(sd_bus *b, const char **p, char **guid)
|
||||
|
||||
b->sockaddr.un.sun_family = AF_UNIX;
|
||||
strncpy(b->sockaddr.un.sun_path, "/var/run/dbus/system_bus_socket", sizeof(b->sockaddr.un.sun_path));
|
||||
b->sockaddr_size = offsetof(struct sockaddr_un, sun_path) + strlen("/var/run/dbus/system_bus_socket");
|
||||
b->sockaddr_size = SOCKADDR_UN_LEN(b->sockaddr.un);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -458,9 +458,7 @@ _public_ int sd_pid_notify_with_fds(pid_t pid, int unset_environment, const char
|
||||
if (sockaddr.un.sun_path[0] == '@')
|
||||
sockaddr.un.sun_path[0] = 0;
|
||||
|
||||
msghdr.msg_namelen = offsetof(struct sockaddr_un, sun_path) + strlen(e);
|
||||
if (msghdr.msg_namelen > sizeof(struct sockaddr_un))
|
||||
msghdr.msg_namelen = sizeof(struct sockaddr_un);
|
||||
msghdr.msg_namelen = SOCKADDR_UN_LEN(sockaddr.un);
|
||||
|
||||
have_pid = pid != 0 && pid != getpid();
|
||||
|
||||
|
||||
@@ -150,7 +150,7 @@ static int get_seat_from_display(const char *display, const char **seat, uint32_
|
||||
if (fd < 0)
|
||||
return -errno;
|
||||
|
||||
if (connect(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)) < 0)
|
||||
if (connect(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0)
|
||||
return -errno;
|
||||
|
||||
r = getpeercred(fd, &ucred);
|
||||
|
||||
@@ -26,14 +26,12 @@
|
||||
#include "fd-util.h"
|
||||
#include "log.h"
|
||||
#include "macro.h"
|
||||
#include "socket-util.h"
|
||||
#include "string-util.h"
|
||||
#include "util.h"
|
||||
|
||||
static int send_on_socket(int fd, const char *socket_name, const void *packet, size_t size) {
|
||||
union {
|
||||
struct sockaddr sa;
|
||||
struct sockaddr_un un;
|
||||
} sa = {
|
||||
union sockaddr_union sa = {
|
||||
.un.sun_family = AF_UNIX,
|
||||
};
|
||||
|
||||
@@ -43,7 +41,7 @@ static int send_on_socket(int fd, const char *socket_name, const void *packet, s
|
||||
|
||||
strncpy(sa.un.sun_path, socket_name, sizeof(sa.un.sun_path));
|
||||
|
||||
if (sendto(fd, packet, size, MSG_NOSIGNAL, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(socket_name)) < 0)
|
||||
if (sendto(fd, packet, size, MSG_NOSIGNAL, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0)
|
||||
return log_error_errno(errno, "Failed to send: %m");
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -431,7 +431,7 @@ static int create_socket(char **name) {
|
||||
snprintf(sa.un.sun_path, sizeof(sa.un.sun_path)-1, "/run/systemd/ask-password/sck.%" PRIx64, random_u64());
|
||||
|
||||
RUN_WITH_UMASK(0177) {
|
||||
if (bind(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)) < 0)
|
||||
if (bind(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0)
|
||||
return -errno;
|
||||
}
|
||||
|
||||
|
||||
@@ -400,28 +400,19 @@ static int resolve_remote(Connection *c) {
|
||||
|
||||
union sockaddr_union sa = {};
|
||||
const char *node, *service;
|
||||
socklen_t salen;
|
||||
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)-1);
|
||||
sa.un.sun_path[sizeof(sa.un.sun_path)-1] = 0;
|
||||
|
||||
salen = offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path);
|
||||
|
||||
return connection_start(c, &sa.sa, salen);
|
||||
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 (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)-2);
|
||||
sa.un.sun_path[sizeof(sa.un.sun_path)-1] = 0;
|
||||
|
||||
salen = offsetof(union sockaddr_union, un.sun_path) + 1 + strlen(sa.un.sun_path + 1);
|
||||
|
||||
return connection_start(c, &sa.sa, salen);
|
||||
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));
|
||||
}
|
||||
|
||||
service = strrchr(arg_remote_host, ':');
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user