From 8135d420eeb79ca40e2257da98dc24707c815d7a Mon Sep 17 00:00:00 2001 From: Stefan Eissing Date: Wed, 22 Jun 2022 15:25:40 +0200 Subject: [PATCH] ngtcp2: avoid supplying 0 length `msg_control` to sendmsg() Testing on macOS 12.4, sendmsg() fails with EINVAL when a msg_control buffer is provided in sengmsg(), even though msg_controllen was set to 0. Initialize msg.msg_controllen just as needed and also perform the size assertion only when needed. Closes #9039 --- lib/vquic/ngtcp2.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/lib/vquic/ngtcp2.c b/lib/vquic/ngtcp2.c index f31d5dcb3..ca9c38834 100644 --- a/lib/vquic/ngtcp2.c +++ b/lib/vquic/ngtcp2.c @@ -1653,25 +1653,22 @@ static CURLcode do_sendmsg(size_t *psent, struct Curl_easy *data, int sockfd, struct iovec msg_iov = {(void *)pkt, pktlen}; struct msghdr msg = {0}; uint8_t msg_ctrl[32]; - size_t ctrllen = 0; ssize_t sent; #if defined(__linux__) && defined(UDP_SEGMENT) struct cmsghdr *cm; #endif *psent = 0; - - assert(sizeof(msg_ctrl) >= CMSG_SPACE(sizeof(uint16_t))); - msg.msg_iov = &msg_iov; msg.msg_iovlen = 1; - msg.msg_control = msg_ctrl; - msg.msg_controllen = sizeof(msg_ctrl); - #if defined(__linux__) && defined(UDP_SEGMENT) if(pktlen > gsolen) { - ctrllen += CMSG_SPACE(sizeof(uint16_t)); + /* Only set this, when we need it. macOS, for example, + * does not seem to like a msg_control of length 0. */ + msg.msg_control = msg_ctrl; + assert(sizeof(msg_ctrl) >= CMSG_SPACE(sizeof(uint16_t))); + msg.msg_controllen = CMSG_SPACE(sizeof(uint16_t)); cm = CMSG_FIRSTHDR(&msg); cm->cmsg_level = SOL_UDP; cm->cmsg_type = UDP_SEGMENT; @@ -1680,7 +1677,6 @@ static CURLcode do_sendmsg(size_t *psent, struct Curl_easy *data, int sockfd, } #endif - msg.msg_controllen = ctrllen; while((sent = sendmsg(sockfd, &msg, 0)) == -1 && SOCKERRNO == EINTR) ;