Fixed bug #32280 (ppp: a pbuf is freed twice)

This commit is contained in:
goldsimon 2011-03-27 13:58:26 +00:00
parent b54c7bedfd
commit b5dd87b184
2 changed files with 14 additions and 7 deletions

View File

@ -237,6 +237,9 @@ HISTORY
++ Bugfixes: ++ Bugfixes:
2011-03-27: Simon Goldschmidt
* ppp.c: Fixed bug #32280 (ppp: a pbuf is freed twice)
2011-03-27: Simon Goldschmidt 2011-03-27: Simon Goldschmidt
* sockets.c: Fixed bug #32906: lwip_connect+lwip_send did not work for udp and * sockets.c: Fixed bug #32906: lwip_connect+lwip_send did not work for udp and
raw pcbs with LWIP_TCPIP_CORE_LOCKING==1. raw pcbs with LWIP_TCPIP_CORE_LOCKING==1.

View File

@ -365,7 +365,6 @@ pppLinkTerminated(int pd)
PPPControl* pc; PPPControl* pc;
pppRecvWakeup(pd); pppRecvWakeup(pd);
pc = &pppControl[pd]; pc = &pppControl[pd];
pppDrop(&pc->rx); /* bug fix #17726 */
PPPDEBUG(LOG_DEBUG, ("pppLinkTerminated: unit %d: linkStatusCB=%p errCode=%d\n", pd, pc->linkStatusCB, pc->errCode)); PPPDEBUG(LOG_DEBUG, ("pppLinkTerminated: unit %d: linkStatusCB=%p errCode=%d\n", pd, pc->linkStatusCB, pc->errCode));
if (pc->linkStatusCB) { if (pc->linkStatusCB) {
@ -1799,6 +1798,7 @@ pppInProc(PPPControlRx *pcrx, u_char *s, int l)
pppDrop(pcrx); pppDrop(pcrx);
/* Otherwise it's a good packet so pass it on. */ /* Otherwise it's a good packet so pass it on. */
} else { } else {
struct pbuf *inp;
/* Trim off the checksum. */ /* Trim off the checksum. */
if(pcrx->inTail->len >= 2) { if(pcrx->inTail->len >= 2) {
pcrx->inTail->len -= 2; pcrx->inTail->len -= 2;
@ -1817,18 +1817,20 @@ pppInProc(PPPControlRx *pcrx, u_char *s, int l)
} }
/* Dispatch the packet thereby consuming it. */ /* Dispatch the packet thereby consuming it. */
inp = pcrx->inHead;
/* Packet consumed, release our references. */
pcrx->inHead = NULL;
pcrx->inTail = NULL;
#if PPP_INPROC_MULTITHREADED #if PPP_INPROC_MULTITHREADED
if(tcpip_callback_with_block(pppInput, pcrx->inHead, 0) != ERR_OK) { if(tcpip_callback_with_block(pppInput, inp, 0) != ERR_OK) {
PPPDEBUG(LOG_ERR, ("pppInProc[%d]: tcpip_callback() failed, dropping packet\n", pcrx->pd)); PPPDEBUG(LOG_ERR, ("pppInProc[%d]: tcpip_callback() failed, dropping packet\n", pcrx->pd));
pbuf_free(pcrx->inHead); pbuf_free(inp);
LINK_STATS_INC(link.drop); LINK_STATS_INC(link.drop);
snmp_inc_ifindiscards(&pppControl[pcrx->pd].netif); snmp_inc_ifindiscards(&pppControl[pcrx->pd].netif);
} }
#else /* PPP_INPROC_MULTITHREADED */ #else /* PPP_INPROC_MULTITHREADED */
pppInput(pcrx->inHead); pppInput(inp);
#endif /* PPP_INPROC_MULTITHREADED */ #endif /* PPP_INPROC_MULTITHREADED */
pcrx->inHead = NULL;
pcrx->inTail = NULL;
} }
/* Prepare for a new packet. */ /* Prepare for a new packet. */
@ -1902,10 +1904,12 @@ pppInProc(PPPControlRx *pcrx, u_char *s, int l)
case PDDATA: /* Process data byte. */ case PDDATA: /* Process data byte. */
/* Make space to receive processed data. */ /* Make space to receive processed data. */
if (pcrx->inTail == NULL || pcrx->inTail->len == PBUF_POOL_BUFSIZE) { if (pcrx->inTail == NULL || pcrx->inTail->len == PBUF_POOL_BUFSIZE) {
if(pcrx->inTail) { if (pcrx->inTail != NULL) {
pcrx->inTail->tot_len = pcrx->inTail->len; pcrx->inTail->tot_len = pcrx->inTail->len;
if (pcrx->inTail != pcrx->inHead) { if (pcrx->inTail != pcrx->inHead) {
pbuf_cat(pcrx->inHead, pcrx->inTail); pbuf_cat(pcrx->inHead, pcrx->inTail);
/* give up the inTail reference now */
pcrx->inTail = NULL;
} }
} }
/* If we haven't started a packet, we need a packet header. */ /* If we haven't started a packet, we need a packet header. */