diff --git a/src/core/dns.c b/src/core/dns.c index d18c51f6..3529844d 100644 --- a/src/core/dns.c +++ b/src/core/dns.c @@ -653,7 +653,7 @@ dns_compare_name(const char *query, struct pbuf* p, u16_t start_offset) do { n = pbuf_try_get_at(p, response_offset++); - if (n < 0) { + if ((n < 0) || (response_offset == 0)) { return 0xFFFF; } /** @see RFC 1035 - 4.1.4. Message compression */ @@ -671,6 +671,9 @@ dns_compare_name(const char *query, struct pbuf* p, u16_t start_offset) return 0xFFFF; } ++response_offset; + if (response_offset == 0) { + return 0xFFFF; + } ++query; --n; } @@ -682,7 +685,10 @@ dns_compare_name(const char *query, struct pbuf* p, u16_t start_offset) } } while (n != 0); - return response_offset + 1; + if (response_offset == 0xFFFF) { + return 0xFFFF; + } + return (u16_t)(response_offset + 1); } /** @@ -700,7 +706,7 @@ dns_skip_name(struct pbuf* p, u16_t query_idx) do { n = pbuf_try_get_at(p, offset++); - if (n < 0) { + if ((n < 0) || (offset == 0)) { return 0xFFFF; } /** @see RFC 1035 - 4.1.4. Message compression */ @@ -720,7 +726,10 @@ dns_skip_name(struct pbuf* p, u16_t query_idx) } } while (n != 0); - return offset + 1; + if (offset == 0xFFFF) { + return 0xFFFF; + } + return (u16_t)(offset + 1); } /** @@ -782,9 +791,13 @@ dns_send(u8_t idx) ++n; } copy_len = (u16_t)(hostname - hostname_part); + if (query_idx + n + 1 > 0xFFFF) { + /* u16_t overflow */ + goto overflow_return; + } pbuf_put_at(p, query_idx, n); - pbuf_take_at(p, hostname_part, copy_len, query_idx + 1); - query_idx += n + 1; + pbuf_take_at(p, hostname_part, copy_len, (u16_t)(query_idx + 1)); + query_idx = (u16_t)(query_idx + n + 1); } while (*hostname != 0); pbuf_put_at(p, query_idx, 0); query_idx++; @@ -838,6 +851,9 @@ dns_send(u8_t idx) } return err; +overflow_return: + pbuf_free(p); + return ERR_VAL; } #if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_RAND_SRC_PORT) != 0) @@ -895,9 +911,9 @@ dns_alloc_pcb(void) } } /* if we come here, creating a new UDP pcb failed, so we have to use - an already existing one */ - for (i = 0, idx = dns_last_pcb_idx + 1; i < DNS_MAX_SOURCE_PORTS; i++, idx++) { - if (idx >= DNS_MAX_SOURCE_PORTS) { + an already existing one (so overflow is no issue) */ + for (i = 0, idx = (u8_t)(dns_last_pcb_idx + 1); i < DNS_MAX_SOURCE_PORTS; i++, idx++) { + if (idx >= LWIP_MAX(0xFF, DNS_MAX_SOURCE_PORTS)) { idx = 0; } if (dns_pcbs[idx] != NULL) { @@ -1203,7 +1219,10 @@ dns_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, goto memerr; /* ignore this packet */ } /* skip the rest of the "question" part */ - res_idx += SIZEOF_DNS_QUERY; + if (res_idx + SIZEOF_DNS_QUERY > 0xFFFF) { + goto memerr; + } + res_idx = (u16_t)(res_idx + SIZEOF_DNS_QUERY); /* Check for error. If so, call callback to inform. */ if (hdr.flags2 & DNS_FLAG2_ERR_MASK) { @@ -1220,7 +1239,10 @@ dns_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, if (pbuf_copy_partial(p, &ans, SIZEOF_DNS_ANSWER, res_idx) != SIZEOF_DNS_ANSWER) { goto memerr; /* ignore this packet */ } - res_idx += SIZEOF_DNS_ANSWER; + if (res_idx + SIZEOF_DNS_ANSWER > 0xFFFF) { + goto memerr; + } + res_idx = (u16_t)(res_idx + SIZEOF_DNS_ANSWER); if (ans.cls == PP_HTONS(DNS_RRCLASS_IN)) { #if LWIP_IPV4 @@ -1266,7 +1288,7 @@ dns_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, if ((int)(res_idx + lwip_htons(ans.len)) > 0xFFFF) { goto memerr; /* ignore this packet */ } - res_idx += lwip_htons(ans.len); + res_idx = (u16_t)(res_idx + lwip_htons(ans.len)); --nanswers; } #if LWIP_IPV4 && LWIP_IPV6 @@ -1362,7 +1384,7 @@ dns_enqueue(const char *name, size_t hostnamelen, dns_found_callback found, } /* check if this is the oldest completed entry */ if (entry->state == DNS_STATE_DONE) { - u8_t age = dns_seqno - entry->seqno; + u8_t age = (u8_t)(dns_seqno - entry->seqno); if (age > lseq) { lseq = age; lseqi = i; diff --git a/src/core/netif.c b/src/core/netif.c index 72c658ce..8f5c5c21 100644 --- a/src/core/netif.c +++ b/src/core/netif.c @@ -161,7 +161,7 @@ netif_loopif_init(struct netif *netif) netif->output_ip6 = netif_loop_output_ipv6; #endif #if LWIP_LOOPIF_MULTICAST - netif->flags |= NETIF_FLAG_IGMP; + netif_set_flags(netif, NETIF_FLAG_IGMP); #endif return ERR_OK; } @@ -380,7 +380,11 @@ netif_add(struct netif *netif, } } while (netif2 != NULL); } - netif_num = netif->num + 1; + if (netif->num == 254) { + netif_num = 0; + } else { + netif_num = (u8_t)(netif->num + 1); + } /* add this netif to the list */ netif->next = netif_list; @@ -724,7 +728,7 @@ void netif_set_up(struct netif *netif) { if (!(netif->flags & NETIF_FLAG_UP)) { - netif->flags |= NETIF_FLAG_UP; + netif_set_flags(netif, NETIF_FLAG_UP); MIB2_COPY_SYSUPTIME_TO(&netif->ts); @@ -798,7 +802,7 @@ netif_set_down(struct netif *netif) } #endif - netif->flags &= ~NETIF_FLAG_UP; + netif_clear_flags(netif, NETIF_FLAG_UP); MIB2_COPY_SYSUPTIME_TO(&netif->ts); #if LWIP_IPV4 && LWIP_ARP @@ -851,7 +855,7 @@ void netif_set_link_up(struct netif *netif) { if (!(netif->flags & NETIF_FLAG_LINK_UP)) { - netif->flags |= NETIF_FLAG_LINK_UP; + netif_set_flags(netif, NETIF_FLAG_LINK_UP); #if LWIP_DHCP dhcp_network_changed(netif); @@ -883,7 +887,7 @@ void netif_set_link_down(struct netif *netif ) { if (netif->flags & NETIF_FLAG_LINK_UP) { - netif->flags &= ~NETIF_FLAG_LINK_UP; + netif_clear_flags(netif, NETIF_FLAG_LINK_UP); NETIF_LINK_CALLBACK(netif); #if LWIP_NETIF_EXT_STATUS_CALLBACK { @@ -963,7 +967,7 @@ netif_loop_output(struct netif *netif, struct pbuf *p) MIB2_STATS_NETIF_INC(stats_if, ifoutdiscards); return ERR_MEM; } - netif->loop_cnt_current += clen; + netif->loop_cnt_current = (u16_t)(netif->loop_cnt_current + clen); #endif /* LWIP_LOOPBACK_MAX_PBUFS */ /* Copy the whole pbuf queue p into the single pbuf r */ @@ -1067,7 +1071,7 @@ netif_poll(struct netif *netif) /* adjust the number of pbufs on queue */ LWIP_ASSERT("netif->loop_cnt_current underflow", ((netif->loop_cnt_current - clen) < netif->loop_cnt_current)); - netif->loop_cnt_current -= clen; + netif->loop_cnt_current = (u16_t)(netif->loop_cnt_current - clen); #endif /* LWIP_LOOPBACK_MAX_PBUFS */ /* 'in_end' now points to the last pbuf from 'in' */ @@ -1126,8 +1130,11 @@ netif_alloc_client_data_id(void) u8_t result = netif_client_id; netif_client_id++; +#if LWIP_NUM_NETIF_CLIENT_DATA > 256 +#error LWIP_NUM_NETIF_CLIENT_DATA must be <= 256 +#endif LWIP_ASSERT("Increase LWIP_NUM_NETIF_CLIENT_DATA in lwipopts.h", result < LWIP_NUM_NETIF_CLIENT_DATA); - return result + LWIP_NETIF_CLIENT_DATA_INDEX_MAX; + return (u8_t)(result + LWIP_NETIF_CLIENT_DATA_INDEX_MAX); } #endif diff --git a/src/include/lwip/netif.h b/src/include/lwip/netif.h index fc787299..13af5c44 100644 --- a/src/include/lwip/netif.h +++ b/src/include/lwip/netif.h @@ -427,6 +427,10 @@ void netif_set_gw(struct netif *netif, const ip4_addr_t *gw); #define netif_ip_gw4(netif) ((const ip_addr_t*)&((netif)->gw)) #endif /* LWIP_IPV4 */ +#define netif_set_flags(netif, set_flags) do { (netif)->flags = (u8_t)((netif)->flags | (set_flags)); } while(0) +#define netif_clear_flags(netif, set_flags) do { (netif)->flags = (u8_t)((netif)->flags & ~(set_flags)); } while(0) +#define netif_is_flag_set(nefif, flag) (((netif)->flags & (flag)) != 0) + void netif_set_up(struct netif *netif); void netif_set_down(struct netif *netif); /** @ingroup netif @@ -521,8 +525,8 @@ u8_t netif_name_to_index(const char *name); char * netif_index_to_name(u8_t idx, char *name); struct netif* netif_get_by_index(u8_t idx); -/* Interface indexes always start at 1 per RFC 3493, section 4, num starts at 0 */ -#define netif_get_index(netif) ((netif)->num + 1) +/* Interface indexes always start at 1 per RFC 3493, section 4, num starts at 0 (internal index is 0..254)*/ +#define netif_get_index(netif) ((u8_t)((netif)->num + 1)) #define NETIF_NO_INDEX (0) /** diff --git a/src/include/lwip/opt.h b/src/include/lwip/opt.h index db2322b6..c87e794c 100644 --- a/src/include/lwip/opt.h +++ b/src/include/lwip/opt.h @@ -1546,7 +1546,7 @@ /** * LWIP_NUM_NETIF_CLIENT_DATA: Number of clients that may store - * data in client_data member array of struct netif. + * data in client_data member array of struct netif (max. 256). */ #if !defined LWIP_NUM_NETIF_CLIENT_DATA || defined __DOXYGEN__ #define LWIP_NUM_NETIF_CLIENT_DATA 0