Skip to content

Commit fc2fffe

Browse files
committed
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.
1 parent d8fdc62 commit fc2fffe

File tree

23 files changed

+87
-75
lines changed

23 files changed

+87
-75
lines changed

src/basic/log.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ static int log_open_syslog(void) {
165165
goto fail;
166166
}
167167

168-
if (connect(syslog_fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)) < 0) {
168+
if (connect(syslog_fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0) {
169169
safe_close(syslog_fd);
170170

171171
/* Some legacy syslog systems still use stream
@@ -177,7 +177,7 @@ static int log_open_syslog(void) {
177177
goto fail;
178178
}
179179

180-
if (connect(syslog_fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)) < 0) {
180+
if (connect(syslog_fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0) {
181181
r = -errno;
182182
goto fail;
183183
}
@@ -215,7 +215,7 @@ static int log_open_journal(void) {
215215
goto fail;
216216
}
217217

218-
if (connect(journal_fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)) < 0) {
218+
if (connect(journal_fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0) {
219219
r = -errno;
220220
goto fail;
221221
}

src/basic/socket-util.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,3 +137,14 @@ ssize_t next_datagram_size_fd(int fd);
137137

138138
#define CMSG_FOREACH(cmsg, mh) \
139139
for ((cmsg) = CMSG_FIRSTHDR(mh); (cmsg); (cmsg) = CMSG_NXTHDR((mh), (cmsg)))
140+
141+
/* Covers only file system and abstract AF_UNIX socket addresses, but not unnamed socket addresses. */
142+
#define SOCKADDR_UN_LEN(sa) \
143+
({ \
144+
const struct sockaddr_un *_sa = &(sa); \
145+
assert(_sa->sun_family == AF_UNIX); \
146+
offsetof(struct sockaddr_un, sun_path) + \
147+
(_sa->sun_path[0] == 0 ? \
148+
1 + strnlen(_sa->sun_path+1, sizeof(_sa->sun_path)-1) : \
149+
strnlen(_sa->sun_path, sizeof(_sa->sun_path))); \
150+
})

src/cgroups-agent/cgroups-agent.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ int main(int argc, char *argv[]) {
5252

5353
l = strlen(argv[1]);
5454

55-
n = sendto(fd, argv[1], l, 0, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path));
55+
n = sendto(fd, argv[1], l, 0, &sa.sa, SOCKADDR_UN_LEN(sa.un));
5656
if (n < 0) {
5757
log_debug_errno(errno, "Failed to send cgroups agent message: %m");
5858
return EXIT_FAILURE;

src/core/dbus.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -975,7 +975,7 @@ static int bus_init_private(Manager *m) {
975975
return 0;
976976

977977
strcpy(sa.un.sun_path, "/run/systemd/private");
978-
salen = offsetof(union sockaddr_union, un.sun_path) + strlen("/run/systemd/private");
978+
salen = SOCKADDR_UN_LEN(sa.un);
979979
} else {
980980
size_t left = sizeof(sa.un.sun_path);
981981
char *p = sa.un.sun_path;

src/core/execute.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ static int connect_journal_socket(int fd, uid_t uid, gid_t gid) {
271271
}
272272
}
273273

274-
r = connect(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path));
274+
r = connect(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un));
275275
if (r < 0)
276276
r = -errno;
277277

src/core/manager.c

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -705,7 +705,7 @@ static int manager_setup_notify(Manager *m) {
705705
(void) unlink(m->notify_socket);
706706

707707
strncpy(sa.un.sun_path, m->notify_socket, sizeof(sa.un.sun_path)-1);
708-
r = bind(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path));
708+
r = bind(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un));
709709
if (r < 0)
710710
return log_error_errno(errno, "bind(%s) failed: %m", sa.un.sun_path);
711711

@@ -782,7 +782,7 @@ static int manager_setup_cgroups_agent(Manager *m) {
782782

783783
/* Only allow root to connect to this socket */
784784
RUN_WITH_UMASK(0077)
785-
r = bind(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path));
785+
r = bind(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un));
786786
if (r < 0)
787787
return log_error_errno(errno, "bind(%s) failed: %m", sa.un.sun_path);
788788

@@ -2245,11 +2245,10 @@ void manager_send_unit_audit(Manager *m, Unit *u, int type, bool success) {
22452245
}
22462246

22472247
void manager_send_unit_plymouth(Manager *m, Unit *u) {
2248-
union sockaddr_union sa = PLYMOUTH_SOCKET;
2249-
2250-
int n = 0;
2248+
static const union sockaddr_union sa = PLYMOUTH_SOCKET;
22512249
_cleanup_free_ char *message = NULL;
22522250
_cleanup_close_ int fd = -1;
2251+
int n = 0;
22532252

22542253
/* Don't generate plymouth events if the service was already
22552254
* started and we're just deserializing */
@@ -2275,7 +2274,7 @@ void manager_send_unit_plymouth(Manager *m, Unit *u) {
22752274
return;
22762275
}
22772276

2278-
if (connect(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + 1 + strlen(sa.un.sun_path+1)) < 0) {
2277+
if (connect(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0) {
22792278

22802279
if (!IN_SET(errno, EPIPE, EAGAIN, ENOENT, ECONNREFUSED, ECONNRESET, ECONNABORTED))
22812280
log_error_errno(errno, "connect() failed: %m");

src/coredump/coredump.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -847,7 +847,7 @@ static int send_iovec(const struct iovec iovec[], size_t n_iovec, int input_fd)
847847
if (fd < 0)
848848
return log_error_errno(errno, "Failed to create coredump socket: %m");
849849

850-
if (connect(fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path)) < 0)
850+
if (connect(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0)
851851
return log_error_errno(errno, "Failed to connect to coredump service: %m");
852852

853853
for (i = 0; i < n_iovec; i++) {

src/fsck/fsck.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ static int fsck_progress_socket(void) {
262262
if (fd < 0)
263263
return log_warning_errno(errno, "socket(): %m");
264264

265-
if (connect(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)) < 0) {
265+
if (connect(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0) {
266266
r = log_full_errno(errno == ECONNREFUSED || errno == ENOENT ? LOG_DEBUG : LOG_WARNING,
267267
errno, "Failed to connect to progress socket %s, ignoring: %m", sa.un.sun_path);
268268
safe_close(fd);

src/import/importd.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -677,7 +677,7 @@ static int manager_new(Manager **ret) {
677677
(void) mkdir_parents_label(sa.un.sun_path, 0755);
678678
(void) unlink(sa.un.sun_path);
679679

680-
if (bind(m->notify_fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path)) < 0)
680+
if (bind(m->notify_fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0)
681681
return -errno;
682682

683683
if (setsockopt(m->notify_fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one)) < 0)

src/journal/journal-send.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -208,13 +208,13 @@ _public_ int sd_journal_sendv(const struct iovec *iov, int n) {
208208
struct iovec *w;
209209
uint64_t *l;
210210
int i, j = 0;
211-
struct sockaddr_un sa = {
212-
.sun_family = AF_UNIX,
213-
.sun_path = "/run/systemd/journal/socket",
211+
static const union sockaddr_union sa = {
212+
.un.sun_family = AF_UNIX,
213+
.un.sun_path = "/run/systemd/journal/socket",
214214
};
215215
struct msghdr mh = {
216-
.msg_name = &sa,
217-
.msg_namelen = offsetof(struct sockaddr_un, sun_path) + strlen(sa.sun_path),
216+
.msg_name = (struct sockaddr*) &sa.sa,
217+
.msg_namelen = SOCKADDR_UN_LEN(sa.un),
218218
};
219219
ssize_t k;
220220
bool have_syslog_identifier = false;
@@ -392,7 +392,7 @@ _public_ int sd_journal_perror(const char *message) {
392392
}
393393

394394
_public_ int sd_journal_stream_fd(const char *identifier, int priority, int level_prefix) {
395-
union sockaddr_union sa = {
395+
static const union sockaddr_union sa = {
396396
.un.sun_family = AF_UNIX,
397397
.un.sun_path = "/run/systemd/journal/stdout",
398398
};
@@ -408,7 +408,7 @@ _public_ int sd_journal_stream_fd(const char *identifier, int priority, int leve
408408
if (fd < 0)
409409
return -errno;
410410

411-
r = connect(fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path));
411+
r = connect(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un));
412412
if (r < 0)
413413
return -errno;
414414

0 commit comments

Comments
 (0)