1 From 9365e296fe281da45797af89a97627e872fc019d Mon Sep 17 00:00:00 2001
2 From: Yu Watanabe <watanabe.yu+github@gmail.com>
3 Date: Sun, 29 Aug 2021 20:50:49 +0900
4 Subject: [PATCH] socket-util: introduce CMSG_SPACE_TIMEVAL/TIMESPEC macro to
5 support additional 64bit timeval or timespec
7 Fixes #20482 and #20564.
9 src/basic/socket-util.h | 22 ++++++++++++++++++++++
10 src/journal/journald-server.c | 2 +-
11 src/libsystemd-network/icmp6-util.c | 2 +-
12 src/timesync/timesyncd-manager.c | 2 +-
13 4 files changed, 25 insertions(+), 3 deletions(-)
15 diff --git a/src/basic/socket-util.h b/src/basic/socket-util.h
16 index e857ae434192..a844c1151afd 100644
17 --- a/src/basic/socket-util.h
18 +++ b/src/basic/socket-util.h
19 @@ -277,6 +277,28 @@ static inline int getsockopt_int(int fd, int level, int optname, int *ret) {
20 int socket_bind_to_ifname(int fd, const char *ifname);
21 int socket_bind_to_ifindex(int fd, int ifindex);
23 +/* Define a 64bit version of timeval/timespec in any case, even on 32bit userspace. */
24 +struct timeval_large {
25 + uint64_t tvl_sec, tvl_usec;
27 +struct timespec_large {
28 + uint64_t tvl_sec, tvl_nsec;
31 +/* glibc duplicates timespec/timeval on certain 32bit archs, once in 32bit and once in 64bit.
32 + * See __convert_scm_timestamps() in glibc souce code. Hence, we need additional buffer space for them
33 + * to prevent from recvmsg_safe() returning -EXFULL. */
34 +#define CMSG_SPACE_TIMEVAL \
35 + ((sizeof(struct timeval) == sizeof(struct timeval_large)) ? \
36 + CMSG_SPACE(sizeof(struct timeval)) : \
37 + CMSG_SPACE(sizeof(struct timeval)) + \
38 + CMSG_SPACE(sizeof(struct timeval_large)))
39 +#define CMSG_SPACE_TIMESPEC \
40 + ((sizeof(struct timespec) == sizeof(struct timespec_large)) ? \
41 + CMSG_SPACE(sizeof(struct timespec)) : \
42 + CMSG_SPACE(sizeof(struct timespec)) + \
43 + CMSG_SPACE(sizeof(struct timespec_large)))
45 ssize_t recvmsg_safe(int sockfd, struct msghdr *msg, int flags);
47 int socket_get_family(int fd, int *ret);
48 diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c
49 index f2189964f0fa..9de31c2be070 100644
50 --- a/src/journal/journald-server.c
51 +++ b/src/journal/journald-server.c
52 @@ -1269,7 +1269,7 @@ int server_process_datagram(
53 * identical to NAME_MAX. For now we use that, but this should be updated one day when the final
55 CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct ucred)) +
56 - CMSG_SPACE(sizeof(struct timeval)) +
57 + CMSG_SPACE_TIMEVAL +
58 CMSG_SPACE(sizeof(int)) + /* fd */
59 CMSG_SPACE(NAME_MAX) /* selinux label */) control;
61 diff --git a/src/libsystemd-network/icmp6-util.c b/src/libsystemd-network/icmp6-util.c
62 index 0b8c3e4cc3d7..823be0f2752b 100644
63 --- a/src/libsystemd-network/icmp6-util.c
64 +++ b/src/libsystemd-network/icmp6-util.c
65 @@ -149,7 +149,7 @@ int icmp6_receive(int fd, void *buffer, size_t size, struct in6_addr *ret_dst,
66 triple_timestamp *ret_timestamp) {
68 CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(int)) + /* ttl */
69 - CMSG_SPACE(sizeof(struct timeval))) control;
70 + CMSG_SPACE_TIMEVAL) control;
71 struct iovec iov = {};
72 union sockaddr_union sa = {};
74 diff --git a/src/timesync/timesyncd-manager.c b/src/timesync/timesyncd-manager.c
75 index 3a89d9b1fac1..d7f511ee221c 100644
76 --- a/src/timesync/timesyncd-manager.c
77 +++ b/src/timesync/timesyncd-manager.c
78 @@ -416,7 +416,7 @@ static int manager_receive_response(sd_event_source *source, int fd, uint32_t re
80 .iov_len = sizeof(ntpmsg),
82 - CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct timespec))) control;
83 + CMSG_BUFFER_TYPE(CMSG_SPACE_TIMESPEC) control;
84 union sockaddr_union server_addr;
85 struct msghdr msghdr = {