Make inet6_rth_* family of functions more compliant with RFC3542:
1. CMSG_NXTHDR(mhdr, cmsg) is supposed to dereference cmsg and return the next header in the chain. If cmsg is NULL it should return the first header, behaving essentially like CMSG_FIRSTHDR(). 2. inet6_rth_(space|init|add) should do basic checking on their input to verify that the number of headers (segments) is between 0 and 127 inclusive. MFC-After: 1 month
This commit is contained in:
parent
ad092d18d7
commit
18a6073100
@ -292,7 +292,9 @@ inet6_rth_space(int type, int segments)
|
||||
{
|
||||
switch (type) {
|
||||
case IPV6_RTHDR_TYPE_0:
|
||||
if ((segments >= 0) && (segments <= 127))
|
||||
return (((segments * 2) + 1) << 3);
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
return (0); /* type not suppported */
|
||||
}
|
||||
@ -309,6 +311,9 @@ inet6_rth_init(void *bp, socklen_t bp_len, int type, int segments)
|
||||
/* length validation */
|
||||
if (bp_len < inet6_rth_space(IPV6_RTHDR_TYPE_0, segments))
|
||||
return (NULL);
|
||||
/* segment validation */
|
||||
if ((segments < 0) || (segments > 127))
|
||||
return (NULL);
|
||||
|
||||
memset(bp, 0, bp_len);
|
||||
rth0 = (struct ip6_rthdr0 *)rth;
|
||||
@ -334,6 +339,9 @@ inet6_rth_add(void *bp, const struct in6_addr *addr)
|
||||
switch (rth->ip6r_type) {
|
||||
case IPV6_RTHDR_TYPE_0:
|
||||
rth0 = (struct ip6_rthdr0 *)rth;
|
||||
/* Don't exceed the number of stated segments */
|
||||
if (rth0->ip6r0_segleft == (rth0->ip6r0_len / 2))
|
||||
return (-1);
|
||||
nextaddr = (struct in6_addr *)(rth0 + 1) + rth0->ip6r0_segleft;
|
||||
*nextaddr = *addr;
|
||||
rth0->ip6r0_segleft++;
|
||||
|
@ -471,11 +471,13 @@ struct sockcred {
|
||||
|
||||
/* given pointer to struct cmsghdr, return pointer to next cmsghdr */
|
||||
#define CMSG_NXTHDR(mhdr, cmsg) \
|
||||
(((char *)(cmsg) + _ALIGN((cmsg)->cmsg_len) + \
|
||||
((char *)(cmsg) == NULL ? CMSG_FIRSTHDR(mhdr) : \
|
||||
((char *)(cmsg) + _ALIGN(((struct cmsghdr *)(cmsg))->cmsg_len) + \
|
||||
_ALIGN(sizeof(struct cmsghdr)) > \
|
||||
(char *)(mhdr)->msg_control + (mhdr)->msg_controllen) ? \
|
||||
(struct cmsghdr *)0 : \
|
||||
(struct cmsghdr *)((char *)(cmsg) + _ALIGN((cmsg)->cmsg_len)))
|
||||
(struct cmsghdr *)((char *)(cmsg) + \
|
||||
_ALIGN(((struct cmsghdr *)(cmsg))->cmsg_len)))
|
||||
|
||||
/*
|
||||
* RFC 2292 requires to check msg_controllen, in case that the kernel returns
|
||||
|
Loading…
Reference in New Issue
Block a user