From: Lennart Poettering Date: Fri, 24 Apr 2020 21:36:03 +0000 (+0200) Subject: tree-wide: use CMSG_SPACE() (and not CMSG_LEN()) to allocate control buffers X-Git-Tag: v246-rc1~411^2~2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=a258f4915a2674d77e656755e5a4fa23059f778a;p=thirdparty%2Fsystemd.git tree-wide: use CMSG_SPACE() (and not CMSG_LEN()) to allocate control buffers 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. --- diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c index 0cff6c4f33d..47f60d4a2a3 100644 --- a/src/libsystemd-network/sd-dhcp-client.c +++ b/src/libsystemd-network/sd-dhcp-client.c @@ -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, diff --git a/src/libsystemd-network/sd-dhcp-server.c b/src/libsystemd-network/sd-dhcp-server.c index 7fa0dc2812a..59792af6863 100644 --- a/src/libsystemd-network/sd-dhcp-server.c +++ b/src/libsystemd-network/sd-dhcp-server.c @@ -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 = { diff --git a/src/libsystemd/sd-bus/bus-socket.c b/src/libsystemd/sd-bus/bus-socket.c index b2b6732c317..e336dbb62ed 100644 --- a/src/libsystemd/sd-bus/bus-socket.c +++ b/src/libsystemd/sd-bus/bus-socket.c @@ -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); diff --git a/src/resolve/resolved-manager.c b/src/resolve/resolved-manager.c index 1849fc1b1d9..69630cf49d3 100644 --- a/src/resolve/resolved-manager.c +++ b/src/resolve/resolved-manager.c @@ -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;