bug: struct cmsghdr does not match system on cygwin64

Kenton Varda kenton@sandstorm.io
Mon Dec 29 05:04:00 GMT 2014


Hello Cygwin,

Cygwin defines 'struct cmsghdr' (see recvmsg(2)) as follows (cygwin/socket.h):

struct cmsghdr
{
  socklen_t             cmsg_len;       /* Length of cmsghdr + data     */
  int                   cmsg_level;     /* Protocol                     */
  int                   cmsg_type;      /* Protocol type                */
};

Unfortunately, Winsock defines its equivalent type as follows (ws2def.h):

typedef struct _WSACMSGHDR {
    SIZE_T      cmsg_len;
    INT         cmsg_level;
    INT         cmsg_type;
    /* followed by UCHAR cmsg_data[] */
} WSACMSGHDR, *PWSACMSGHDR, FAR *LPWSACMSGHDR;

As you can see, on a 64-bit build, the cmsg_len is 64 bits in the
Winsock struct. However, Cygwin's socklen_t is always 32 bits,
therefore cmsg_len is 32 bits in the Cygwin struct.

Cygwin's recvmsg() calls WSARecvMsg() passing the control message
buffer pointer verbatim, expecting the system to fill the buffer
correctly. The system dutifully fills the buffer with control messages
that are not legible using Cygwin's definition of the struct, leaving
the calling application with apparent garbage data.

sendmsg() likely has a similar problem, though I haven't checked.

It seems like the best solution is to change the type of cmsg_len to
size_t. While this would technically violate standards (I think?), it
turns out the Linux headers define it this way, so presumably no one
will mind.

The other option is to perform some sort of translation of the control
message buffer inside sendmsg() and recvmsg(), but that would
obviously be painful and error-prone.

AFAICT, this bug breaks all users of the IP_PKTINFO and IPV6_PKTINFO
socket options on cygwin64.

-Kenton

--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple



More information about the Cygwin mailing list