diff options
| author | Michael Kerrisk <mtk.manpages@gmail.com> | 2018-07-08 20:32:15 +0200 |
|---|---|---|
| committer | Michael Kerrisk <mtk.manpages@gmail.com> | 2018-07-10 07:14:50 +0200 |
| commit | ca16e00db8cabbdccf109b49548177840e98a688 (patch) | |
| tree | bb5ed8025a3ceb5a932b99512e7c1be0594bb234 /man7/unix.7 | |
| parent | c87721467e21e060c332ca53f3f4ec6e01686c17 (diff) | |
| download | man-pages-ca16e00db8cabbdccf109b49548177840e98a688.tar.gz | |
cmsg.3: Explain zero-initialization requirement for CMSG_NXTHDR()
When initializing a new buffer (e.g., that will be sent with
sendmsg(2)), that buffer must first be zero-initialized to
ensure the correct operation of CMSG_NXTHDR().
Verified by experiment, and also by inspection of the glibc
source code:
_EXTERN_INLINE struct cmsghdr *
__NTH (__cmsg_nxthdr (struct msghdr *__mhdr, struct cmsghdr *__cmsg))
{
if ((size_t) __cmsg->cmsg_len < sizeof (struct cmsghdr))
/* The kernel header does this so there may be a reason. */
return (struct cmsghdr *) 0;
[1] __cmsg = (struct cmsghdr *) ((unsigned char *) __cmsg
+ CMSG_ALIGN (__cmsg->cmsg_len));
if ((unsigned char *) (__cmsg + 1) > ((unsigned char *) __mhdr->msg_control
+ __mhdr->msg_controllen)
[2] || ((unsigned char *) __cmsg + CMSG_ALIGN (__cmsg->cmsg_len) // <---
> ((unsigned char *) __mhdr->msg_control + __mhdr->msg_controllen)))
/* No more entries. */
return (struct cmsghdr *) 0;
return __cmsg;
}
At point [1], __cmsg has been updated to point to the next
cmsghdr. The subsequent check at [2] relies on 'cmsg_len'
in the next cmsghdr having some "sensible" value (e.g., 0).
See also https://stackoverflow.com/questions/27601849/cmsg-nxthdr-returns-null-even-though-there-are-more-cmsghdr-objects
Signed-off-by: Michael Kerrisk <mtk.manpages@gmail.com>
Diffstat (limited to 'man7/unix.7')
0 files changed, 0 insertions, 0 deletions
