diff --git a/test/fuzz/Makefile b/test/fuzz/Makefile index 67ffb195..ccbe9561 100644 --- a/test/fuzz/Makefile +++ b/test/fuzz/Makefile @@ -34,13 +34,14 @@ all compile: lwip_fuzz CC=afl-gcc LDFLAGS=-lm -CFLAGS=-O0 +# use 'make D=-DUSER_DEFINE' to pass a user define to gcc +CFLAGS=-O0 $(D) CONTRIBDIR=../../../lwip-contrib include $(CONTRIBDIR)/ports/unix/Common.mk clean: - rm -f *.o $(LWIPLIBCOMMON) lwip_fuzz *.s .depend* *.core core + rm -f *.o $(LWIPLIBCOMMON) $(APPLIB) lwip_fuzz *.s .depend* *.core core depend dep: .depend @@ -49,5 +50,5 @@ include .depend .depend: fuzz.c $(LWIPFILES) $(APPFILES) $(CCDEP) $(CFLAGS) -MM $^ > .depend || rm -f .depend -lwip_fuzz: .depend $(LWIPLIBCOMMON) fuzz.o - $(CC) $(CFLAGS) -o lwip_fuzz fuzz.o $(LWIPLIBCOMMON) $(LDFLAGS) +lwip_fuzz: .depend $(LWIPLIBCOMMON) $(APPLIB) fuzz.o + $(CC) $(CFLAGS) -o lwip_fuzz fuzz.o $(APPLIB) $(LWIPLIBCOMMON) $(LDFLAGS) diff --git a/test/fuzz/README b/test/fuzz/README index 1d1e3d8d..de6fb756 100644 --- a/test/fuzz/README +++ b/test/fuzz/README @@ -10,6 +10,9 @@ the code and keeping track of which code is executed. Just running make will produce the test program. +Running make with parameter 'D=-DLWIP_FUZZ_MULTI_PACKET' will produce a binary +that parses the input data as multiple packets (experimental!). + Then run afl with: afl-fuzz -i inputs/ -o output ./lwip_fuzz diff --git a/test/fuzz/fuzz.c b/test/fuzz/fuzz.c index a9157f13..36383329 100644 --- a/test/fuzz/fuzz.c +++ b/test/fuzz/fuzz.c @@ -32,14 +32,31 @@ #include "lwip/init.h" #include "lwip/netif.h" +#include "lwip/dns.h" #include "netif/etharp.h" #if LWIP_IPV6 #include "lwip/ethip6.h" #include "lwip/nd6.h" #endif + +#include "lwip/apps/httpd.h" +#include "lwip/apps/snmp.h" +#include "lwip/apps/lwiperf.h" +#include "lwip/apps/mdns.h" + #include #include +/* This define enables multi packet processing. + * For this, the input is interpreted as 2 byte length + data + 2 byte length + data... + * #define LWIP_FUZZ_MULTI_PACKET +*/ +#ifdef LWIP_FUZZ_MULTI_PACKET +u8_t pktbuf[20000]; +#else +u8_t pktbuf[2000]; +#endif + /* no-op send function */ static err_t lwip_tx_func(struct netif *netif, struct pbuf *p) { @@ -56,7 +73,7 @@ static err_t testif_init(struct netif *netif) netif->linkoutput = lwip_tx_func; netif->mtu = 1500; netif->hwaddr_len = 6; - netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP; + netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_IGMP; netif->hwaddr[0] = 0x00; netif->hwaddr[1] = 0x23; @@ -93,13 +110,38 @@ static void input_pkt(struct netif *netif, const u8_t *data, size_t len) } } +static void input_pkts(struct netif *netif, const u8_t *data, size_t len) +{ +#ifdef LWIP_FUZZ_MULTI_PACKET + const u16_t max_packet_size = 1514; + const u8_t *ptr = data; + size_t rem_len = len; + + while (rem_len > sizeof(u16_t)) { + u16_t frame_len; + memcpy(&frame_len, ptr, sizeof(u16_t)); + ptr += sizeof(u16_t); + rem_len -= sizeof(u16_t); + frame_len = htons(frame_len) & 0x7FF; + frame_len = LWIP_MIN(frame_len, max_packet_size); + if (frame_len > rem_len) { + frame_len = rem_len; + } + input_pkt(netif, ptr, frame_len); + ptr += frame_len; + rem_len -= frame_len; + } +#else /* LWIP_FUZZ_MULTI_PACKET */ + input_pkt(netif, data, len); +#endif /* LWIP_FUZZ_MULTI_PACKET */ +} + int main(int argc, char** argv) { struct netif net_test; ip4_addr_t addr; ip4_addr_t netmask; ip4_addr_t gw; - u8_t pktbuf[2000]; size_t len; lwip_init(); @@ -110,10 +152,19 @@ int main(int argc, char** argv) netif_add(&net_test, &addr, &netmask, &gw, &net_test, testif_init, ethernet_input); netif_set_up(&net_test); + netif_set_link_up(&net_test); #if LWIP_IPV6 nd6_tmr(); /* tick nd to join multicast groups */ #endif + dns_setserver(0, &net_test.gw); + + /* initialize apps */ + httpd_init(); + lwiperf_start_tcp_server_default(NULL, NULL); + mdns_resp_init(); + mdns_resp_add_netif(&net_test, "hostname", 255); + snmp_init(); if(argc > 1) { FILE* f; @@ -130,7 +181,7 @@ int main(int argc, char** argv) } else { len = fread(pktbuf, 1, sizeof(pktbuf), stdin); } - input_pkt(&net_test, pktbuf, len); + input_pkts(&net_test, pktbuf, len); return 0; } diff --git a/test/fuzz/lwipopts.h b/test/fuzz/lwipopts.h index 4aff09ba..4ab26f28 100644 --- a/test/fuzz/lwipopts.h +++ b/test/fuzz/lwipopts.h @@ -42,8 +42,14 @@ #define IPV6_FRAG_COPYHEADER 1 #define LWIP_IPV6_DUP_DETECT_ATTEMPTS 0 -/* Enable DHCP to test it */ +/* Enable some protocols to test them */ #define LWIP_DHCP 1 +#define LWIP_AUTOIP 1 + +#define LWIP_IGMP 1 +#define LWIP_DNS 1 + +#define LWIP_ALTCP 1 /* Turn off checksum verification of fuzzed data */ #define CHECKSUM_CHECK_IP 0 @@ -56,13 +62,19 @@ #define MEM_SIZE 16000 #define TCP_SND_QUEUELEN 40 #define MEMP_NUM_TCP_SEG TCP_SND_QUEUELEN +#define TCP_OVERSIZE 1 #define TCP_SND_BUF (12 * TCP_MSS) #define TCP_WND (10 * TCP_MSS) #define LWIP_WND_SCALE 1 -#define TCP_RCV_SCALE 0 +#define TCP_RCV_SCALE 2 #define PBUF_POOL_SIZE 400 /* pbuf tests need ~200KByte */ /* Minimal changes to opt.h required for etharp unit tests: */ #define ETHARP_SUPPORT_STATIC_ENTRIES 1 +#define LWIP_NUM_NETIF_CLIENT_DATA 1 +#define LWIP_SNMP 1 +#define MIB2_STATS 1 +#define LWIP_MDNS_RESPONDER 1 + #endif /* LWIP_HDR_LWIPOPTS_H__ */