dhcp: Fix potential OOB read when parsing DHCP messages
The missing parentheses around the additions when calculating optlen in the previous code can cause an out-of-bound read of up to 228 bytes if no DHCP_OPTEND is found in the message (the calculation basically evaluated to `- 20 + 8 + 240`). Since the buffer for the received packet (via pf_handler_t) is located on the stack, this shouldn't cause much of an issue in practice.
This commit is contained in:
@@ -641,14 +641,14 @@ CALLBACK(receive_dhcp, void,
|
|||||||
int fd, chunk_t pkt)
|
int fd, chunk_t pkt)
|
||||||
{
|
{
|
||||||
dhcp_packet_t *packet = (dhcp_packet_t*)pkt.ptr;
|
dhcp_packet_t *packet = (dhcp_packet_t*)pkt.ptr;
|
||||||
size_t optlen, origoptlen, optpos = 0, optsize;
|
size_t optoffset, optlen, origoptlen, optpos = 0, optsize;
|
||||||
dhcp_option_t *option;
|
dhcp_option_t *option;
|
||||||
|
|
||||||
if (pkt.len >= sizeof(struct ip) + sizeof(struct udphdr) +
|
optoffset = sizeof(struct ip) + sizeof(struct udphdr) +
|
||||||
offsetof(dhcp_t, options))
|
offsetof(dhcp_t, options);
|
||||||
|
if (pkt.len >= optoffset)
|
||||||
{
|
{
|
||||||
origoptlen = optlen = pkt.len - sizeof(struct ip) +
|
origoptlen = optlen = pkt.len - optoffset;
|
||||||
sizeof(struct udphdr) + offsetof(dhcp_t, options);
|
|
||||||
while (optlen > sizeof(dhcp_option_t))
|
while (optlen > sizeof(dhcp_option_t))
|
||||||
{
|
{
|
||||||
option = (dhcp_option_t*)&packet->dhcp.options[optpos];
|
option = (dhcp_option_t*)&packet->dhcp.options[optpos];
|
||||||
|
|||||||
Reference in New Issue
Block a user