This is the mail archive of the cygwin mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: bug: struct cmsghdr does not match system on cygwin64


Marco Atzeri wrote:
> If I am not wrong, for 64bit,
> on windows sizeof (SIZE_T) =4
> while on cygwin sizeof(size_t)=8

sizeof(SIZE_T) == 8 on Win64. The purpose of SIZE_T is to be the same
size as a pointer:
  http://msdn.microsoft.com/en-us/library/cc441980.aspx

To be clear, I am actually observing everything after cmsg_len being
shifted 4 bytes in real code that works on other platforms.
Specifically, the Cap'n Proto unit tests fail on Cygwin but pass on
Linux and OSX after this commit:
  https://github.com/kentonv/capnproto/commit/68ad32202ed43e42a15de3da90a86b7efdcf8f12

-Kenton

On Sun, Dec 28, 2014 at 9:03 PM, Kenton Varda <kenton@sandstorm.io> wrote:
> 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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]