options.c: Don't trust the options length field in do_get_dhcp_opt() to

not be longer than the total option length.

A lying field sent by the DHCP server could possibly read data past the end of
the options field in the dhcp packet into the returned options data buffer.

It's hard to see how this could lead to an exploit because the total length
of data read into the options data buffer was indeed properly length-checked
so that it is impossible to overrun the destination buffer.  Thus, this
problem is at worst a read-too-far with no ability to write to unexpected
locations.

The worst possible outcome is a program crash/DoS, depending on memory
layout.  Information disclosure is not an issue because this is on the
path where the consumer of the destination buffer is ndhc, not the remote
DHCP server.
This commit is contained in:
Nicholas J. Kain 2014-03-12 13:30:55 -04:00
parent 765f3de274
commit 80f82c2451

View File

@ -90,13 +90,16 @@ static ssize_t do_get_dhcp_opt(uint8_t *sbuf, ssize_t slen, uint8_t code,
break; break;
if (i >= slen - 2) if (i >= slen - 2)
break; break;
ssize_t soptsiz = sbuf[i+1];
if (sbuf[i] == code) { if (sbuf[i] == code) {
if (dlen - didx < sbuf[i+1]) if (dlen - didx < soptsiz)
return didx; return didx;
memcpy(dbuf+didx, sbuf+i+2, sbuf[i+1]); if (slen - i - 2 < soptsiz)
didx += sbuf[i+1]; return didx;
memcpy(dbuf+didx, sbuf+i+2, soptsiz);
didx += soptsiz;
} }
i += sbuf[i+1] + 2; i += soptsiz + 2;
} }
return didx; return didx;
} }