diff --git a/.gitignore b/.gitignore index 3c71437a..23572cf3 100644 --- a/.gitignore +++ b/.gitignore @@ -30,6 +30,7 @@ Makefile /include/libtpms/tpm_library.h /m4/* /tests/base64decode +/tests/fuzz /tests/freebl_sha1flattensize /debian/*debhelper* /debian/*substvars diff --git a/README b/README index 9aacf732..ebccfe43 100644 --- a/README +++ b/README @@ -74,6 +74,22 @@ For patch submissions, please use a Signed-off-by: to indicate agreement to the DCO1.1.txt. +Fuzzing +------- +Initial fuzzing is possible with clang & libfuzzer. + +You have to configure the project with --enable-fuzzer +(--enable-sanitizer can also help spot more issues). Then you can +build fuzz and run it with the testing corpus. + +Fuzz testing is known to work with Fedora 28 or later. It requires that the +'clang' package is installed. + +Ex: +$ ./configure --with-openssl --with-tpm2 --enable-sanitizers --enable-fuzzer CC=clang +$ make && make -C tests fuzz +$ tests/fuzz tests/corpus-execute-command + Maintainers ----------- libtpms is currently being maintained by Stefan Berger . diff --git a/configure.ac b/configure.ac index e5e7e96a..af52613b 100644 --- a/configure.ac +++ b/configure.ac @@ -137,6 +137,15 @@ AC_ARG_WITH([tpm2], AM_CONDITIONAL(WITH_TPM2, false) ) +AC_ARG_ENABLE([sanitizers], AS_HELP_STRING([--enable-sanitizers], [Enable address sanitizing]), + [SANITIZERS="-fsanitize=address,undefined"], []) +AC_ARG_ENABLE([fuzzer], AS_HELP_STRING([--enable-fuzzer], [Enable fuzzer]), + [FUZZER="$SANITIZERS -fsanitize=fuzzer" + AM_CONDITIONAL(WITH_FUZZER, true)], + [AM_CONDITIONAL(WITH_FUZZER, false)]) +AC_SUBST([SANITIZERS]) +AC_SUBST([FUZZER]) + LT_INIT AC_PROG_CC AC_PROG_INSTALL diff --git a/src/Makefile.am b/src/Makefile.am index 7bf662be..f3683b1c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -8,9 +8,12 @@ lib_LTLIBRARIES=libtpms.la common_CFLAGS = -include tpm_library_conf.h \ -I$(top_srcdir)/include/libtpms \ - $(HARDENING_CFLAGS) + $(HARDENING_CFLAGS) \ + $(SANITIZERS) \ + $(FUZZER) -LDFLAGS = $(HARDENING_LDFLAGS) + +LDFLAGS = $(HARDENING_LDFLAGS) $(SANITIZERS) $(FUZZER) # # TPM1.2 diff --git a/tests/Makefile.am b/tests/Makefile.am index cf194c7c..c8a498d9 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -4,11 +4,17 @@ # For the license, see the LICENSE file in the root directory. # +AM_CFLAGS = -I../include $(SANITIZERS) +AM_LDFLAGS = -ltpms -L../src/.libs $(SANITIZERS) + check_PROGRAMS = base64decode TESTS = base64decode.sh -base64decode_CFLAGS = -I../include -base64decode_LDFLAGS = -ltpms -L../src/.libs +if WITH_FUZZER +check_PROGRAMS += fuzz +fuzz_CFLAGS = -fsanitize=fuzzer $(AM_CFLAGS) +fuzz_LDFLAGS = -fsanitize=fuzzer $(AM_LDFLAGS) +endif if LIBTPMS_USE_FREEBL diff --git a/tests/fuzz.c b/tests/fuzz.c new file mode 100644 index 00000000..c2f9242b --- /dev/null +++ b/tests/fuzz.c @@ -0,0 +1,38 @@ +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) +{ + unsigned char *rbuffer = NULL; + uint32_t rlength; + uint32_t rtotal = 0; + TPM_RESULT res; + unsigned char startup[] = { + 0x80, 0x01, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x01, 0x44, 0x00, 0x00 + }; + + res = TPMLIB_ChooseTPMVersion(TPMLIB_TPM_VERSION_2); + assert(res == TPM_SUCCESS); + + res = TPMLIB_MainInit(); + assert(res == TPM_SUCCESS); + + res = TPMLIB_Process(&rbuffer, &rlength, &rtotal, startup, sizeof(startup)); + assert(res == TPM_SUCCESS); + + res = TPMLIB_Process(&rbuffer, &rlength, &rtotal, (unsigned char*)data, size); + assert(res == TPM_SUCCESS); + + TPMLIB_Terminate(); + TPM_Free(rbuffer); + + return 0; +}