dhcp: fix parse error with chained pbfus

If a chained pbuf starts with DHCP_OPTION_PAD, an overflow check
triggers and the packet is ignored.

Fix this by changing the way the offset is increased for PAD.
Also ignore a packet that is missing the END option.

Signed-off-by: Simon Goldschmidt <goldsimon@gmx.de>
This commit is contained in:
Simon Goldschmidt 2018-07-02 20:25:42 +02:00
parent cc8995823a
commit 19a929f5fb

View File

@ -1574,7 +1574,6 @@ again:
/* special option: no len encoded */ /* special option: no len encoded */
decode_len = len = 0; decode_len = len = 0;
/* will be increased below */ /* will be increased below */
offset--;
break; break;
case (DHCP_OPTION_SUBNET_MASK): case (DHCP_OPTION_SUBNET_MASK):
LWIP_ERROR("len == 4", len == 4, return ERR_VAL;); LWIP_ERROR("len == 4", len == 4, return ERR_VAL;);
@ -1639,6 +1638,9 @@ again:
op, len, q, val_offset); op, len, q, val_offset);
break; break;
} }
if (op == DHCP_OPTION_PAD) {
offset++;
} else {
if (offset + len + 2 > 0xFFFF) { if (offset + len + 2 > 0xFFFF) {
/* overflow */ /* overflow */
return ERR_BUF; return ERR_BUF;
@ -1679,6 +1681,7 @@ decode_next:
dhcp_set_option_value(dhcp, decode_idx, value); dhcp_set_option_value(dhcp, decode_idx, value);
} }
} }
}
if (offset >= q->len) { if (offset >= q->len) {
offset = (u16_t)(offset - q->len); offset = (u16_t)(offset - q->len);
offset_max = (u16_t)(offset_max - q->len); offset_max = (u16_t)(offset_max - q->len);
@ -1688,7 +1691,7 @@ decode_next:
options = (u8_t *)q->payload; options = (u8_t *)q->payload;
} else { } else {
/* We've run out of bytes, probably no end marker. Don't proceed. */ /* We've run out of bytes, probably no end marker. Don't proceed. */
break; return ERR_BUF;
} }
} }
} }