mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2024-10-05 22:29:49 +00:00
fixed bug #43173, pppos_input() corrupts memory if IP_FORWARD is enabled
This commit is contained in:
parent
b8d798158b
commit
ab9feb2e35
@ -1622,6 +1622,10 @@ pppos_input(ppp_pcb *pcb, u_char *s, int l)
|
|||||||
/* Packet consumed, release our references. */
|
/* Packet consumed, release our references. */
|
||||||
pcrx->in_head = NULL;
|
pcrx->in_head = NULL;
|
||||||
pcrx->in_tail = NULL;
|
pcrx->in_tail = NULL;
|
||||||
|
#if IP_FORWARD || LWIP_IPV6_FORWARD
|
||||||
|
/* hide the room for Ethernet forwarding header */
|
||||||
|
pbuf_header(inp, -(s16_t)PBUF_LINK_HLEN);
|
||||||
|
#endif /* IP_FORWARD || LWIP_IPV6_FORWARD */
|
||||||
#if PPP_INPROC_MULTITHREADED
|
#if PPP_INPROC_MULTITHREADED
|
||||||
if(tcpip_callback_with_block(pppos_input_callback, inp, 0) != ERR_OK) {
|
if(tcpip_callback_with_block(pppos_input_callback, inp, 0) != ERR_OK) {
|
||||||
PPPDEBUG(LOG_ERR, ("pppos_input[%d]: tcpip_callback() failed, dropping packet\n", pcb->num));
|
PPPDEBUG(LOG_ERR, ("pppos_input[%d]: tcpip_callback() failed, dropping packet\n", pcb->num));
|
||||||
@ -1711,6 +1715,7 @@ pppos_input(ppp_pcb *pcb, 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->in_tail == NULL || pcrx->in_tail->len == PBUF_POOL_BUFSIZE) {
|
if (pcrx->in_tail == NULL || pcrx->in_tail->len == PBUF_POOL_BUFSIZE) {
|
||||||
|
u16_t pbuf_alloc_len;
|
||||||
if (pcrx->in_tail != NULL) {
|
if (pcrx->in_tail != NULL) {
|
||||||
pcrx->in_tail->tot_len = pcrx->in_tail->len;
|
pcrx->in_tail->tot_len = pcrx->in_tail->len;
|
||||||
if (pcrx->in_tail != pcrx->in_head) {
|
if (pcrx->in_tail != pcrx->in_head) {
|
||||||
@ -1720,45 +1725,35 @@ pppos_input(ppp_pcb *pcb, u_char *s, int l)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* If we haven't started a packet, we need a packet header. */
|
/* If we haven't started a packet, we need a packet header. */
|
||||||
|
pbuf_alloc_len = 0;
|
||||||
#if IP_FORWARD || LWIP_IPV6_FORWARD
|
#if IP_FORWARD || LWIP_IPV6_FORWARD
|
||||||
/* If IP forwarding is enabled we are using a PBUF_LINK packet type so
|
/* If IP forwarding is enabled we are reserving PBUF_LINK_HLEN bytes so
|
||||||
* the packet is being allocated with enough header space to be
|
* the packet is being allocated with enough header space to be
|
||||||
* forwarded (to Ethernet for example).
|
* forwarded (to Ethernet for example).
|
||||||
*/
|
*/
|
||||||
next_pbuf = pbuf_alloc(PBUF_LINK, 0, PBUF_POOL);
|
if (pcrx->in_head == NULL) {
|
||||||
#else /* IP_FORWARD || LWIP_IPV6_FORWARD */
|
pbuf_alloc_len = PBUF_LINK_HLEN;
|
||||||
next_pbuf = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL);
|
}
|
||||||
#endif /* IP_FORWARD || LWIP_IPV6_FORWARD */
|
#endif /* IP_FORWARD || LWIP_IPV6_FORWARD */
|
||||||
|
next_pbuf = pbuf_alloc(PBUF_RAW, pbuf_alloc_len, PBUF_POOL);
|
||||||
if (next_pbuf == NULL) {
|
if (next_pbuf == NULL) {
|
||||||
/* No free buffers. Drop the input packet and let the
|
/* No free buffers. Drop the input packet and let the
|
||||||
* higher layers deal with it. Continue processing
|
* higher layers deal with it. Continue processing
|
||||||
* the received pbuf chain in case a new packet starts. */
|
* the received pbuf chain in case a new packet starts. */
|
||||||
PPPDEBUG(LOG_ERR, ("pppos_input[%d]: NO FREE MBUFS!\n", pcb->num));
|
PPPDEBUG(LOG_ERR, ("pppos_input[%d]: NO FREE PBUFS!\n", pcb->num));
|
||||||
LINK_STATS_INC(link.memerr);
|
LINK_STATS_INC(link.memerr);
|
||||||
ppp_drop(pcrx);
|
ppp_drop(pcrx);
|
||||||
pcrx->in_state = PDSTART; /* Wait for flag sequence. */
|
pcrx->in_state = PDSTART; /* Wait for flag sequence. */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (pcrx->in_head == NULL) {
|
if (pcrx->in_head == NULL) {
|
||||||
u8_t *payload;
|
u8_t *payload = ((u8_t*)next_pbuf->payload) + pbuf_alloc_len;
|
||||||
/* pbuf_header() used below is only trying to put PPP headers
|
|
||||||
* before the current payload pointer if there is enough space
|
|
||||||
* in the pbuf to do so. Therefore we don't care if it fails,
|
|
||||||
* but if it fail we have to set len to the size used by PPP headers.
|
|
||||||
*/
|
|
||||||
#if PPP_INPROC_MULTITHREADED
|
#if PPP_INPROC_MULTITHREADED
|
||||||
if (pbuf_header(next_pbuf, +sizeof(struct pppos_input_header) +sizeof(pcrx->in_protocol))) {
|
|
||||||
next_pbuf->len += sizeof(struct pppos_input_header) + sizeof(pcrx->in_protocol);
|
|
||||||
}
|
|
||||||
payload = next_pbuf->payload;
|
|
||||||
((struct pppos_input_header*)payload)->pcb = pcb;
|
((struct pppos_input_header*)payload)->pcb = pcb;
|
||||||
payload += sizeof(struct pppos_input_header);
|
payload += sizeof(struct pppos_input_header);
|
||||||
#else /* PPP_INPROC_MULTITHREADED */
|
next_pbuf->len += sizeof(struct pppos_input_header);
|
||||||
if (pbuf_header(next_pbuf, +sizeof(pcrx->in_protocol))) {
|
|
||||||
next_pbuf->len += sizeof(pcrx->in_protocol);
|
|
||||||
}
|
|
||||||
payload = next_pbuf->payload;
|
|
||||||
#endif /* PPP_INPROC_MULTITHREADED */
|
#endif /* PPP_INPROC_MULTITHREADED */
|
||||||
|
next_pbuf->len += sizeof(pcrx->in_protocol);
|
||||||
*(payload++) = pcrx->in_protocol >> 8;
|
*(payload++) = pcrx->in_protocol >> 8;
|
||||||
*(payload) = pcrx->in_protocol & 0xFF;
|
*(payload) = pcrx->in_protocol & 0xFF;
|
||||||
pcrx->in_head = next_pbuf;
|
pcrx->in_head = next_pbuf;
|
||||||
|
Loading…
Reference in New Issue
Block a user