Browse Source

Fuzzing: compile the whole libespeak with -fsanitize=fuzzer-no-link

-fsanitize=fuzzer-no-link makes it workable to build a library with fuzzing
enabled, and let the fuzzing test program explicitly trigger the fuzzing.

This allows fuzzing to trace cmp instructions to guide the fuzzing to
improve results.
master
Samuel Thibault 2 years ago
parent
commit
eabe24901f
4 changed files with 37 additions and 24 deletions
  1. 4
    3
      .github/workflows/fuzzing.yml
  2. 4
    7
      Makefile.am
  3. 22
    11
      configure.ac
  4. 7
    3
      tests/fuzzing/synth_fuzzer.c

+ 4
- 3
.github/workflows/fuzzing.yml View File

@@ -16,6 +16,7 @@ jobs:
include:
- arch: x86-32
archdeps: "gcc-multilib g++-multilib libpcaudio-dev:i386 libsonic-dev:i386 libc6-dbg:i386"
archconfig: "--host=i686-linux-gnu"
archconfigflags: "-m32"

- arch: x86-64
@@ -31,11 +32,11 @@ jobs:
- name: autoconf
run: ./autogen.sh ; chmod -x INSTALL m4/*.m4
- name: configure
run: CC=clang CXX=clang++
CFLAGS="${{ matrix.archconfigflags }} -fsanitize=address,undefined -fstack-protector-strong -g -Og -fno-omit-frame-pointer"
run: CC="clang ${{ matrix.archconfigflags }}" CXX="clang++ ${{ matrix.archconfigflags }}"
CFLAGS="-fsanitize=address,undefined -fstack-protector-strong -g -Og -fno-omit-frame-pointer"
CXXFLAGS="${{ matrix.archconfigflags }} -fsanitize=address,undefined -fstack-protector-strong -g -Og -fno-omit-frame-pointer"
LDFLAGS="-fsanitize=address,undefined -lubsan"
./configure --with-libfuzzer
./configure ${{ matrix.archconfig }} --with-libfuzzer
- name: Store the fuzzer config
if: ${{ failure() }}
uses: actions/upload-artifact@v3

+ 4
- 7
Makefile.am View File

@@ -262,7 +262,7 @@ man1_MANS += src/speak-ng.1
endif

src_speak_ng_LDADD = src/libespeak-ng.la
src_speak_ng_LDFLAGS = -static -lm ${PCAUDIOLIB_LIBS}
src_speak_ng_LDFLAGS = -static -lm ${PCAUDIOLIB_LIBS} ${LIBFUZZER_NO_MAIN}
src_speak_ng_CFLAGS = -Isrc/libespeak-ng ${AM_CFLAGS}

bin_PROGRAMS += src/espeak-ng
@@ -271,7 +271,7 @@ if HAVE_RONN
man1_MANS += src/espeak-ng.1
endif

src_espeak_ng_LDADD = src/libespeak-ng.la ${PCAUDIOLIB_LIBS}
src_espeak_ng_LDADD = src/libespeak-ng.la ${PCAUDIOLIB_LIBS} ${LIBFUZZER_NO_MAIN}
src_espeak_ng_SOURCES = src/espeak-ng.c
if HAVE_LIBFUZZER
nodist_EXTRA_src_espeak_ng_SOURCES = force-cxx-linking.cxx
@@ -354,14 +354,11 @@ endif


if HAVE_LIBFUZZER
tests_ssml_fuzzer_test_CFLAGS += -fsanitize=fuzzer
tests_ssml_fuzzer_test_LDFLAGS = -fsanitize=fuzzer

noinst_PROGRAMS = tests/fuzzing/synth_fuzzer.test
tests_fuzzing_synth_fuzzer_test_SOURCES = tests/fuzzing/synth_fuzzer.c
tests_fuzzing_synth_fuzzer_test_LDADD = src/libespeak-ng.la
tests_fuzzing_synth_fuzzer_test_CFLAGS= ${AM_CFLAGS} -fsanitize=fuzzer -DPATH_ESPEAK_DATA=\"$(abs_top_srcdir)/espeak-ng-data\" -Isrc/libespeak-ng
tests_fuzzing_synth_fuzzer_test_LDFLAGS= ${AM_LDFLAGS} -fsanitize=fuzzer -static -lm -Wl,-z,relro ${PCAUDIOLIB_LIBS}
tests_fuzzing_synth_fuzzer_test_CFLAGS= ${AM_CFLAGS} -DPATH_ESPEAK_DATA=\"$(abs_top_srcdir)/espeak-ng-data\" -Isrc/libespeak-ng
tests_fuzzing_synth_fuzzer_test_LDFLAGS= ${AM_LDFLAGS} -static -lm -Wl,-z,relro ${PCAUDIOLIB_LIBS} ${LIBFUZZER_NO_MAIN}
else
tests_ssml_fuzzer_test_LDADD += tests/libfuzzrunner.la
endif

+ 22
- 11
configure.ac View File

@@ -136,17 +136,28 @@ else
fi


AC_LANG_PUSH(C)
TEMP_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -fsanitize=fuzzer"
AC_MSG_CHECKING([if $CC supports fuzzer with the -fsanitize=fuzzer flag])
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM( [[]], [[]])],
[have_fuzzer_fuzzer=yes],
[have_fuzzer_fuzzer=no])
AC_MSG_RESULT($have_fuzzer_fuzzer)
CFLAGS="$TEMP_CFLAGS"
AC_LANG_POP(C)
if test "$with_libfuzzer" = yes ; then
AC_LANG_PUSH(C)
TEMP_CFLAGS="$CFLAGS"
TEMP_LIBS="$LIBS"
HOST_CPU="`$CC -print-multiarch | sed -e 's/-.*//'`"
LIBFUZZER_NO_MAIN="`$CC -print-runtime-dir`/libclang_rt.fuzzer_no_main-$HOST_CPU.a -lstdc++ -lm"
CFLAGS="$CFLAGS -fsanitize=fuzzer-no-link"
LIBS="$LIBS $LIBFUZZER_NO_MAIN"
AC_MSG_CHECKING([if $CC supports fuzzer with the -fsanitize=fuzzer flag])
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM( [[]], [[]])],
[have_fuzzer_fuzzer=yes],
[have_fuzzer_fuzzer=no])
AC_MSG_RESULT($have_fuzzer_fuzzer)
if test "$have_fuzzer_fuzzer" != yes ; then
CFLAGS="$TEMP_CFLAGS"
LIBFUZZER_NO_MAIN=""
fi
AC_SUBST(LIBFUZZER_NO_MAIN)
LIBS="$TEMP_LIBS"
AC_LANG_POP(C)
fi

dnl ================================================================
dnl FreeBSD check.

+ 7
- 3
tests/fuzzing/synth_fuzzer.c View File

@@ -40,10 +40,10 @@ espeak_callback(short *data, int samples, espeak_EVENT *events)
}

/* See http://llvm.org/docs/LibFuzzer.html */
extern int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);

extern int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
extern int LLVMFuzzerRunDriver(int *argc, char ***argv,
int (*UserCb)(const uint8_t *Data, size_t Size));

int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
{
int buflength = size+1;
if (!initialized)
@@ -78,3 +78,7 @@ extern int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)

return 0;
}

int main(int argc, char *argv[]) {
LLVMFuzzerRunDriver(&argc, &argv, LLVMFuzzerTestOneInput);
}

Loading…
Cancel
Save