Skip to content

Commit

Permalink
icmp6: Fix copying of chained pbuf in reply
Browse files Browse the repository at this point in the history
Fixes bug #58553, and the newly added unit test.

The pbuf_take_at loop should probably be made into a pbuf library
function, which would avoid this mistake in the future and provide
a simpler implementation of pbuf_copy.
  • Loading branch information
yarrick authored and david-cermak committed Dec 7, 2021
1 parent 29100ab commit 7c822ff
Showing 1 changed file with 11 additions and 2 deletions.
13 changes: 11 additions & 2 deletions src/core/ipv6/icmp6.c
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,7 @@ icmp6_send_response_with_addrs_and_netif(struct pbuf *p, u8_t code, u32_t data,
struct pbuf *q;
struct icmp6_hdr *icmp6hdr;
u16_t datalen = LWIP_MIN(p->tot_len, LWIP_ICMP6_DATASIZE);
u16_t offset;

/* ICMPv6 header + datalen (as much of the offending packet as possible) */
q = pbuf_alloc(PBUF_IP, sizeof(struct icmp6_hdr) + datalen,
Expand All @@ -405,8 +406,16 @@ icmp6_send_response_with_addrs_and_netif(struct pbuf *p, u8_t code, u32_t data,
icmp6hdr->code = code;
icmp6hdr->data = lwip_htonl(data);

/* copy fields from original packet */
pbuf_take_at(q, p->payload, datalen, sizeof(struct icmp6_hdr));
/* copy fields from original packet (which may be a chain of pbufs) */
offset = sizeof(struct icmp6_hdr);
while (p && datalen) {
u16_t len = LWIP_MIN(datalen, p->len);
err_t res = pbuf_take_at(q, p->payload, datalen, offset);
if (res != ERR_OK) break;
datalen -= len;
offset += len;
p = p->next;
}

/* calculate checksum */
icmp6hdr->chksum = 0;
Expand Down

0 comments on commit 7c822ff

Please sign in to comment.