2

When passing file descriptors over Unix domain sockets, control messages at level SOL_SOCKET of type SCM_RIGHTS are used.

Control messages are read and written using the macros CMSG_FIRSTHDR, CMSG_NXTHDR and CMSG_DATA. They take alignment issues into account. Depending on the operating system and libc implementation, they cast pointers and dereference the result either in the same or a different translation unit. They also return such pointers and the calling code typically dereferences them.

As a result, using a simple stack-allocated char buf[CMSG_SPACE(sizeof(int))] as a control message buffer will violate strict-aliasing as the buffer may only be accessed using lvalues of type char, signed char, unsigned char or qualified versions of those. (On some platforms, the buffer might also not be suitably aligned, but the amd64 calling conventions appear to guarantee this because the buffer is large enough.)

An obviously correct fix is to allocate the control message buffer using calloc(), which provides suitably aligned memory without an effective type. However, I would like to avoid making the program less efficient.

In https://svnweb.freebsd.org/base/head/lib/libopenbsd/imsg.c?revision=292023&view=markup I found a different approach where the stack buffer is of type union { struct cmsghdr hdr; char buf[CMSG_SPACE(sizeof(int))]; }, but I don't know whether that is correct. I guess it helps that struct cmsghdr has a field of type int.

Extra question: how to do this in C++ given that C++ has different rules about (among other things) unions than C?

jilles
  • 10,509
  • 2
  • 26
  • 39
  • I suspect POSIX requires C implementations to align structures so that this isn't a problem. – Barmar Mar 17 '19 at 15:47
  • @Barmar [POSIX doesn't appear to address alignment in for this usage at all](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html). Even documents such as [RFC 2292](https://www.ietf.org/rfc/rfc2292.txt) assume it's something provided (or not...) by the implementation. And [the Linux `cmsg` man page](http://man7.org/linux/man-pages/man3/cmsg.3.html) uses the same `union` construct to force proper alignment that's mentioned in the question. – Andrew Henle Mar 17 '19 at 16:21
  • (cont) Note also there's quite a discussion involving alignment on https://stackoverflow.com/questions/28003921/sending-file-descriptor-by-linux-socket – Andrew Henle Mar 17 '19 at 16:24

0 Answers0