In the current implementation, when setting up ancillary data, __cmsg_nxthdr will try to read data from the uninitialized area of the ancillary buffer and may erroneously return NULL. 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 NULL; Above is the relevant part of the current implementation. "cmsg->cmsg_len" in the second "||" clause will read uninitialized data. That second "||" clause is not needed at all (and the kernel version of this function does not have it). This implementation is ok for parsing ancillary data (it provides some extra sanity checking of the data), but it is broken for setting up ancillary data. A workaround is to memset the entire ancillary data buffer to 0 before initializing it, but there is no such requirement in neither man pages nor RFC 2292 or RFC 3542. Glibc's implementation of CMSG_NXTHDR is not consistent with the reference implementation in RFC 2292 and RFC 3542. P.S. The current implementation does not support another RFC 2292/3542 requirement requirement: The following behavior of this macro is new to this API: if the value of the cmsg pointer is NULL, a pointer to the cmsghdr structure describing the first ancillary data object is returned. That is, CMSG_NXTHDR(mhdr, NULL) is equivalent to CMSG_FIRSTHDR(mhdr). But you'll probably want a different bug report for this.
Where is the self-contained test case?
Created attachment 6141 [details] Test that fails, unless NEED_A_WORKAROUND_FOR_BUG_13500 is defined Here is a test case. The expected output is "Looks good!". Currently, the output is "CMSG_NXTHDR is lying -- I have space for another int"
Test has been provided, so removing WAITING.
use NEED_A_WORKAROUND_FOR_BUG_13500 to zero buf, will make length check useless, even to introduce security bugs.
(In reply to phperl from comment #4) > use NEED_A_WORKAROUND_FOR_BUG_13500 to zero buf, will make length check > useless, even to introduce security bugs. Sorry, I don't understand this comment. The length check is *always* useless for constructing ancillary data lists, but it is not useless for *reading* them.
(In reply to Florian Weimer from comment #5) > (In reply to phperl from comment #4) > > use NEED_A_WORKAROUND_FOR_BUG_13500 to zero buf, will make length check > > useless, even to introduce security bugs. > > Sorry, I don't understand this comment. > > The length check is *always* useless for constructing ancillary data lists, > but it is not useless for *reading* them. Sorry, I missed the *reading* process.
I'm marking this as RESOLVED INVALID. The length check in the current glibc CMSG_NXTHDR macro requires that the you are reading valid data, and the check will not be removed to facilitate setting up of lists. If you are setting up a list you must set it to some known values for the macro to work correctly e.g. memset to zero. I suggest reaching out to the linux man pages project to update the man page with relevant information for developers. Note that I don't see where RFC 2292, and RFC 3542 cover setting up a list, only reading one. As Florian notes: "The length check is *always* useless for constructing ancillary data lists, but it is not useless for *reading* them."