[PATCH] Drop instead of ASSERT in tcp_input header parsing

Since allowing input validation to trip the ASSERT handler is bad,
let's just drop the packets instead if validation fails.

Signed-off-by: sg <goldsimon@gmx.de>
This commit is contained in:
Henrik Persson
2016-06-13 20:08:43 +02:00
committed by sg
parent 25652254a5
commit b9a2ee8aaa
2 changed files with 94 additions and 6 deletions

View File

@@ -3,6 +3,7 @@
#include "lwip/priv/tcp_priv.h"
#include "lwip/stats.h"
#include "tcp_helper.h"
#include "lwip/inet_chksum.h"
#ifdef _MSC_VER
#pragma warning(disable: 4307) /* we explicitly wrap around TCP seqnos */
@@ -122,6 +123,75 @@ START_TEST(test_tcp_recv_inseq)
}
END_TEST
/** Check that we handle malformed tcp headers, and discard the pbuf(s) */
START_TEST(test_tcp_malformed_header)
{
struct test_tcp_counters counters;
struct tcp_pcb* pcb;
struct pbuf* p;
char data[] = {1, 2, 3, 4};
ip_addr_t remote_ip, local_ip, netmask;
u16_t data_len, chksum;
u16_t remote_port = 0x100, local_port = 0x101;
struct netif netif;
struct test_tcp_txcounters txcounters;
struct tcp_hdr *hdr;
LWIP_UNUSED_ARG(_i);
/* initialize local vars */
memset(&netif, 0, sizeof(netif));
IP_ADDR4(&local_ip, 192, 168, 1, 1);
IP_ADDR4(&remote_ip, 192, 168, 1, 2);
IP_ADDR4(&netmask, 255, 255, 255, 0);
test_tcp_init_netif(&netif, &txcounters, &local_ip, &netmask);
data_len = sizeof(data);
/* initialize counter struct */
memset(&counters, 0, sizeof(counters));
counters.expected_data_len = data_len;
counters.expected_data = data;
/* create and initialize the pcb */
pcb = test_tcp_new_counters_pcb(&counters);
EXPECT_RET(pcb != NULL);
tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port);
/* create a segment */
p = tcp_create_rx_segment(pcb, counters.expected_data, data_len, 0, 0, 0);
pbuf_header(p, -(s16_t)sizeof(struct ip_hdr));
hdr = (struct tcp_hdr *)p->payload;
TCPH_HDRLEN_FLAGS_SET(hdr, 15, 0x3d1);
hdr->chksum = 0;
chksum = ip_chksum_pseudo(p, IP_PROTO_TCP, p->tot_len,
&remote_ip, &local_ip);
hdr->chksum = chksum;
pbuf_header(p, sizeof(struct ip_hdr));
EXPECT(p != NULL);
EXPECT(p->next == NULL);
if (p != NULL) {
/* pass the segment to tcp_input */
test_tcp_input(p, &netif);
/* check if counters are as expected */
EXPECT(counters.close_calls == 0);
EXPECT(counters.recv_calls == 0);
EXPECT(counters.recved_bytes == 0);
EXPECT(counters.err_calls == 0);
}
/* make sure the pcb is freed */
EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 1);
tcp_abort(pcb);
EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 0);
}
END_TEST
/** Provoke fast retransmission by duplicate ACKs and then recover by ACKing all sent data.
* At the end, send more data. */
START_TEST(test_tcp_fast_retx_recover)
@@ -661,6 +731,7 @@ tcp_suite(void)
testfunc tests[] = {
TESTFUNC(test_tcp_new_abort),
TESTFUNC(test_tcp_recv_inseq),
TESTFUNC(test_tcp_malformed_header),
TESTFUNC(test_tcp_fast_retx_recover),
TESTFUNC(test_tcp_fast_rexmit_wraparound),
TESTFUNC(test_tcp_rto_rexmit_wraparound),