summaryrefslogtreecommitdiff
path: root/src/basic/socket-util.h
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2020-04-24 23:54:25 +0200
committerLennart Poettering <lennart@poettering.net>2020-05-07 14:39:44 +0200
commitfb29cdbef21f1d66e2ebe600601897b6578d3959 (patch)
treeb0e0b17b4259ea901f706f8e365ed3b3817f12dd /src/basic/socket-util.h
parent0d9d333672167f7c4586c1708eee53066ce8f55d (diff)
downloadsystemd-fb29cdbef21f1d66e2ebe600601897b6578d3959.tar.gz
tree-wide: make sure our control buffers are properly aligned
We always need to make them unions with a "struct cmsghdr" in them, so that things properly aligned. Otherwise we might end up at an unaligned address and the counting goes all wrong, possibly making the kernel refuse our buffers. Also, let's make sure we initialize the control buffers to zero when sending, but leave them uninitialized when reading. Both the alignment and the initialization thing is mentioned in the cmsg(3) man page.
Diffstat (limited to 'src/basic/socket-util.h')
-rw-r--r--src/basic/socket-util.h11
1 files changed, 11 insertions, 0 deletions
diff --git a/src/basic/socket-util.h b/src/basic/socket-util.h
index fba4efef81..6f366c0429 100644
--- a/src/basic/socket-util.h
+++ b/src/basic/socket-util.h
@@ -166,6 +166,17 @@ struct cmsghdr* cmsg_find(struct msghdr *mh, int level, int type, socklen_t leng
(ctype*) (_found ? CMSG_DATA(_found) : NULL); \
})
+/* Resolves to a type that can carry cmsghdr structures. Make sure things are properly aligned, i.e. the type
+ * itself is placed properly in memory and the size is also aligned to what's appropriate for "cmsghdr"
+ * structures. */
+#define CMSG_BUFFER_TYPE(size) \
+ union { \
+ struct cmsghdr cmsghdr; \
+ uint8_t buf[size]; \
+ uint8_t align_check[(size) >= CMSG_SPACE(0) && \
+ (size) == CMSG_ALIGN(size) ? 1 : -1]; \
+ }
+
/*
* Certain hardware address types (e.g Infiniband) do not fit into sll_addr
* (8 bytes) and run over the structure. This macro returns the correct size that