diff --git a/components/lwip/core/ipv4/dhcp.c b/components/lwip/core/ipv4/dhcp.c index 2c4a6b3d26..5b1575a325 100644 --- a/components/lwip/core/ipv4/dhcp.c +++ b/components/lwip/core/ipv4/dhcp.c @@ -1590,8 +1590,8 @@ dhcp_parse_reply(struct dhcp *dhcp, struct pbuf *p) again: q = p; while ((q != NULL) && (options_idx >= q->len)) { - options_idx -= q->len; - options_idx_max -= q->len; + options_idx = (u16_t)(options_idx - q->len); + options_idx_max = (u16_t)(options_idx_max - q->len); q = q->next; } if (q == NULL) { @@ -1606,7 +1606,11 @@ again: u8_t len; u8_t decode_len = 0; int decode_idx = -1; - u16_t val_offset = offset + 2; + u16_t val_offset = (u16_t)(offset + 2); + if (val_offset < offset) { + /* overflow */ + return ERR_BUF; + } /* len byte might be in the next pbuf */ if (offset + 1 < q->len) { len = options[offset + 1]; @@ -1679,7 +1683,11 @@ again: LWIP_DEBUGF(DHCP_DEBUG, ("skipping option %"U16_F" in options\n", op)); break; } - offset += len + 2; + if ((u32_t)(offset + len + 2) > 0xFFFF) { + /* overflow */ + return ERR_BUF; + } + offset = (u16_t)(offset + len + 2); if (decode_len > 0) { u32_t value = 0; u16_t copy_len; @@ -1690,11 +1698,17 @@ decode_next: pbuf_copy_partial(q, &value, copy_len, val_offset); if (decode_len > 4) { /* decode more than one u32_t */ + u16_t next_val_offset; //LWIP_ERROR("decode_len % 4 == 0", decode_len % 4 == 0, return ERR_VAL;); dhcp_got_option(dhcp, decode_idx); dhcp_set_option_value(dhcp, decode_idx, htonl(value)); - decode_len -= 4; - val_offset += 4; + decode_len = (u8_t)(decode_len - 4); + next_val_offset = (u16_t)(val_offset + 4); + if (next_val_offset < val_offset) { + /* overflow */ + return ERR_BUF; + } + val_offset = next_val_offset; decode_idx++; goto decode_next; } else if (decode_len == 4) { @@ -1708,8 +1722,8 @@ decode_next: } } if (offset >= q->len) { - offset -= q->len; - offset_max -= q->len; + offset = (u16_t)(offset - q->len); + offset_max = (u16_t)(offset_max - q->len); if ((offset < offset_max) && offset_max) { q = q->next; LWIP_ASSERT("next pbuf was null", q); diff --git a/components/lwip/core/ipv6/ip6.c b/components/lwip/core/ipv6/ip6.c index acd28fb5b8..fc66793ecc 100644 --- a/components/lwip/core/ipv6/ip6.c +++ b/components/lwip/core/ipv6/ip6.c @@ -571,7 +571,7 @@ netif_found: ip_data.current_ip_header_tot_len += hlen; /* Skip over this header. */ - if (hlen > p->len) { + if (p->len < 8 || hlen > p->len) { LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("IPv6 options header (hlen %"U16_F") does not fit in first pbuf (len %"U16_F"), IPv6 packet dropped.\n", hlen, p->len)); @@ -594,7 +594,7 @@ netif_found: ip_data.current_ip_header_tot_len += hlen; /* Skip over this header. */ - if (hlen > p->len) { + if (p->len < 8 || hlen > p->len) { LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("IPv6 options header (hlen %"U16_F") does not fit in first pbuf (len %"U16_F"), IPv6 packet dropped.\n", hlen, p->len)); @@ -617,7 +617,7 @@ netif_found: ip_data.current_ip_header_tot_len += hlen; /* Skip over this header. */ - if (hlen > p->len) { + if (p->len < 8 || hlen > p->len) { LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("IPv6 options header (hlen %"U16_F") does not fit in first pbuf (len %"U16_F"), IPv6 packet dropped.\n", hlen, p->len));