summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2016-05-22 18:49:59 -0400
committerRich Felker <dalias@aerifal.cx>2016-05-22 18:49:59 -0400
commit81fb75a1d75c20d97292cbbe4cde6a1e65871abe (patch)
tree71138623e144edd910490f327696b546e14f7d67
parent51eeb6ebc94d965768143c45e9f39b0a7998bdbd (diff)
downloadmusl-81fb75a1d75c20d97292cbbe4cde6a1e65871abe.tar.gz
musl-81fb75a1d75c20d97292cbbe4cde6a1e65871abe.tar.bz2
musl-81fb75a1d75c20d97292cbbe4cde6a1e65871abe.tar.xz
musl-81fb75a1d75c20d97292cbbe4cde6a1e65871abe.zip
fix undefined pointer arithmetic in CMSG_NXTHDR macro
previously, the only way the stopping condition could be met with correct lengths in the headers invoked undefined behavior, adding sizeof(struct cmsghdr) beyond the end of the cmsg buffer. instead, compute and compare sizes rather than pointers.
-rw-r--r--include/sys/socket.h6
1 files changed, 3 insertions, 3 deletions
diff --git a/include/sys/socket.h b/include/sys/socket.h
index fd653490..67883750 100644
--- a/include/sys/socket.h
+++ b/include/sys/socket.h
@@ -266,9 +266,9 @@ struct linger
#define __MHDR_END(mhdr) ((unsigned char *)(mhdr)->msg_control + (mhdr)->msg_controllen)
#define CMSG_DATA(cmsg) ((unsigned char *) (((struct cmsghdr *)(cmsg)) + 1))
-#define CMSG_NXTHDR(mhdr, cmsg) ((cmsg)->cmsg_len < sizeof (struct cmsghdr) ? (struct cmsghdr *)0 : \
- (__CMSG_NEXT(cmsg) + sizeof (struct cmsghdr) >= __MHDR_END(mhdr) ? (struct cmsghdr *)0 : \
- ((struct cmsghdr *)__CMSG_NEXT(cmsg))))
+#define CMSG_NXTHDR(mhdr, cmsg) ((cmsg)->cmsg_len < sizeof (struct cmsghdr) || \
+ __CMSG_LEN(cmsg) + sizeof(struct cmsghdr) >= __MHDR_END(mhdr) - (unsigned char *)(cmsg) \
+ ? 0 : (struct cmsghdr *)__CMSG_NEXT(cmsg))
#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))