]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
tree-wide: use CMSG_SPACE() (and not CMSG_LEN()) to allocate control buffers
authorLennart Poettering <lennart@poettering.net>
Fri, 24 Apr 2020 21:36:03 +0000 (23:36 +0200)
committerLennart Poettering <lennart@poettering.net>
Thu, 7 May 2020 12:39:44 +0000 (14:39 +0200)
We need to use the CMSG_SPACE() macro to size the control buffers, not
CMSG_LEN(). The former is rounded up to next alignment boundary, the
latter is not. The former should be used for allocations, the latter for
encoding how much of it is actually initialized. See cmsg(3) man page
for details about this.

Given how confusing this is, I guess we don't have to be too ashamed
here, in most cases we actually did get this right.

src/libsystemd-network/sd-dhcp-client.c
src/libsystemd-network/sd-dhcp-server.c
src/libsystemd/sd-bus/bus-socket.c
src/resolve/resolved-manager.c

index 0cff6c4f33dfc165f65383c6124459e0a3c04e25..47f60d4a2a3ab655757cd6b6387357c88b2eeb23 100644 (file)
@@ -1899,7 +1899,7 @@ static int client_receive_message_raw(
 
         sd_dhcp_client *client = userdata;
         _cleanup_free_ DHCPPacket *packet = NULL;
-        uint8_t cmsgbuf[CMSG_LEN(sizeof(struct tpacket_auxdata))];
+        uint8_t cmsgbuf[CMSG_SPACE(sizeof(struct tpacket_auxdata))];
         struct iovec iov = {};
         struct msghdr msg = {
                 .msg_iov = &iov,
index 7fa0dc2812a60faceb10a67711a182e32d223aad..59792af68630a50886af97043730a2f2e8de1e4b 100644 (file)
@@ -267,7 +267,7 @@ static int dhcp_server_send_udp(sd_dhcp_server *server, be32_t destination,
                 .iov_base = message,
                 .iov_len = len,
         };
-        uint8_t cmsgbuf[CMSG_LEN(sizeof(struct in_pktinfo))] = {};
+        uint8_t cmsgbuf[CMSG_SPACE(sizeof(struct in_pktinfo))] = {};
         struct msghdr msg = {
                 .msg_name = &dest,
                 .msg_namelen = sizeof(dest.in),
@@ -970,7 +970,7 @@ int dhcp_server_handle_message(sd_dhcp_server *server, DHCPMessage *message,
 static int server_receive_message(sd_event_source *s, int fd,
                                   uint32_t revents, void *userdata) {
         _cleanup_free_ DHCPMessage *message = NULL;
-        uint8_t cmsgbuf[CMSG_LEN(sizeof(struct in_pktinfo))];
+        uint8_t cmsgbuf[CMSG_SPACE(sizeof(struct in_pktinfo))];
         sd_dhcp_server *server = userdata;
         struct iovec iov = {};
         struct msghdr msg = {
index b2b6732c31708dab52b21990ea63bcd32d0858c2..e336dbb62ed94c7fc864213500d638c8756ad2e8 100644 (file)
@@ -1037,8 +1037,10 @@ int bus_socket_write_message(sd_bus *bus, sd_bus_message *m, size_t *idx) {
                 if (m->n_fds > 0 && *idx == 0) {
                         struct cmsghdr *control;
 
-                        mh.msg_control = control = alloca(CMSG_SPACE(sizeof(int) * m->n_fds));
-                        mh.msg_controllen = control->cmsg_len = CMSG_LEN(sizeof(int) * m->n_fds);
+                        mh.msg_controllen = CMSG_SPACE(sizeof(int) * m->n_fds);
+                        mh.msg_control = alloca0(mh.msg_controllen);
+                        control = CMSG_FIRSTHDR(&mh);
+                        control->cmsg_len = CMSG_LEN(sizeof(int) * m->n_fds);
                         control->cmsg_level = SOL_SOCKET;
                         control->cmsg_type = SCM_RIGHTS;
                         memcpy(CMSG_DATA(control), m->fds, sizeof(int) * m->n_fds);
index 1849fc1b1d9f131249d454a3a8fe39bdf4a78025..69630cf49d31c3bd1be3c0669eb8dedf2e9becc4 100644 (file)
@@ -962,10 +962,10 @@ static int manager_ipv4_send(
                 struct in_pktinfo *pi;
 
                 mh.msg_control = &control;
-                mh.msg_controllen = CMSG_LEN(sizeof(struct in_pktinfo));
+                mh.msg_controllen = sizeof(control);
 
                 cmsg = CMSG_FIRSTHDR(&mh);
-                cmsg->cmsg_len = mh.msg_controllen;
+                cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
                 cmsg->cmsg_level = IPPROTO_IP;
                 cmsg->cmsg_type = IP_PKTINFO;
 
@@ -1021,10 +1021,10 @@ static int manager_ipv6_send(
                 struct in6_pktinfo *pi;
 
                 mh.msg_control = &control;
-                mh.msg_controllen = CMSG_LEN(sizeof(struct in6_pktinfo));
+                mh.msg_controllen = sizeof(control);
 
                 cmsg = CMSG_FIRSTHDR(&mh);
-                cmsg->cmsg_len = mh.msg_controllen;
+                cmsg->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
                 cmsg->cmsg_level = IPPROTO_IPV6;
                 cmsg->cmsg_type = IPV6_PKTINFO;