the kernel wrongly expects the cmsg length field to be size_t instead
of socklen_t. in order to work around the issue, we have to impose a
length limit and copy to a local buffer. the length limit should be
more than sufficient for any real-world use; these headers are only
used for passing file descriptors and permissions between processes
over unix sockets.
POSIX clearly specifies the type of msg_iovlen and msg_controllen, and
Linux ignores it and makes them both size_t instead. to work around
this we add padding (instead of just using the wrong types like glibc
does), but we also need to patch-up the struct before passing it to
the kernel in case the caller did not zero-fill it.
if i could trust the kernel to just ignore the upper 32 bits, this
would not be necessary, but i don't think it will ignore them...