summaryrefslogtreecommitdiff
path: root/src/basic
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2023-04-16 16:28:26 +0900
committerGitHub <noreply@github.com>2023-04-16 16:28:26 +0900
commitd8e75260e9667225638e32cd1e4cf897cb7b7adb (patch)
treeafdd17ba5403d479fed7f5187b3179406db18f2a /src/basic
parent23603bc67f86384a037b287f66b13db6482feafe (diff)
parentb5d39bb3cae7e36c284fcfcc87a42ff8a2bae7f5 (diff)
downloadsystemd-d8e75260e9667225638e32cd1e4cf897cb7b7adb.tar.gz
Merge pull request #27253 from yuwata/cmsg-find-and-copy-data
socket-util: introduce CMSG_FIND_AND_COPY_DATA()
Diffstat (limited to 'src/basic')
-rw-r--r--src/basic/socket-util.c18
-rw-r--r--src/basic/socket-util.h9
2 files changed, 25 insertions, 2 deletions
diff --git a/src/basic/socket-util.c b/src/basic/socket-util.c
index b35de4dad6..5b76948c06 100644
--- a/src/basic/socket-util.c
+++ b/src/basic/socket-util.c
@@ -1171,6 +1171,24 @@ struct cmsghdr* cmsg_find(struct msghdr *mh, int level, int type, socklen_t leng
return NULL;
}
+void* cmsg_find_and_copy_data(struct msghdr *mh, int level, int type, void *buf, size_t buf_len) {
+ struct cmsghdr *cmsg;
+
+ assert(mh);
+ assert(buf);
+ assert(buf_len > 0);
+
+ /* This is similar to cmsg_find_data(), but copy the found data to buf. This should be typically used
+ * when reading possibly unaligned data such as timestamp, as time_t is 64bit and size_t is 32bit on
+ * RISCV32. See issue #27241. */
+
+ cmsg = cmsg_find(mh, level, type, CMSG_LEN(buf_len));
+ if (!cmsg)
+ return NULL;
+
+ return memcpy_safe(buf, CMSG_DATA(cmsg), buf_len);
+}
+
int socket_ioctl_fd(void) {
int fd;
diff --git a/src/basic/socket-util.h b/src/basic/socket-util.h
index 7d504319a8..b323b1b99f 100644
--- a/src/basic/socket-util.h
+++ b/src/basic/socket-util.h
@@ -183,17 +183,22 @@ int flush_accept(int fd);
* riscv32. */
#define CMSG_TYPED_DATA(cmsg, type) \
({ \
- struct cmsghdr *_cmsg = cmsg; \
- assert_cc(__alignof__(type) <= __alignof__(struct cmsghdr)); \
+ struct cmsghdr *_cmsg = (cmsg); \
+ assert_cc(alignof(type) <= alignof(struct cmsghdr)); \
_cmsg ? CAST_ALIGN_PTR(type, CMSG_DATA(_cmsg)) : (type*) NULL; \
})
struct cmsghdr* cmsg_find(struct msghdr *mh, int level, int type, socklen_t length);
+void* cmsg_find_and_copy_data(struct msghdr *mh, int level, int type, void *buf, size_t buf_len);
/* Type-safe, dereferencing version of cmsg_find() */
#define CMSG_FIND_DATA(mh, level, type, ctype) \
CMSG_TYPED_DATA(cmsg_find(mh, level, type, CMSG_LEN(sizeof(ctype))), ctype)
+/* Type-safe version of cmsg_find_and_copy_data() */
+#define CMSG_FIND_AND_COPY_DATA(mh, level, type, ctype) \
+ (ctype*) cmsg_find_and_copy_data(mh, level, type, &(ctype){}, sizeof(ctype))
+
/* 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. */