PKG_PROG_PKG_CONFIG
AC_PROG_CPP
+AC_PROG_CXX
AC_PROG_INSTALL
AC_PROG_LN_S
AC_PROG_SED
[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])
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 \
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
--- /dev/null
+#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 */
--- /dev/null
+#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;
+}
--- /dev/null
+#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
--- /dev/null
+#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
return 0; /* NOTREACHED */
}
+#if 0
#ifdef _WIN32
int
wmain(int argc, wchar_t *wargv[])
return openvpn_main(argc, argv);
}
#endif /* ifdef _WIN32 */
+#endif