[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[lwip-devel] [bug #57377] Assertion "pbuf_free: p->ref > 0" failed
From: |
Erik Ekman |
Subject: |
[lwip-devel] [bug #57377] Assertion "pbuf_free: p->ref > 0" failed |
Date: |
Fri, 19 Jun 2020 08:55:35 -0400 (EDT) |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36 |
Follow-up Comment #3, bug #57377 (project lwip):
I agree that this looks like a double free.
tcp_slowtmr: processing active pcb
pbuf_alloc(length=1)
pbuf_alloc(length=1) == 0x43d816
tcp_create_segment: no memory.
pbuf_free(0x43d816)
pbuf_free: deallocating 0x43d816
tcp_split_unsent_seg: could not create new TCP segment
pbuf_free(0x43d816)
Assertion "pbuf_free: p->ref > 0" failed at line 753 in ../../src/core/pbuf.c
tcp_create_segment() frees the pbuf pointer, but this is not noticed by the
caller since the pbuf was sent as a normal pointer (not pointer to pointer):
static struct tcp_seg *
tcp_create_segment(const struct tcp_pcb *pcb, struct pbuf *p, u8_t hdrflags,
u32_t seqno, u8_t optflags);
Callers to tcp_create_segment:
tcp_write() line 666:
- Does not free the pbuf on error
tcp_split_unsent_seg() line 914:
- Does free pbuf on error (the case found in this bug)
tcp_enqueue_flags() line 1085:
- Does not free the pbuf on error
It seems the standard is to expect that the pbuf is freed, and
tcp_split_unsent_seg() should be updated to not try to free it again.
My proposed fix would be:
diff --git a/src/core/tcp_out.c b/src/core/tcp_out.c
index bfb033b1..d9d1b57b 100644
--- a/src/core/tcp_out.c
+++ b/src/core/tcp_out.c
@@ -913,6 +913,7 @@ tcp_split_unsent_seg(struct tcp_pcb *pcb, u16_t split)
seg = tcp_create_segment(pcb, p, remainder_flags,
lwip_ntohl(useg->tcphdr->seqno) + split, optflags);
if (seg == NULL) {
+ p = NULL; /* Freed by tcp_create_segment */
LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
("tcp_split_unsent_seg: could not create new TCP
segment\n"));
goto memerr;
which removes the double free, and makes the test input not crash.
Supplying a pointer to pointer to tcp_create_segment is more work, and there
are many ways the pbuf can be freed (like via tcp_seg_free, so it would be
easy to miss resetting the pbuf pointer).
_______________________________________________________
Reply to this item at:
<https://savannah.nongnu.org/bugs/?57377>
_______________________________________________
Message sent via Savannah
https://savannah.nongnu.org/