From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on inbox.vuxu.org X-Spam-Level: X-Spam-Status: No, score=-3.3 required=5.0 tests=MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED,RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL autolearn=ham autolearn_force=no version=3.4.4 Received: (qmail 8080 invoked from network); 3 Oct 2021 13:36:04 -0000 Received: from mother.openwall.net (195.42.179.200) by inbox.vuxu.org with ESMTPUTF8; 3 Oct 2021 13:36:04 -0000 Received: (qmail 11415 invoked by uid 550); 3 Oct 2021 13:36:01 -0000 Mailing-List: contact musl-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Reply-To: musl@lists.openwall.com Received: (qmail 11394 invoked from network); 3 Oct 2021 13:36:00 -0000 Date: Sun, 3 Oct 2021 09:35:47 -0400 From: Rich Felker To: "J. Hanne" Cc: musl@lists.openwall.com Message-ID: <20211003133546.GB2559@brightrain.aerifal.cx> References: <20210903101352.379FC2FC06B2@dd11108.kasserver.com> <20210903131212.GE13220@brightrain.aerifal.cx> <20210905172745.GD3090@voyager> <20211003081459.34C1C2FC23EF@dd11108.kasserver.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20211003081459.34C1C2FC23EF@dd11108.kasserver.com> User-Agent: Mutt/1.5.21 (2010-09-15) Subject: Re: [musl] CMSG_LEN macro On Sun, Oct 03, 2021 at 10:14:59AM +0200, J. Hanne wrote: > Hi, > > thanks for your thoughts. The NLMSG macros also already gave me > similar headache some time ago. I personally find both APIs > counter-intuitive because they use the term "ALIGN", when they mean > "PAD", so that the *following* item is aligned. > > I would suggest the following patch now: > > Do not use CMSG_ALIGN on struct cmsghdr, because: > - This has no effect on any architecture anyway, because sizeof(struct cmsghdr) == 16 on all archs > - Using it contradicts with CMSG_DATA, which does NOT apply any padding after struct cmsghdr > - This is consistent with the NLMSG_* macros > --- > diff -uNr a/include/sys/socket.h b/include/sys/socket.h > --- a/include/sys/socket.h 2021-01-15 03:26:00.000000000 +0100 > +++ b/include/sys/socket.h 2021-10-03 09:49:35.000000000 +0200 > @@ -358,8 +358,8 @@ > #define CMSG_FIRSTHDR(mhdr) ((size_t) (mhdr)->msg_controllen >= sizeof (struct cmsghdr) ? (struct cmsghdr *) (mhdr)->msg_control : (struct cmsghdr *) 0) > > #define CMSG_ALIGN(len) (((len) + sizeof (size_t) - 1) & (size_t) ~(sizeof (size_t) - 1)) Aside: this should be cleaned up too. It has a truely no-op cast (the type is the same as the type of the expression) and gratuitously uses ~(x-1) instead of -x. But this could be a separate change. (Note: implicit in my claim here is an assumption that size_t has rank not less than that of int, but this is assumed everywhere and is a condition on any ABI we would ever plausibly support.) > -#define CMSG_SPACE(len) (CMSG_ALIGN (len) + CMSG_ALIGN (sizeof (struct cmsghdr))) > -#define CMSG_LEN(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + (len)) > +#define CMSG_SPACE(len) (CMSG_ALIGN (len) + sizeof (struct cmsghdr)) > +#define CMSG_LEN(len) (sizeof (struct cmsghdr) + (len)) Looks ok I think. > #define SCM_RIGHTS 0x01 > #define SCM_CREDENTIALS 0x02 > -- > > By the way, the question which led me to all this stuff is: How do I > get the payload length of a received cmsg. Neither the man page nor > an Internet search gave me any satisfactory answer. So my best guess > was "do some arithmetic with CMSG_LEN": > payloadlen = cmsghdr->cmsg_len - CMSG_LEN(0); > However, when double-checking with musl source code, the CMSG_ALIGN > on struct cmsghdr made me doubt my approach. Now, I will stick to it > - as long as nobody else has a better idea? I would probably compute the address of the end of the cmsg and subtract CMSG_DATA -- something like: (unsigned char *)cmsg + cmsg->cmsg_len - CMSG_DATA(cmsg) treating the length as untrusted if appropriate. This might be better rearranged (so there's no question of overflow if cmsg_len is invalid) as: cmsg->cmsg_len - (CMSG_DATA(cmsg) - (unsigned char *)cmsg) This avoids relying on a nonportable CMSG_LEN macro or assumptions about it. Rich