test/fuzz: add some applications, add an experimental multi-packet mode

The experimental multi-packet mode splits input bytes depending on a length
decoded from the first 2 bytes and does that until the end of input.
To use this mode, compile with "make D=-DLWIP_FUZZ_MULTI_PACKET"

Signed-off-by: goldsimon <goldsimon@gmx.de>
This commit is contained in:
goldsimon 2018-02-15 14:35:08 +01:00
parent cd1516e2e4
commit 58de2af5f2
4 changed files with 76 additions and 9 deletions

View File

@ -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)

View File

@ -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/<INPUT> -o output ./lwip_fuzz

View File

@ -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 <string.h>
#include <stdio.h>
/* 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;
}

View File

@ -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__ */