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.
This commit is contained in:
Samuel Thibault
2023-03-30 02:31:03 +02:00
parent ff46761d6a
commit eabe24901f
4 changed files with 37 additions and 24 deletions
+4 -3
View File
@@ -16,6 +16,7 @@ jobs:
include: include:
- arch: x86-32 - arch: x86-32
archdeps: "gcc-multilib g++-multilib libpcaudio-dev:i386 libsonic-dev:i386 libc6-dbg:i386" archdeps: "gcc-multilib g++-multilib libpcaudio-dev:i386 libsonic-dev:i386 libc6-dbg:i386"
archconfig: "--host=i686-linux-gnu"
archconfigflags: "-m32" archconfigflags: "-m32"
- arch: x86-64 - arch: x86-64
@@ -31,11 +32,11 @@ jobs:
- name: autoconf - name: autoconf
run: ./autogen.sh ; chmod -x INSTALL m4/*.m4 run: ./autogen.sh ; chmod -x INSTALL m4/*.m4
- name: configure - name: configure
run: CC=clang CXX=clang++ run: CC="clang ${{ matrix.archconfigflags }}" CXX="clang++ ${{ matrix.archconfigflags }}"
CFLAGS="${{ matrix.archconfigflags }} -fsanitize=address,undefined -fstack-protector-strong -g -Og -fno-omit-frame-pointer" 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" CXXFLAGS="${{ matrix.archconfigflags }} -fsanitize=address,undefined -fstack-protector-strong -g -Og -fno-omit-frame-pointer"
LDFLAGS="-fsanitize=address,undefined -lubsan" LDFLAGS="-fsanitize=address,undefined -lubsan"
./configure --with-libfuzzer ./configure ${{ matrix.archconfig }} --with-libfuzzer
- name: Store the fuzzer config - name: Store the fuzzer config
if: ${{ failure() }} if: ${{ failure() }}
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v3
+4 -7
View File
@@ -262,7 +262,7 @@ man1_MANS += src/speak-ng.1
endif endif
src_speak_ng_LDADD = src/libespeak-ng.la 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} src_speak_ng_CFLAGS = -Isrc/libespeak-ng ${AM_CFLAGS}
bin_PROGRAMS += src/espeak-ng bin_PROGRAMS += src/espeak-ng
@@ -271,7 +271,7 @@ if HAVE_RONN
man1_MANS += src/espeak-ng.1 man1_MANS += src/espeak-ng.1
endif 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 src_espeak_ng_SOURCES = src/espeak-ng.c
if HAVE_LIBFUZZER if HAVE_LIBFUZZER
nodist_EXTRA_src_espeak_ng_SOURCES = force-cxx-linking.cxx nodist_EXTRA_src_espeak_ng_SOURCES = force-cxx-linking.cxx
@@ -354,14 +354,11 @@ endif
if HAVE_LIBFUZZER if HAVE_LIBFUZZER
tests_ssml_fuzzer_test_CFLAGS += -fsanitize=fuzzer
tests_ssml_fuzzer_test_LDFLAGS = -fsanitize=fuzzer
noinst_PROGRAMS = tests/fuzzing/synth_fuzzer.test noinst_PROGRAMS = tests/fuzzing/synth_fuzzer.test
tests_fuzzing_synth_fuzzer_test_SOURCES = tests/fuzzing/synth_fuzzer.c 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_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_CFLAGS= ${AM_CFLAGS} -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_LDFLAGS= ${AM_LDFLAGS} -static -lm -Wl,-z,relro ${PCAUDIOLIB_LIBS} ${LIBFUZZER_NO_MAIN}
else else
tests_ssml_fuzzer_test_LDADD += tests/libfuzzrunner.la tests_ssml_fuzzer_test_LDADD += tests/libfuzzrunner.la
endif endif
+22 -11
View File
@@ -136,17 +136,28 @@ else
fi fi
AC_LANG_PUSH(C) if test "$with_libfuzzer" = yes ; then
TEMP_CFLAGS="$CFLAGS" AC_LANG_PUSH(C)
CFLAGS="$CFLAGS -fsanitize=fuzzer" TEMP_CFLAGS="$CFLAGS"
AC_MSG_CHECKING([if $CC supports fuzzer with the -fsanitize=fuzzer flag]) TEMP_LIBS="$LIBS"
AC_COMPILE_IFELSE( HOST_CPU="`$CC -print-multiarch | sed -e 's/-.*//'`"
[AC_LANG_PROGRAM( [[]], [[]])], LIBFUZZER_NO_MAIN="`$CC -print-runtime-dir`/libclang_rt.fuzzer_no_main-$HOST_CPU.a -lstdc++ -lm"
[have_fuzzer_fuzzer=yes], CFLAGS="$CFLAGS -fsanitize=fuzzer-no-link"
[have_fuzzer_fuzzer=no]) LIBS="$LIBS $LIBFUZZER_NO_MAIN"
AC_MSG_RESULT($have_fuzzer_fuzzer) AC_MSG_CHECKING([if $CC supports fuzzer with the -fsanitize=fuzzer flag])
CFLAGS="$TEMP_CFLAGS" AC_COMPILE_IFELSE(
AC_LANG_POP(C) [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 ================================================================
dnl FreeBSD check. dnl FreeBSD check.
+7 -3
View File
@@ -40,10 +40,10 @@ espeak_callback(short *data, int samples, espeak_EVENT *events)
} }
/* See http://llvm.org/docs/LibFuzzer.html */ /* See http://llvm.org/docs/LibFuzzer.html */
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));
extern int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
{ {
int buflength = size+1; int buflength = size+1;
if (!initialized) if (!initialized)
@@ -78,3 +78,7 @@ extern int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
return 0; return 0;
} }
int main(int argc, char *argv[]) {
LLVMFuzzerRunDriver(&argc, &argv, LLVMFuzzerTestOneInput);
}