PPP, PPPoL2TP, fix double free of L2TP pcb in pppol2tp_create error path

ppp_free() calls the low level protocol destroy function, pppol2tp_destroy()
here, which freed the l2tp pcb, followed by pppol2tp_create which also freed
the pcb.

Fixing it by reordering the L2TP init so we don't have to call ppp_free()
anymore.

Signed-off-by: Sylvain Rochet <gradator@gradator.net>
This commit is contained in:
Sylvain Rochet 2016-01-20 21:12:37 +01:00
parent 52463fa25b
commit c4d78e6422

View File

@ -129,11 +129,6 @@ ppp_pcb *pppol2tp_create(struct netif *pppif,
goto memp_malloc_l2tp_failed; goto memp_malloc_l2tp_failed;
} }
ppp = ppp_new(pppif, &pppol2tp_callbacks, l2tp, link_status_cb, ctx_cb);
if (ppp == NULL) {
goto ppp_new_failed;
}
#if LWIP_IPV6 #if LWIP_IPV6
if (IP_IS_V6_VAL(*ipaddr)) { if (IP_IS_V6_VAL(*ipaddr)) {
udp = udp_new_ip6(); udp = udp_new_ip6();
@ -145,6 +140,11 @@ ppp_pcb *pppol2tp_create(struct netif *pppif,
} }
udp_recv(udp, pppol2tp_input, l2tp); udp_recv(udp, pppol2tp_input, l2tp);
ppp = ppp_new(pppif, &pppol2tp_callbacks, l2tp, link_status_cb, ctx_cb);
if (ppp == NULL) {
goto ppp_new_failed;
}
memset(l2tp, 0, sizeof(pppol2tp_pcb)); memset(l2tp, 0, sizeof(pppol2tp_pcb));
l2tp->phase = PPPOL2TP_STATE_INITIAL; l2tp->phase = PPPOL2TP_STATE_INITIAL;
l2tp->ppp = ppp; l2tp->ppp = ppp;
@ -159,9 +159,9 @@ ppp_pcb *pppol2tp_create(struct netif *pppif,
return ppp; return ppp;
udp_new_failed:
ppp_free(ppp);
ppp_new_failed: ppp_new_failed:
udp_remove(udp);
udp_new_failed:
memp_free(MEMP_PPPOL2TP_PCB, l2tp); memp_free(MEMP_PPPOL2TP_PCB, l2tp);
memp_malloc_l2tp_failed: memp_malloc_l2tp_failed:
ipaddr_check_failed: ipaddr_check_failed: