From: Stefan Eissing Date: Wed, 22 Jun 2022 13:25:40 +0000 (+0200) Subject: ngtcp2: avoid supplying 0 length `msg_control` to sendmsg() X-Git-Tag: curl-7_84_0~12 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8135d420eeb79ca40e2257da98dc24707c815d7a;p=thirdparty%2Fcurl.git 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 --- diff --git a/lib/vquic/ngtcp2.c b/lib/vquic/ngtcp2.c index f31d5dcb31..ca9c388345 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) ;