Skip to content

Commit

Permalink
ngtcp2: avoid supplying 0 length msg_control to sendmsg()
Browse files Browse the repository at this point in the history
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 curl#9039
  • Loading branch information
Stefan Eissing authored and bagder committed Jun 23, 2022
1 parent 71bbabb commit 8135d42
Showing 1 changed file with 5 additions and 9 deletions.
14 changes: 5 additions & 9 deletions lib/vquic/ngtcp2.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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)
;
Expand Down

0 comments on commit 8135d42

Please sign in to comment.