tightened check for the length of ND options.

Submitted by:	jinmei@kame.net (JINMEI Tatuya)
Obtained from:	KAME
This commit is contained in:
Hajimu UMEMOTO 2003-03-26 17:28:47 +00:00
parent 5e7ce4785f
commit 8a9448cabc

View File

@ -1208,14 +1208,23 @@ nd6_options(struct nd_opt_hdr *hdr, int limit,
int optlen = 0;
for (; limit > 0; limit -= optlen) {
if (limit < sizeof(struct nd_opt_hdr)) {
syslog(LOG_INFO, "<%s> short option header", __FUNCTION__);
goto bad;
}
hdr = (struct nd_opt_hdr *)((caddr_t)hdr + optlen);
optlen = hdr->nd_opt_len << 3;
if (hdr->nd_opt_len == 0) {
syslog(LOG_ERR,
syslog(LOG_INFO,
"<%s> bad ND option length(0) (type = %d)",
__FUNCTION__, hdr->nd_opt_type);
goto bad;
}
optlen = hdr->nd_opt_len << 3;
if (optlen > limit) {
syslog(LOG_INFO, "<%s> short option", __FUNCTION__);
goto bad;
}
if (hdr->nd_opt_type > ND_OPT_MTU) {
syslog(LOG_INFO,
@ -1231,10 +1240,24 @@ nd6_options(struct nd_opt_hdr *hdr, int limit,
continue;
}
/*
* Option length check. Do it here for all fixed-length
* options.
*/
if ((hdr->nd_opt_type == ND_OPT_MTU &&
(optlen != sizeof(struct nd_opt_mtu))) ||
((hdr->nd_opt_type == ND_OPT_PREFIX_INFORMATION &&
optlen != sizeof(struct nd_opt_prefix_info)))) {
syslog(LOG_INFO, "<%s> invalid option length",
__FUNCTION__);
continue;
}
switch (hdr->nd_opt_type) {
case ND_OPT_SOURCE_LINKADDR:
case ND_OPT_TARGET_LINKADDR:
case ND_OPT_REDIRECTED_HEADER:
break; /* we don't care about these options */
case ND_OPT_MTU:
if (ndopts->nd_opt_array[hdr->nd_opt_type]) {
syslog(LOG_INFO,