Create fuzzing basis + base64 fuzzer

Signed-off-by: Guido Vranken <guidovranken@gmail.com>
This commit is contained in:
Guido Vranken 2017-06-23 14:51:55 +02:00
parent 0402c7faad
commit c48481d1bc
8 changed files with 405 additions and 11 deletions

View file

@ -364,6 +364,7 @@ esac
PKG_PROG_PKG_CONFIG
AC_PROG_CPP
AC_PROG_CXX
AC_PROG_INSTALL
AC_PROG_LN_S
AC_PROG_SED
@ -582,6 +583,11 @@ AC_COMPILE_IFELSE(
[AC_MSG_RESULT([no])]
)
CFLAGS="${CFLAGS} -DFUZZING -g3 -fsanitize-coverage=trace-pc-guard,indirect-calls,trace-cmp -fsanitize=address -fsanitize=undefined -fsanitize-recover=alignment"
CXXFLAGS="${CXXFLAGS} -DFUZZING -g3 -fsanitize-coverage=trace-pc-guard,indirect-calls,trace-cmp -fsanitize=address -fsanitize=undefined -fsanitize-recover=alignment"
CC="clang"
CXX="clang++"
saved_LDFLAGS="$LDFLAGS"
LDFLAGS="$LDFLAGS -Wl,--wrap=exit"
AC_MSG_CHECKING([linker supports --wrap])

View file

@ -35,9 +35,8 @@ if WIN32
AM_CFLAGS += -municode -UUNICODE
endif
sbin_PROGRAMS = openvpn
openvpn_SOURCES = \
lib_LTLIBRARIES = libopenvpn.la
libopenvpn_la_SOURCES = \
argv.c argv.h \
base64.c base64.h \
basic.h \
@ -120,17 +119,39 @@ openvpn_SOURCES = \
tun.c tun.h \
win32.h win32.c \
cryptoapi.h cryptoapi.c
openvpn_LDADD = \
$(top_builddir)/src/compat/libcompat.la \
libopenvpn_la_SOURCES += \
fuzzing.h fuzzing.c
extra_PROGRAMS = \
openvpn-fuzzer-base64 openvpn-fuzzer-base64-standalone
extradir = .
fuzzer_sources = dummy.cpp
fuzzer_cflags = \
$(TAP_CFLAGS) \
$(OPTIONAL_CRYPTO_CFLAGS) \
$(OPTIONAL_LZO_CFLAGS) \
$(OPTIONAL_LZ4_CFLAGS) \
$(OPTIONAL_PKCS11_HELPER_CFLAGS) \
-DPLUGIN_LIBDIR=\"${plugindir}\"
fuzzer_ldflags = -static
fuzzer_ldadd = \
$(SOCKETS_LIBS) \
$(OPTIONAL_LZO_LIBS) \
$(OPTIONAL_LZ4_LIBS) \
$(OPTIONAL_PKCS11_HELPER_LIBS) \
$(OPTIONAL_CRYPTO_LIBS) \
$(OPTIONAL_SELINUX_LIBS) \
$(OPTIONAL_SYSTEMD_LIBS) \
$(OPTIONAL_DL_LIBS)
if WIN32
openvpn_SOURCES += openvpn_win32_resources.rc block_dns.c block_dns.h
openvpn_LDADD += -lgdi32 -lws2_32 -lwininet -lcrypt32 -liphlpapi -lwinmm -lfwpuclnt -lrpcrt4
endif
$(OPTIONAL_DL_LIBS) \
libopenvpn.la \
$(top_builddir)/src/compat/libcompat.la \
$(OPTIONAL_LZO_LIBS)
openvpn_fuzzer_base64_SOURCES = $(fuzzer_sources)
openvpn_fuzzer_base64_LDFLAGS = $(fuzzer_ldflags)
openvpn_fuzzer_base64_CFLAGS = $(fuzzer_cflags)
openvpn_fuzzer_base64_LDADD = $(fuzzer_ldadd) fuzzer-base64.o libFuzzer.a
openvpn_fuzzer_base64_standalone_SOURCES = fuzzer-standalone-loader.c
openvpn_fuzzer_base64_standalone_LDFLAGS = $(fuzzer_ldflags)
openvpn_fuzzer_base64_standalone_CFLAGS = $(fuzzer_cflags)
openvpn_fuzzer_base64_standalone_LDADD = $(fuzzer_ldadd) fuzzer-base64.o

0
src/openvpn/dummy.cpp Normal file
View file

View file

@ -0,0 +1,52 @@
#include "config.h"
#include "syshead.h"
#ifdef FUZZING
#if defined(ENABLE_CRYPTO) && defined(ENABLE_CRYPTO_OPENSSL)
#elif defined(ENABLE_CRYPTO) && defined(ENABLE_CRYPTO_MBEDTLS)
#else
#error "This fuzzing target cannot be built"
#endif
#include "fuzzing.h"
#include "base64.h"
int LLVMFuzzerInitialize(int *argc, char ***argv)
{
return 1;
}
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
{
char* str = NULL;
unsigned char* outbuf;
uint16_t* outsize;
int ret;
if ( size < sizeof(*outsize) )
{
return 0;
}
outsize = (uint16_t*)data;
data += sizeof(*outsize);
size -= sizeof(*outsize);
if ( openvpn_base64_encode(data, size, &str) > 0 )
{
#ifdef MSAN
test_undefined_memory(str, strlen(str)+1);
#endif
}
free(str);
str = malloc(size+1);
memcpy(str, (char*)data, size);
str[size] = 0;
outbuf = malloc(*outsize);
if ( (ret = openvpn_base64_decode(str, outbuf, *outsize)) > 0 )
{
#ifdef MSAN
test_undefined_memory(outbuf, ret);
#endif
}
free(str);
free(outbuf);
return 0;
}
#endif /* FUZZING */

View file

@ -0,0 +1,30 @@
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <stdint.h>
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
int LLVMFuzzerInitialize(int *argc, char ***argv);
int main(int argc, char **argv) {
int n;
for (n = 1; n < argc; ++n) {
struct stat st;
FILE *f;
unsigned char *buf;
size_t s;
stat(argv[n], &st);
f = fopen(argv[n], "rb");
if (f == NULL)
continue;
buf = malloc(st.st_size);
s = fread(buf, 1, st.st_size, f);
LLVMFuzzerInitialize(NULL, NULL);
LLVMFuzzerTestOneInput(buf, s);
free(buf);
fclose(f);
}
return 0;
}

236
src/openvpn/fuzzing.c Normal file
View file

@ -0,0 +1,236 @@
#ifdef FUZZING
#ifdef HAVE_CONFIG_H
#include "config.h"
#elif defined(_MSC_VER)
#include "config-msvc.h"
#endif
#include "syshead.h"
#include "buffer.h"
#include "fuzzing.h"
static unsigned char* fuzzer_data = NULL;
static size_t fuzzer_data_size = 0;
void fuzzer_set_input(unsigned char* data, size_t size)
{
fuzzer_data = data;
fuzzer_data_size = size;
}
unsigned char* fuzzer_get_current_data(void)
{
return fuzzer_data;
}
size_t fuzzer_get_current_size(void)
{
return fuzzer_data_size;
}
static int recv_no_rnd = 0;
void fuzzer_set_recv_no_rnd(int yesno)
{
recv_no_rnd = yesno;
}
ssize_t fuzzer_get_data(void* dest, size_t size)
{
if ( size > fuzzer_data_size )
{
return -1;
}
memcpy(dest, fuzzer_data, size);
fuzzer_data += size;
fuzzer_data_size -= size;
return size;
}
ssize_t fuzzer_get_data_rnd(void* dest, size_t size)
{
size_t realsize;
unsigned int realsize_ui;
unsigned short realsize_us;
unsigned char realsize_uc;
if ( size == 0 )
{
return 0;
}
if ( size > 0x7FFFFFFF )
{
return 0;
}
if ( size > 65535 )
{
if ( fuzzer_get_data(&realsize_ui, sizeof(realsize_ui)) < 0 )
{
return -1;
}
realsize = realsize_ui;
}
else if ( size > 255 )
{
if ( fuzzer_get_data(&realsize_us, sizeof(realsize_us)) < 0 )
{
return -1;
}
realsize = realsize_us;
}
else
{
if ( fuzzer_get_data(&realsize_uc, sizeof(realsize_uc)) < 0 )
{
return -1;
}
realsize = realsize_uc;
}
realsize %= (size+1);
return fuzzer_get_data(dest, realsize);
}
ssize_t fuzzer_get_integer(size_t max)
{
size_t s;
if ( max == 0 )
{
return 0;
}
/*
if ( max > 0x7FFFFFFF )
{
return -1;
}
*/
if ( fuzzer_get_data(&s, sizeof(s)) < 0 )
{
return -1;
}
return s % (max+1);
}
static char* fuzzer_get_string_inner(size_t maxsize, struct gc_arena* gc)
{
ssize_t strsize;
char* ret;
if ( (strsize = fuzzer_get_integer(maxsize)) < 0 )
{
return NULL;
}
if ( gc == NULL )
{
ret = malloc(strsize+1);
}
else
{
ALLOC_ARRAY_GC(ret, char, strsize+1, gc);
}
if ( ret == NULL )
{
return NULL;
}
if ( fuzzer_get_data(ret, strsize) < 0 )
{
if ( gc == NULL )
{
free(ret);
}
return NULL;
}
ret[strsize] = 0;
return ret;
}
char* fuzzer_get_string(size_t maxsize)
{
return fuzzer_get_string_inner(maxsize, NULL);
}
char* fuzzer_get_string_gc(size_t maxsize, struct gc_arena* gc)
{
return fuzzer_get_string_inner(maxsize, gc);
}
ssize_t fuzzer_read(void* dest, size_t size)
{
if ( recv_no_rnd )
{
return fuzzer_get_data(dest, size);
}
else
{
return fuzzer_get_data_rnd(dest, size);
}
}
ssize_t fuzzer_recv(void* dest, size_t size)
{
if ( recv_no_rnd )
{
return fuzzer_get_data(dest, size);
}
else
{
return fuzzer_get_data_rnd(dest, size);
}
}
ssize_t fuzzer_send(size_t size)
{
/*
ssize_t r = fuzzer_get_integer(size);
if ( r < 0 )
{
return -1;
}
*/
return size;
//return r;
}
void fuzzer_alter_buffer(struct buffer* buffer)
{
ssize_t newoffset, newlen;
if ( buffer->capacity == 0 )
{
return;
}
FUZZER_GET_INTEGER(newoffset, buffer->capacity);
newlen = buffer->capacity - newoffset;
if ( newlen != 0 )
{
FUZZER_GET_INTEGER(newlen, newlen);
}
buffer->offset = newoffset;
buffer->len = newlen;
return;
cleanup:
return;
}
void test_undefined_memory(void* vp, size_t s)
{
FILE* fp = fopen("/dev/null", "wb");
unsigned char* p = (unsigned char*)vp;
fwrite(p, s, 1, fp);
fclose(fp);
}
#endif

47
src/openvpn/fuzzing.h Normal file
View file

@ -0,0 +1,47 @@
#ifdef FUZZING
#ifdef HAVE_CONFIG_H
#include "config.h"
#elif defined(_MSC_VER)
#include "config-msvc.h"
#endif
#include "syshead.h"
#include "buffer.h"
void fuzzer_set_input(unsigned char* data, size_t size);
unsigned char* fuzzer_get_current_data(void);
size_t fuzzer_get_current_size(void);
void fuzzer_set_recv_no_rnd(int yesno);
ssize_t fuzzer_get_data(void* dest, size_t size);
ssize_t fuzzer_get_data_rnd(void* dest, size_t size);
ssize_t fuzzer_get_integer(size_t max);
char* fuzzer_get_string(size_t maxsize);
char* fuzzer_get_string_gc(size_t maxsize, struct gc_arena* gc);
ssize_t fuzzer_read(void* dest, size_t size);
ssize_t fuzzer_recv(void* dest, size_t size);
ssize_t fuzzer_send(size_t size);
void fuzzer_alter_buffer(struct buffer* buffer);
void test_undefined_memory(void* vp, size_t s);
#define FUZZER_GET_DATA(dest, size) { \
if ( fuzzer_get_data((dest), (size)) < 0 ) { \
goto cleanup; \
} \
}
#define FUZZER_GET_INTEGER(dest, max) { \
(dest) = fuzzer_get_integer(max); \
if ( (dest) < 0 ) { \
goto cleanup; \
} \
}
#define FUZZER_GET_STRING(dest, max) { \
(dest) = NULL; \
if ( ((dest) = fuzzer_get_string(max)) == NULL ) { \
goto cleanup; \
} \
}
#define FUZZER_GET_STRING_GC(dest, max, gc) { \
(dest) = NULL; \
if ( ((dest) = fuzzer_get_string_gc((max), (gc))) == NULL ) { \
goto cleanup; \
} \
}
#endif

View file

@ -329,6 +329,7 @@ openvpn_main(int argc, char *argv[])
return 0; /* NOTREACHED */
}
#if 0
#ifdef _WIN32
int
wmain(int argc, wchar_t *wargv[])
@ -366,3 +367,4 @@ main(int argc, char *argv[])
return openvpn_main(argc, argv);
}
#endif /* ifdef _WIN32 */
#endif