From 11f479f5193062dc4eb60f7c5964ffbd382dd52a Mon Sep 17 00:00:00 2001 From: ume Date: Fri, 26 Mar 2004 19:52:18 +0000 Subject: Validate IPv6 socket options more carefully to avoid a panic. PR: kern/61513 Reviewed by: cperciva, nectar --- sys/netinet6/ip6_output.c | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) (limited to 'sys/netinet6/ip6_output.c') 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 -- cgit v1.1