mirror of
https://git.savannah.nongnu.org/git/lwip.git
synced 2026-06-13 08:23:56 +08:00
tcp: handle segmentation oversize during segment split (bug #52676)
This fixes a bug in tcp_split_unsent_seg where oversized segments were not handled during the split, leading to pcb->unsent_oversized and useg->oversize_left getting out of sync with the split segment This would result in over-writing the pbuf if another call to tcp_write() happened after the split, but before the remainder of the split was sent in tcp_output Now pcb->unsent_oversized is explicitly cleared (because the remainder at the tail is never oversized) and useg->oversized_left is cleared after it is trimmed This also updates the test_tcp_persist_split unit test to explicitly check for this case
This commit is contained in:
@@ -1902,6 +1902,10 @@ tcp_split_unsent_seg(struct tcp_pcb *pcb, u16_t split)
|
||||
pbuf_realloc(useg->p, useg->p->tot_len - remainder);
|
||||
useg->len -= remainder;
|
||||
TCPH_SET_FLAG(useg->tcphdr, split_flags);
|
||||
#if TCP_OVERSIZE_DBGCHECK
|
||||
/* By trimming, realloc may have actually shrunk the pbuf, so clear oversize_left */
|
||||
useg->oversize_left = 0;
|
||||
#endif /* TCP_OVERSIZE_DBGCHECK */
|
||||
|
||||
#if TCP_CHECKSUM_ON_COPY
|
||||
/* The checksum on the split segment is now incorrect. We need to re-run it over the split */
|
||||
@@ -1932,6 +1936,14 @@ tcp_split_unsent_seg(struct tcp_pcb *pcb, u16_t split)
|
||||
seg->next = useg->next;
|
||||
useg->next = seg;
|
||||
|
||||
#if TCP_OVERSIZE
|
||||
/* If remainder is last segment on the unsent, ensure we clear the oversize amount
|
||||
* because the remainder is always sized to the exact remaining amount */
|
||||
if (seg->next == NULL) {
|
||||
pcb->unsent_oversize = 0;
|
||||
}
|
||||
#endif /* TCP_OVERSIZE */
|
||||
|
||||
return ERR_OK;
|
||||
memerr:
|
||||
TCP_STATS_INC(tcp.memerr);
|
||||
|
||||
Reference in New Issue
Block a user