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; int optlen = 0;
for (; limit > 0; limit -= optlen) { 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); hdr = (struct nd_opt_hdr *)((caddr_t)hdr + optlen);
optlen = hdr->nd_opt_len << 3;
if (hdr->nd_opt_len == 0) { if (hdr->nd_opt_len == 0) {
syslog(LOG_ERR, syslog(LOG_INFO,
"<%s> bad ND option length(0) (type = %d)", "<%s> bad ND option length(0) (type = %d)",
__FUNCTION__, hdr->nd_opt_type); __FUNCTION__, hdr->nd_opt_type);
goto bad; 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) { if (hdr->nd_opt_type > ND_OPT_MTU) {
syslog(LOG_INFO, syslog(LOG_INFO,
@ -1231,10 +1240,24 @@ nd6_options(struct nd_opt_hdr *hdr, int limit,
continue; 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) { switch (hdr->nd_opt_type) {
case ND_OPT_SOURCE_LINKADDR: case ND_OPT_SOURCE_LINKADDR:
case ND_OPT_TARGET_LINKADDR: case ND_OPT_TARGET_LINKADDR:
case ND_OPT_REDIRECTED_HEADER: case ND_OPT_REDIRECTED_HEADER:
break; /* we don't care about these options */
case ND_OPT_MTU: case ND_OPT_MTU:
if (ndopts->nd_opt_array[hdr->nd_opt_type]) { if (ndopts->nd_opt_array[hdr->nd_opt_type]) {
syslog(LOG_INFO, syslog(LOG_INFO,