NetBSD-Users archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: aligning control message ancillary data

In article <>,
Taylor R Campbell  <> wrote:
>But then I checked -current, and it changed dramatically!  Now it uses
>nearly the union that stunnel uses, but looks rather clumsier:
>   struct msghdr msg;
>   union {
>       struct cmsghdr hdr;
>       char buf[1024]; /* Here stunnel uses CMSG_SPACE. */
>   } cmsgbuf;
>   struct cmsghdr *cmsg;
>   /* ... */
>   if (sizeof(cmsgbuf.buf) < CMSG_SPACE(sizeof(int))) {
>       error("%s: %zu < %zu, recompile", __func__,
>               sizeof(cmsgbuf.buf), CMSG_SPACE(sizeof(int)));
>       return -1;
>   }
>   /* ... */
>   msg.msg_control = &cmsgbuf.buf;
>   msg.msg_controllen = CMSG_SPACE(sizeof(int));
>   cmsg = CMSG_FIRSTHDR(&msg);
>   cmsg->cmsg_len = CMSG_LEN(sizeof(int));
>The magic constant 1024 scares me, and the conditional looks
>ridiculous, and now msg.msg_controllen disagrees with cmsg->cmsg_len.
>In OpenBSD's source tree, there is a subtly different idiom; in fact,
>the last four changes to it have been to change the idiom.  So...which
>one is right?

This deserves a bit of an explanation (as I understand it).

1. We want the union to guarantee proper alignment.
2. CMSG_SPACE() does not evaluate to a constant, and this makes
   the buf array varying size, so the end of the stack for that
   function cannot be computed at compile time. This means that
   the function cannot be protected with -fstack-protector. We
   want daemons that deal with security to have all the functions
   protected. 1024 is chosen because is much larger than needed.
   This is also protected via a assertion for runtime.
3. I think that msg_controllen should reflect the size of the message
   buffer, where cmsg_len should contain the length of this message.
   Again I the api sucks for exposing so much of the guts and having
   two different but similar sounding macros to compute the size of
   the message. I guess controllen could be set to sizeof(cmsgbuf) too
   but the interface is so fragile who knows what it will break. It
   is notable that this change caused the kernel to panic() when it
   was first introduced.


Home | Main Index | Thread Index | Old Index