mirror of https://github.com/mkerrisk/man-pages
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>
This commit is contained in:
parent
c87721467e
commit
ca16e00db8
|
@ -85,6 +85,14 @@ returns the next valid
|
|||
after the passed
|
||||
.IR cmsghdr .
|
||||
It returns NULL when there isn't enough space left in the buffer.
|
||||
.IP
|
||||
When initializing a buffer that will contain a series of
|
||||
.I cmsghdr
|
||||
structures (e.g., to be sent with
|
||||
.BR sendmsg (2)),
|
||||
that buffer should first be zero-initialized
|
||||
to ensure the correct operation of
|
||||
.BR CMSG_NXTHDR ().
|
||||
.IP *
|
||||
.BR CMSG_ALIGN (),
|
||||
given a length, returns it including the required alignment.
|
||||
|
|
Loading…
Reference in New Issue