mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2024-08-24 15:16:02 +00:00
udp/raw: prevent packet length overflows
Previously, on netifs with unrestricted MTUs (typically loopback interfaces), it was possible to give a packet to the UDP/RAW API calls that is so large that when prepending headers, the pbuf's tot_len field would overflow. This could easily result in undesirable behavior at lower layers, e.g. a crash when copying the packet for later delivery. This patch models such overflows as memory allocation errors, thus resulting in clean failures. Checks have to be added in multiple places to cover (hopefully) all cases.
This commit is contained in:
parent
fffd61c746
commit
03f47e58a3
|
@ -583,6 +583,10 @@ pbuf_header_impl(struct pbuf *p, s16_t header_size_increment, u8_t force)
|
||||||
LWIP_ERROR("increment_magnitude <= p->len", (increment_magnitude <= p->len), return 1;);
|
LWIP_ERROR("increment_magnitude <= p->len", (increment_magnitude <= p->len), return 1;);
|
||||||
} else {
|
} else {
|
||||||
increment_magnitude = (u16_t)header_size_increment;
|
increment_magnitude = (u16_t)header_size_increment;
|
||||||
|
/* Do not allow tot_len to wrap as a result. */
|
||||||
|
if ((u16_t)(increment_magnitude + p->tot_len) < increment_magnitude) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
#if 0
|
#if 0
|
||||||
/* Can't assert these as some callers speculatively call
|
/* Can't assert these as some callers speculatively call
|
||||||
pbuf_header() to see if it's OK. Will return 1 below instead. */
|
pbuf_header() to see if it's OK. Will return 1 below instead. */
|
||||||
|
|
|
@ -403,6 +403,10 @@ raw_sendto_if_src(struct raw_pcb *pcb, struct pbuf *p, const ip_addr_t *dst_ip,
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* packet too large to add an IP header without causing an overflow? */
|
||||||
|
if ((u16_t)(p->tot_len + header_size) < p->tot_len) {
|
||||||
|
return ERR_MEM;
|
||||||
|
}
|
||||||
/* not enough space to add an IP header to first pbuf in given p chain? */
|
/* not enough space to add an IP header to first pbuf in given p chain? */
|
||||||
if (pbuf_header(p, header_size)) {
|
if (pbuf_header(p, header_size)) {
|
||||||
/* allocate header in new pbuf */
|
/* allocate header in new pbuf */
|
||||||
|
|
|
@ -701,6 +701,10 @@ udp_sendto_if_src_chksum(struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *d
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* packet too large to add a UDP header without causing an overflow? */
|
||||||
|
if ((u16_t)(p->tot_len + UDP_HLEN) < p->tot_len) {
|
||||||
|
return ERR_MEM;
|
||||||
|
}
|
||||||
/* not enough space to add an UDP header to first pbuf in given p chain? */
|
/* not enough space to add an UDP header to first pbuf in given p chain? */
|
||||||
if (pbuf_header(p, UDP_HLEN)) {
|
if (pbuf_header(p, UDP_HLEN)) {
|
||||||
/* allocate header in a separate new pbuf */
|
/* allocate header in a separate new pbuf */
|
||||||
|
|
Loading…
Reference in New Issue
Block a user