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.
This commit is contained in:
Lennart Poettering 2020-04-24 23:36:03 +02:00
parent 6bae4b905c
commit a258f4915a
4 changed files with 11 additions and 9 deletions

View 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,

View 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 = {

View 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);

View 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;