proxyarp: Validate IPv4 header total length value in dhcp_snoop

This field needs to be validated in addition to validating the total
length of the received frame to avoid reading beyond the frame buffer.

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
Jouni Malinen 2014-11-28 22:31:38 +02:00 committed by Jouni Malinen
parent 8c5043b42c
commit bcb132e185

View file

@ -52,17 +52,22 @@ static void handle_dhcp(void *ctx, const u8 *src_addr, const u8 *buf,
const u8 *end, *pos; const u8 *end, *pos;
int res, msgtype = 0, prefixlen = 32; int res, msgtype = 0, prefixlen = 32;
u32 subnet_mask = 0; u32 subnet_mask = 0;
u16 tot_len;
exten_len = len - ETH_HLEN - (sizeof(*b) - sizeof(b->exten)); exten_len = len - ETH_HLEN - (sizeof(*b) - sizeof(b->exten));
if (exten_len < 4) if (exten_len < 4)
return; return;
b = (const struct bootp_pkt *) &buf[ETH_HLEN]; b = (const struct bootp_pkt *) &buf[ETH_HLEN];
tot_len = ntohs(b->iph.tot_len);
if (tot_len > (unsigned int) (len - ETH_HLEN))
return;
if (os_memcmp(b->exten, ic_bootp_cookie, ARRAY_SIZE(ic_bootp_cookie))) if (os_memcmp(b->exten, ic_bootp_cookie, ARRAY_SIZE(ic_bootp_cookie)))
return; return;
/* Parse DHCP options */ /* Parse DHCP options */
end = (const u8 *) b + ntohs(b->iph.tot_len); end = (const u8 *) b + tot_len;
pos = &b->exten[4]; pos = &b->exten[4];
while (pos < end && *pos != 0xff) { while (pos < end && *pos != 0xff) {
const u8 *opt = pos++; const u8 *opt = pos++;