From bcaf2f08aab5f86d384ffe96a09755ac1b8bd210 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Wed, 30 Nov 2016 21:56:27 +0100 Subject: [PATCH] PPP, PPPoS: fix memory leak when disconnecting if there are remaining input bytes Art says: pppos_input() can call ppp_input() which can call pppos_disconnect() to disconnect the interface. However, it will continue to read in characters and allocate a pbuf from the PBUF_POOL and keep it in pppos->in_head and in_tail. When a re-connect happens and pppos_connect() is called, this pppos->in_head and in_tail are zeroed, hence a memory leak. (This happens with PPP_INPROC_IRQ_SAFE not defined.) A fix would be inside pppos_input() to break out of the loop inputting characters after calling ppp_input() if pppos->open == 0. Note that the loop is not even entered if pppos->open == 0. ppp_input(ppp, inp); if(pppos->open == 0) //get out if they disconnected break; Fix it in a similar way which doesn't add new code by moving the existing pppos->open check inside the byte loop. --- src/netif/ppp/pppos.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/netif/ppp/pppos.c b/src/netif/ppp/pppos.c index 5220ed30..eaeb2d12 100644 --- a/src/netif/ppp/pppos.c +++ b/src/netif/ppp/pppos.c @@ -471,18 +471,20 @@ pppos_input(ppp_pcb *ppp, u8_t *s, int l) u8_t escaped; PPPOS_DECL_PROTECT(lev); - PPPOS_PROTECT(lev); - if (!pppos->open) { - PPPOS_UNPROTECT(lev); - return; - } - PPPOS_UNPROTECT(lev); - PPPDEBUG(LOG_DEBUG, ("pppos_input[%d]: got %d bytes\n", ppp->netif->num, l)); while (l-- > 0) { cur_char = *s++; PPPOS_PROTECT(lev); + /* ppp_input can disconnect the interface, we need to abort to prevent a memory + * leak if there are remaining bytes because pppos_connect and pppos_listen + * functions expect input buffer to be free. Furthermore there are no real + * reason to continue reading bytes if we are disconnected. + */ + if (!pppos->open) { + PPPOS_UNPROTECT(lev); + return; + } escaped = ESCAPE_P(pppos->in_accm, cur_char); PPPOS_UNPROTECT(lev); /* Handle special characters. */