summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authormtm <mtm@FreeBSD.org>2007-04-19 15:48:16 +0000
committermtm <mtm@FreeBSD.org>2007-04-19 15:48:16 +0000
commitb79eceb7f37331e0724c1eb4b575b3b779b8a47b (patch)
tree4d4aa29554dab123ae85efd563d50ada2c64aa48 /lib
parentd15cc39e73860f1cbeb14f0698536d3635f893d4 (diff)
downloadFreeBSD-src-b79eceb7f37331e0724c1eb4b575b3b779b8a47b.zip
FreeBSD-src-b79eceb7f37331e0724c1eb4b575b3b779b8a47b.tar.gz
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
Diffstat (limited to 'lib')
-rw-r--r--lib/libc/net/rthdr.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/lib/libc/net/rthdr.c b/lib/libc/net/rthdr.c
index 5fbb4bb..f92fdec 100644
--- a/lib/libc/net/rthdr.c
+++ b/lib/libc/net/rthdr.c
@@ -292,7 +292,9 @@ inet6_rth_space(int type, int segments)
{
switch (type) {
case IPV6_RTHDR_TYPE_0:
- return (((segments * 2) + 1) << 3);
+ 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++;
OpenPOWER on IntegriCloud