simplied the fix to FreeBSD-SA-04:06.ipv6. The previous one worried

too much even though we actually validate the parameters.  This code
also is more compatible with other *BSDs, which do copyin within
setsockopt().

Submitted by:	Keiichi SHIMA <keiichi__at__iijlab.net>
Reviewed by:	security-officer (nectar)
Obtained from:	KAME
This commit is contained in:
Hajimu UMEMOTO 2005-07-28 18:07:07 +00:00
parent d6279c101e
commit e770771a78
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=148488

View File

@ -1764,6 +1764,7 @@ do { \
{
/* new advanced API (RFC3542) */
u_char *optbuf;
u_char optbuf_storage[MCLBYTES];
int optlen;
struct ip6_pktopts **optp;
@ -1773,48 +1774,21 @@ do { \
break;
}
switch (optname) {
case IPV6_HOPOPTS:
case IPV6_DSTOPTS:
case IPV6_RTHDRDSTOPTS:
case IPV6_NEXTHOP:
if (!privileged)
error = EPERM;
break;
}
/*
* We only ensure valsize is not too large
* here. Further validation will be done
* later.
*/
error = sooptcopyin(sopt, optbuf_storage,
sizeof(optbuf_storage), 0);
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;
}
optbuf = optbuf_storage;
optp = &in6p->in6p_outputopts;
error = ip6_pcbopt(optname,
optbuf, optlen,
optp, privileged, uproto);
free(optbuf, M_TEMP);
break;
}
#undef OPTSET