summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorume <ume@FreeBSD.org>2004-03-26 19:52:18 +0000
committerume <ume@FreeBSD.org>2004-03-26 19:52:18 +0000
commit11f479f5193062dc4eb60f7c5964ffbd382dd52a (patch)
treee99a84e7b828e8e198ef8e99c89434dfc678ecac /sys
parentb44e46cbe7c7547a45789778ba2daaf00635ae02 (diff)
downloadFreeBSD-src-11f479f5193062dc4eb60f7c5964ffbd382dd52a.zip
FreeBSD-src-11f479f5193062dc4eb60f7c5964ffbd382dd52a.tar.gz
Validate IPv6 socket options more carefully to avoid a panic.
PR: kern/61513 Reviewed by: cperciva, nectar
Diffstat (limited to 'sys')
-rw-r--r--sys/netinet/ip6.h1
-rw-r--r--sys/netinet6/ip6_output.c38
2 files changed, 38 insertions, 1 deletions
diff --git a/sys/netinet/ip6.h b/sys/netinet/ip6.h
index 336ef48..bbc18df 100644
--- a/sys/netinet/ip6.h
+++ b/sys/netinet/ip6.h
@@ -213,6 +213,7 @@ struct ip6_frag {
#define IPV6_MMTU 1280 /* minimal MTU and reassembly. 1024 + 256 */
#define IPV6_MAXPACKET 65535 /* ip6 max packet size without Jumbo payload*/
+#define IPV6_MAXOPTHDR 2048 /* max option header size, 256 64-bit words */
#ifdef _KERNEL
/*
diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c
index 2dd5fc9..bdccf66 100644
--- a/sys/netinet6/ip6_output.c
+++ b/sys/netinet6/ip6_output.c
@@ -1780,12 +1780,48 @@ do { \
break;
}
- optbuf = sopt->sopt_val;
+ switch (optname) {
+ case IPV6_HOPOPTS:
+ case IPV6_DSTOPTS:
+ case IPV6_RTHDRDSTOPTS:
+ case IPV6_NEXTHOP:
+ if (!privileged)
+ error = EPERM;
+ break;
+ }
+ if (error)
+ break;
+
+ switch (optname) {
+ case IPV6_PKTINFO:
+ optlen = sizeof(struct in6_pktinfo);
+ break;
+ case IPV6_NEXTHOP:
+ optlen = SOCK_MAXADDRLEN;
+ break;
+ default:
+ optlen = IPV6_MAXOPTHDR;
+ break;
+ }
+ if (sopt->sopt_valsize > optlen) {
+ error = EINVAL;
+ break;
+ }
+
optlen = sopt->sopt_valsize;
+ optbuf = malloc(optlen, M_TEMP, M_WAITOK);
+ error = sooptcopyin(sopt, optbuf, optlen,
+ optlen);
+ if (error) {
+ free(optbuf, M_TEMP);
+ break;
+ }
+
optp = &in6p->in6p_outputopts;
error = ip6_pcbopt(optname,
optbuf, optlen,
optp, privileged, uproto);
+ free(optbuf, M_TEMP);
break;
}
#undef OPTSET
OpenPOWER on IntegriCloud