This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Using CMSG_NXTHDR to construct ancillary data lists
- From: Florian Weimer <fweimer at redhat dot com>
- To: GNU C Library <libc-alpha at sourceware dot org>
- Date: Wed, 7 Dec 2016 11:29:58 +0100
- Subject: Using CMSG_NXTHDR to construct ancillary data lists
- Authentication-results: sourceware.org; auth=none
Is it supported to use CMSG_NXTHDR to *build* a list of ancillary data
(as opposed to just reading it)?
Our current implementation has a length check for the ancillary data
returned by CMSG_NXTHDR; if it does not fit into the buffer indicated by
struct msghdr, NULL is returned.
This length check is invalid if the list is being constructed because
the length has not been initialized at this point.
Here's how the current implementation looks like:
_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;
__cmsg = (struct cmsghdr *) ((unsigned char *) __cmsg
+ CMSG_ALIGN (__cmsg->cmsg_len));
if ((unsigned char *) (__cmsg + 1) > ((unsigned char *)
__mhdr->msg_control
+ __mhdr->msg_controllen)
|| ((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;
}
__cmsg is advanced to the next list element, and then the length check
is performed against data from the new message segment.
The length check of the next list element might be a useful
belts-and-suspenders approach to deal with the data return from the
kernel. However, I don't expect the kernel to supply bad data here and
pass through unchecked data from an untrusted source.
Application code can work around this issue by initializing to zero the
buffer used to construct the list of ancillary data. Then the length
check will succeed because the length is treated as zero.
Thanks,
Florian