-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
@@ -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 |
@@ -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 |
@@ -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. |
@@ -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); | |||
} |