View Issue Details

IDProjectCategoryView StatusLast Update
00010561003.1(2008)/Issue 7Base Definitions and Headerspublic2024-06-11 08:52
ReporterEdSchouten Assigned Toajosey  
PrioritynormalSeverityEditorialTypeClarification Requested
Status ClosedResolutionAccepted As Marked 
NameEd Schouten
OrganizationNuxi
User Reference
Sectionsys/socket.h
Page Number-
Line Number-
Interp Status---
Final Accepted Text0001056:0003809
Summary0001056: CMSG_NXTHDR(): under what criteria may NULL be returned?
DescriptionWhile comparing implementations of the CMSG_*() macros across various UNIX flavours, I noticed a difference between implementations of CMSG_NXTHDR() that is quite important when constructing messages.

On FreeBSD, CMSG_NXTHDR() may only return NULL in the following cases:

- It is called with cmsg == NULL and msg_controllen is less than the size of a single header.
- It is called with cmsg != NULL and the header of the next message is outside of the buffer pointed to by msg_control and msg_controllen.

On Linux, CMSG_NXTHDR() is slightly stronger. In the second case, it requires that the next message is entirely within the buffer; not just the header. In other words, it takes the cmsg_len of the next message into consideration, while FreeBSD's implementation does not.

Though I can understand why Linux does this, in my opinion it only makes sense from recvmsg()'s point of view. It's nice if CMSG_NXTHDR() only returns headers that are well-formed.

From a sendmsg() point of view, this is actually pretty bad, as it makes it harder to construct messages properly. You allocate a buffer that contains random garbage, which you then initialize with a sequence of messages. CMSG_NXTHDR() cannot be used to obtain the address of the next message, as the garbage stored in cmsg_len is used to determine whether the message should be returned or not.
Desired ActionThere are two ways of solving this specific problem:

- Requiring that if CMSG_NXTHDR() is used to construct messages, the buffer is first zero-initialized, meaning that cmsg_len is zero. This makes CMSG_NXTHDR() on Linux work properly.

- Stating that CMSG_NXTHDR() should not inspect the contents of the message it is going to return, so that it can easily be used as part of constructing a sequence of messages.
Tagsissue8

Relationships

related to 0000978 Closedajosey Please add CMSG_LEN() and CMSG_SPACE(). 

Activities

EdSchouten

2016-06-06 11:26

reporter   bugnote:0003246

Note that the latter (FreeBSD's behaviour) matches the implementation provided by RFC 2292.

geoffclare

2017-07-14 14:26

manager   bugnote:0003809

Last edited: 2017-07-20 16:00

Suggested changes that would explicitly allow either behaviour and also add the RFC 2292 feature where CMSG_NXTHDR(mhdr, NULL) is equivalent to CMSG_FIRSTHDR(mhdr).

All page and line numbers are for the 2016 edition.

On page xlvii of the frontmatter, add a new second paragraph (after RFC 2181):
IETF RFC 2292
Advanced Sockets API for IPv6, W. Stevens, M. Thomas, February 1998 (available at: www.ietf.org/rfc/rfc2292.txt).

On page 387 line 13153 section <sys/socket.h> change:
this macro shall return a pointer to the next cmsghdr structure, or a null pointer if this structure is the last cmsghdr in the ancillary data.
to:
this macro shall return a pointer to the next cmsghdr structure, or a null pointer if the second argument points to the last cmsghdr and data array pair in the ancillary data. If the ancillary data contains another cmsghdr structure after this one but the cmsg_len value in that structure is such that the data array following that structure would extend beyond the end of the ancilliary data, it is unspecified whether this macro returns a pointer to that cmsghdr structure or returns a null pointer.

If the first argument is a pointer to a msghdr structure and the second argument is a null pointer, this macro shall be equivalent to CMSG_FIRSTHDR() called with the first argument.

On page 387 line 13157 section <sys/socket.h> change:
or a null pointer if there is no ancillary data associated with the msghdr structure.
to:
or a null pointer if either there is no ancillary data associated with the msghdr structure (msg_controllen is zero) or there is insufficient room in the ancilliary data for a complete cmsghdr structure (msg_controllen is non-zero but less than <tt>sizeof(struct cmsghdr)</tt>).

On page 390 line 13289 section <sys/socket.h> add a new paragraph to APPLICATION USAGE:
Portable applications need to account for the alternative behaviors of the CMSG_NXTHDR() macro as follows:
  • When constructing ancilliary data in a msghdr structure, ensure that all locations within the ancilliary data that might be returned by CMSG_NXTHDR() contain a cmsg_len value of zero (typically this is achieved by using memset() to initialise the entire msg_control buffer to null bytes before populating the first cmsghdr structure).

  • When extracting ancilliary data from a received msghdr structure, check that the data array following the last cmsghdr structure does not extend beyond the end of the ancilliary data.


geoffclare

2020-04-16 09:03

manager   bugnote:0004824

When applying this bug I did not need to add the 2nd para of the CMSG_NXTHDR new text, as an equivalent addition was already made by bug 0000978.

(I also fixed the spelling of ancillary.)

Issue History

Date Modified Username Field Change
2016-06-06 09:39 EdSchouten New Issue
2016-06-06 09:39 EdSchouten Status New => Under Review
2016-06-06 09:39 EdSchouten Assigned To => ajosey
2016-06-06 09:39 EdSchouten Name => Ed Schouten
2016-06-06 09:39 EdSchouten Organization => Nuxi
2016-06-06 09:39 EdSchouten Section => sys/socket.h
2016-06-06 09:39 EdSchouten Page Number => -
2016-06-06 09:39 EdSchouten Line Number => -
2016-06-06 11:26 EdSchouten Note Added: 0003246
2017-07-14 14:26 geoffclare Note Added: 0003809
2017-07-14 14:30 geoffclare Note Edited: 0003809
2017-07-14 14:33 geoffclare Note Edited: 0003809
2017-07-20 15:34 geoffclare Note Edited: 0003809
2017-07-20 15:41 geoffclare Note Edited: 0003809
2017-07-20 16:00 geoffclare Note Edited: 0003809
2017-07-20 16:04 geoffclare Interp Status => ---
2017-07-20 16:04 geoffclare Final Accepted Text => 0001056:0003809
2017-07-20 16:04 geoffclare Status Under Review => Resolved
2017-07-20 16:04 geoffclare Resolution Open => Accepted As Marked
2017-07-20 16:04 geoffclare Tag Attached: issue8
2020-04-16 09:03 geoffclare Note Added: 0004824
2020-04-16 09:03 geoffclare Status Resolved => Applied
2020-04-16 09:04 geoffclare Relationship added related to 0000978
2024-06-11 08:52 agadmin Status Applied => Closed