tree-wide: copy timestamp data from cmsg
authorYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 13 Apr 2023 09:02:48 +0000 (18:02 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Sun, 16 Apr 2023 04:26:58 +0000 (13:26 +0900)
On RISCV32, time_t is 64bit and size_t is 32bit, hence the timestamp
data in message header may not be aligned.

Fixes #27241.

src/journal/journald-server.c
src/libsystemd-network/icmp6-util.c
src/libsystemd-network/sd-dhcp6-client.c
src/timesync/timesyncd-manager.c

index b952269e2eb994142d0436c42d5a0feb259ee67b..7be3763f15cd071f40583a1a7b51de432bb1c281 100644 (file)
@@ -1417,7 +1417,7 @@ int server_process_datagram(
         size_t label_len = 0, m;
         Server *s = ASSERT_PTR(userdata);
         struct ucred *ucred = NULL;
-        struct timeval *tv = NULL;
+        struct timeval tv_buf, *tv = NULL;
         struct cmsghdr *cmsg;
         char *label = NULL;
         struct iovec iovec;
@@ -1493,10 +1493,10 @@ int server_process_datagram(
                         label = CMSG_TYPED_DATA(cmsg, char);
                         label_len = cmsg->cmsg_len - CMSG_LEN(0);
                 } else if (cmsg->cmsg_level == SOL_SOCKET &&
-                           cmsg->cmsg_type == SO_TIMESTAMP &&
+                           cmsg->cmsg_type == SCM_TIMESTAMP &&
                            cmsg->cmsg_len == CMSG_LEN(sizeof(struct timeval))) {
                         assert(!tv);
-                        tv = CMSG_TYPED_DATA(cmsg, struct timeval);
+                        tv = memcpy(&tv_buf, CMSG_DATA(cmsg), sizeof(struct timeval));
                 } else if (cmsg->cmsg_level == SOL_SOCKET &&
                          cmsg->cmsg_type == SCM_RIGHTS) {
                         assert(!fds);
index fba5c3bd96ceb319ad87216584f11f45383bd632..ecddab61e42381ca2aa6f0aa71436c313ce61f00 100644 (file)
@@ -199,9 +199,11 @@ int icmp6_receive(int fd, void *buffer, size_t size, struct in6_addr *ret_dst,
                 }
 
                 if (cmsg->cmsg_level == SOL_SOCKET &&
-                    cmsg->cmsg_type == SO_TIMESTAMP &&
-                    cmsg->cmsg_len == CMSG_LEN(sizeof(struct timeval)))
-                        triple_timestamp_from_realtime(&t, timeval_load(CMSG_TYPED_DATA(cmsg, struct timeval)));
+                    cmsg->cmsg_type == SCM_TIMESTAMP &&
+                    cmsg->cmsg_len == CMSG_LEN(sizeof(struct timeval))) {
+                        struct timeval *tv = memcpy(&(struct timeval) {}, CMSG_DATA(cmsg), sizeof(struct timeval));
+                        triple_timestamp_from_realtime(&t, timeval_load(tv));
+                }
         }
 
         if (!triple_timestamp_is_set(&t))
index 57dd91f81f3c45798c8053aef5fe893580cc1d98..6d62ba380b808638427ffbc0b92218692ebf1b49 100644 (file)
@@ -1276,7 +1276,6 @@ static int client_receive_message(
                 .msg_control = &control,
                 .msg_controllen = sizeof(control),
         };
-        struct cmsghdr *cmsg;
         triple_timestamp t = {};
         _cleanup_free_ DHCP6Message *message = NULL;
         struct in6_addr *server_address = NULL;
@@ -1320,12 +1319,9 @@ static int client_receive_message(
                 server_address = &sa.in6.sin6_addr;
         }
 
-        CMSG_FOREACH(cmsg, &msg) {
-                if (cmsg->cmsg_level == SOL_SOCKET &&
-                    cmsg->cmsg_type == SO_TIMESTAMP &&
-                    cmsg->cmsg_len == CMSG_LEN(sizeof(struct timeval)))
-                        triple_timestamp_from_realtime(&t, timeval_load(CMSG_TYPED_DATA(cmsg, struct timeval)));
-        }
+        struct timeval *tv = CMSG_FIND_AND_COPY_DATA(&msg, SOL_SOCKET, SCM_TIMESTAMP, struct timeval);
+        if (tv)
+                triple_timestamp_from_realtime(&t, timeval_load(tv));
 
         if (client->transaction_id != (message->transaction_id & htobe32(0x00ffffff)))
                 return 0;
index e024fa9715c5a6705bf1e53419b1698894d386f2..569389b9d484f71fd2e537f98c60833ebcdb9e9e 100644 (file)
@@ -446,7 +446,7 @@ static int manager_receive_response(sd_event_source *source, int fd, uint32_t re
                 return 0;
         }
 
-        recv_time = CMSG_FIND_DATA(&msghdr, SOL_SOCKET, SCM_TIMESTAMPNS, struct timespec);
+        recv_time = CMSG_FIND_AND_COPY_DATA(&msghdr, SOL_SOCKET, SCM_TIMESTAMPNS, struct timespec);
         if (!recv_time)
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Packet timestamp missing.");