Add fuzzing architecture
This commit is contained in:
parent
fa2985a535
commit
f41c6aaf63
26
Makefile.am
26
Makefile.am
|
@ -1,6 +1,6 @@
|
||||||
# got some hints from https://gitorious.org/openismus-playground/examplelib/source
|
# got some hints from https://gitorious.org/openismus-playground/examplelib/source
|
||||||
|
|
||||||
SUBDIRS = po include src tools $(LIBPSL_DOCS) tests
|
SUBDIRS = po include src tools $(LIBPSL_DOCS) fuzz tests
|
||||||
|
|
||||||
ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
|
ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
|
||||||
|
|
||||||
|
@ -23,17 +23,20 @@ dist-hook:
|
||||||
clean-local:
|
clean-local:
|
||||||
rm -rf */*.gc?? */*/*.gc?? libpsl.info lcov
|
rm -rf */*.gc?? */*/*.gc?? libpsl.info lcov
|
||||||
|
|
||||||
check-coverage:
|
LCOV_INFO=libpsl.info
|
||||||
|
check-coverage: clean
|
||||||
if test -z "$(XLIB)"; then \
|
if test -z "$(XLIB)"; then \
|
||||||
CFLAGS=$$CFLAGS" --coverage -O0" LDFLAGS=$$LDFLAGS" --coverage" ./configure --disable-runtime --disable-builtin; \
|
CFLAGS=$$CFLAGS" --coverage -O0" LDFLAGS=$$LDFLAGS" --coverage" ./configure --disable-runtime --disable-builtin; \
|
||||||
else \
|
else \
|
||||||
CFLAGS=$$CFLAGS" --coverage -O0" LDFLAGS=$$LDFLAGS" --coverage" ./configure --enable-runtime=$(XLIB) --enable-builtin=$(XLIB); \
|
CFLAGS=$$CFLAGS" --coverage -O0" LDFLAGS=$$LDFLAGS" --coverage" ./configure --enable-runtime=$(XLIB) --enable-builtin=$(XLIB); \
|
||||||
fi
|
fi
|
||||||
$(MAKE) clean && $(MAKE)
|
$(MAKE)
|
||||||
lcov --capture --initial --directory src --output-file libpsl.info
|
lcov --capture --initial --directory src --output-file $(LCOV_INFO)
|
||||||
$(MAKE) check
|
$(MAKE) check
|
||||||
lcov --capture --directory src --output-file libpsl.info
|
lcov --capture --directory src --output-file $(LCOV_INFO)
|
||||||
genhtml --prefix . libpsl.info --legend --title "libpsl" --output-directory=lcov
|
genhtml --prefix . $(LCOV_INFO) --legend --title "libpsl" --output-directory=lcov
|
||||||
|
@echo
|
||||||
|
@echo "You can now view the coverage report with 'xdg-open lcov/index.html'"
|
||||||
|
|
||||||
check-coverage-libidn:
|
check-coverage-libidn:
|
||||||
XLIB=libidn $(MAKE) check-coverage
|
XLIB=libidn $(MAKE) check-coverage
|
||||||
|
@ -43,3 +46,14 @@ check-coverage-libidn2:
|
||||||
|
|
||||||
check-coverage-libicu:
|
check-coverage-libicu:
|
||||||
XLIB=libicu $(MAKE) check-coverage
|
XLIB=libicu $(MAKE) check-coverage
|
||||||
|
|
||||||
|
fuzz-coverage: clean
|
||||||
|
$(MAKE) -C src CFLAGS="$(CFLAGS) --coverage" LDFLAGS="$(LDFLAGS) --coverage"
|
||||||
|
$(MAKE) -C fuzz fuzz-coverage CFLAGS="$(CFLAGS) --coverage" LDFLAGS="$(LDFLAGS) --coverage"
|
||||||
|
lcov --capture --initial --directory src --directory fuzz --output-file $(LCOV_INFO)
|
||||||
|
lcov --capture --directory src --directory fuzz --output-file $(LCOV_INFO)
|
||||||
|
# lcov --remove $(LCOV_INFO) '*/test_linking.c' '*/css_tokenizer.lex' '*/<stdout>' -o $(LCOV_INFO)
|
||||||
|
genhtml --prefix . --ignore-errors source $(LCOV_INFO) --legend --title "libpsl-fuzz" --output-directory=lcov
|
||||||
|
@echo
|
||||||
|
@echo "You can now view the coverage report with 'xdg-open lcov/index.html'"
|
||||||
|
|
||||||
|
|
|
@ -273,6 +273,7 @@ AC_CONFIG_FILES([Makefile
|
||||||
src/Makefile
|
src/Makefile
|
||||||
tools/Makefile
|
tools/Makefile
|
||||||
po/Makefile.in
|
po/Makefile.in
|
||||||
|
fuzz/Makefile
|
||||||
tests/Makefile
|
tests/Makefile
|
||||||
libpsl.pc:libpsl.pc.in])
|
libpsl.pc:libpsl.pc.in])
|
||||||
AC_OUTPUT
|
AC_OUTPUT
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
AM_CFLAGS = $(WERROR_CFLAGS) $(WARN_CFLAGS) -Wno-unused-parameter
|
||||||
|
AM_CPPFLAGS = -I$(top_srcdir)/include -I$(srcdir) -DSRCDIR=\"$(abs_srcdir)\" -DTEST_RUN
|
||||||
|
AM_LDFLAGS = -static
|
||||||
|
LDADD = ../src/libpsl.la
|
||||||
|
|
||||||
|
PSL_TESTS = \
|
||||||
|
libpsl_fuzzer$(EXEEXT) \
|
||||||
|
libpsl_load_dafsa_fuzzer$(EXEEXT)
|
||||||
|
|
||||||
|
check_PROGRAMS = $(PSL_TESTS)
|
||||||
|
|
||||||
|
libpsl_fuzzer_SOURCES = libpsl_fuzzer.c main.c fuzzer.h
|
||||||
|
libpsl_load_dafsa_fuzzer_SOURCES = libpsl_load_dafsa_fuzzer.c main.c fuzzer.h
|
||||||
|
|
||||||
|
dist-hook:
|
||||||
|
find . -name '*.options' -exec cp -v '{}' $(distdir) ';'
|
||||||
|
find . -name '*.dict' -exec cp -v '{}' $(distdir) ';'
|
||||||
|
find . -name '*.in' -exec cp -vr '{}' $(distdir) ';'
|
||||||
|
find . -name '*.repro' -exec cp -vr '{}' $(distdir) ';'
|
||||||
|
|
||||||
|
TESTS_ENVIRONMENT = TESTS_VALGRIND="@VALGRIND_ENVIRONMENT@"
|
||||||
|
TESTS = $(PSL_TESTS)
|
||||||
|
|
||||||
|
clean-local:
|
||||||
|
rm -rf *.gc?? *.log lcov coverage.info
|
||||||
|
|
||||||
|
fuzz-coverage: $(PSL_TESTS)
|
||||||
|
find . -name '*_fuzzer' -exec ./coverage.sh '{}' ';'
|
||||||
|
|
||||||
|
oss-fuzz:
|
||||||
|
if test "$$OUT" != ""; then \
|
||||||
|
for ccfile in *_fuzzer.c; do \
|
||||||
|
fuzzer=$$(basename $$ccfile .c); \
|
||||||
|
$$CXX $$CXXFLAGS -I$(top_srcdir)/include -I$(top_srcdir) \
|
||||||
|
"$${fuzzer}.c" -o "$${fuzzer}" \
|
||||||
|
../src/.libs/libpsl.a $${LIB_FUZZING_ENGINE} -Wl,-Bstatic \
|
||||||
|
-lidn2 -lunistring \
|
||||||
|
-Wl,-Bdynamic; \
|
||||||
|
done; \
|
||||||
|
fi
|
||||||
|
|
||||||
|
.PHONY: oss-fuzz
|
|
@ -0,0 +1,63 @@
|
||||||
|
# Fuzzers
|
||||||
|
|
||||||
|
These are fuzzers designed for use with `libFuzzer` or `afl`. They can
|
||||||
|
be used to run on Google's OSS-Fuzz (https://github.com/google/oss-fuzz/).
|
||||||
|
|
||||||
|
The convention used here is that the initial values for each parser fuzzer
|
||||||
|
are taken from the $NAME.in directory.
|
||||||
|
|
||||||
|
Crash reproducers from OSS-Fuzz are put into $NAME.repro directory for
|
||||||
|
regression testing with top dir 'make check' or 'make check-valgrind'.
|
||||||
|
|
||||||
|
|
||||||
|
# Running a fuzzer using clang
|
||||||
|
|
||||||
|
Use the following commands on top dir:
|
||||||
|
```
|
||||||
|
export CC=clang-5.0
|
||||||
|
export CXX=clang++-5.0
|
||||||
|
export CFLAGS="-O1 -fno-omit-frame-pointer -gline-tables-only -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -fsanitize=address -fsanitize-address-use-after-scope -fsanitize-coverage=trace-pc-guard,trace-cmp"
|
||||||
|
export CXXFLAGS="-O1 -fno-omit-frame-pointer -gline-tables-only -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -fsanitize=address -fsanitize-address-use-after-scope -fsanitize-coverage=trace-pc-guard,trace-cmp -stdlib=libc++"
|
||||||
|
./configure --enable-static --disable-gtk-doc
|
||||||
|
make clean
|
||||||
|
make -j$(nproc)
|
||||||
|
cd fuzz
|
||||||
|
|
||||||
|
# build and run libpsl_fuzzer
|
||||||
|
./run-clang.sh libpsl_fuzzer
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
# Running a fuzzer using AFL
|
||||||
|
|
||||||
|
Use the following commands on top dir:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ CC=afl-clang-fast ./configure --disable-gtk-doc
|
||||||
|
$ make -j$(nproc) clean all
|
||||||
|
$ cd fuzz
|
||||||
|
$ ./run-afl.sh libpsl_fuzzer
|
||||||
|
```
|
||||||
|
|
||||||
|
# Fuzz code coverage using the corpus directories *.in/
|
||||||
|
|
||||||
|
Code coverage reports currently work best with gcc+lcov+genhtml.
|
||||||
|
|
||||||
|
In the top directory:
|
||||||
|
```
|
||||||
|
CC=gcc CFLAGS="-O0 -g" ./configure --disable-gtk-doc
|
||||||
|
make fuzz-coverage
|
||||||
|
xdg-open lcov/index.html
|
||||||
|
```
|
||||||
|
|
||||||
|
Each fuzzer target has it's own functions to cover, e.g.
|
||||||
|
`libpsl_fuzzer` covers psl_is_public_suffix.
|
||||||
|
|
||||||
|
To work on corpora for better coverage, `cd fuzz` and use e.g.
|
||||||
|
`./view-coverage.sh libpsl_fuzzer`.
|
||||||
|
|
||||||
|
|
||||||
|
# Enhancing the testsuite for issues found
|
||||||
|
|
||||||
|
Each reproducer file should be dropped into the appropriate *.repro/
|
||||||
|
directory.
|
|
@ -0,0 +1,5 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
for f in $1.in/*; do
|
||||||
|
$1 < $f >/dev/null
|
||||||
|
done
|
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* Copyright(c) 2017 Tim Ruehsen
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of this software and associated documentation files (the "Software"),
|
||||||
|
* to deal in the Software without restriction, including without limitation
|
||||||
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
* and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
* Software is furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* This file is part of libpsl.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stddef.h> // size_t
|
||||||
|
#include <stdint.h> // uint8_t
|
||||||
|
|
||||||
|
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
|
|
@ -0,0 +1,56 @@
|
||||||
|
/*
|
||||||
|
* Copyright(c) 2017 Tim Ruehsen
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of this software and associated documentation files (the "Software"),
|
||||||
|
* to deal in the Software without restriction, including without limitation
|
||||||
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
* and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
* Software is furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* This file is part of libpsl.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#include <assert.h> // assert
|
||||||
|
#include <stdint.h> // uint8_t
|
||||||
|
#include <stdlib.h> // malloc, free
|
||||||
|
#include <string.h> // memcpy
|
||||||
|
|
||||||
|
#include "libpsl.h"
|
||||||
|
#include "fuzzer.h"
|
||||||
|
|
||||||
|
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||||
|
{
|
||||||
|
char *domain = (char *) malloc(size + 1);
|
||||||
|
|
||||||
|
assert(domain != NULL);
|
||||||
|
|
||||||
|
// 0 terminate
|
||||||
|
memcpy(domain, data, size);
|
||||||
|
domain[size] = 0;
|
||||||
|
|
||||||
|
psl_ctx_t *psl;
|
||||||
|
psl = (psl_ctx_t *) psl_builtin();
|
||||||
|
psl_is_public_suffix(NULL, domain);
|
||||||
|
psl_is_public_suffix(psl, domain);
|
||||||
|
psl_is_public_suffix2(psl, domain, PSL_TYPE_PRIVATE);
|
||||||
|
psl_is_public_suffix2(psl, domain, PSL_TYPE_ICANN);
|
||||||
|
psl_free(psl);
|
||||||
|
|
||||||
|
free(domain);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
x.com
|
|
@ -0,0 +1 @@
|
||||||
|
.äöü.de
|
|
@ -0,0 +1 @@
|
||||||
|
x
|
|
@ -0,0 +1,59 @@
|
||||||
|
/*
|
||||||
|
* Copyright(c) 2017 Tim Ruehsen
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of this software and associated documentation files (the "Software"),
|
||||||
|
* to deal in the Software without restriction, including without limitation
|
||||||
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
* and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
* Software is furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* This file is part of libpsl.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#include <assert.h> // assert
|
||||||
|
#include <stdint.h> // uint8_t
|
||||||
|
#include <stdlib.h> // malloc, free
|
||||||
|
#include <string.h> // memcpy
|
||||||
|
|
||||||
|
#include "libpsl.h"
|
||||||
|
#include "fuzzer.h"
|
||||||
|
|
||||||
|
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||||
|
{
|
||||||
|
char *in = (char *) malloc(size + 16);
|
||||||
|
|
||||||
|
assert(in != NULL);
|
||||||
|
|
||||||
|
// create a valid DAFSA input file
|
||||||
|
memcpy(in, ".DAFSA@PSL_0 \n", 16);
|
||||||
|
memcpy(in + 16, data, size);
|
||||||
|
|
||||||
|
FILE *fp = fmemopen(in, size + 16, "r");
|
||||||
|
assert(fp != NULL);
|
||||||
|
|
||||||
|
psl_ctx_t *psl;
|
||||||
|
psl = psl_load_fp(fp);
|
||||||
|
|
||||||
|
psl_is_public_suffix(NULL, NULL);
|
||||||
|
psl_is_public_suffix(psl, ".ü.com");
|
||||||
|
psl_free(psl);
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
free(in);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
aguchéÀDò„uzzo.iôÀ´o.ðºkhazia.sõÀ–éƒrá™ko.chiâ‰eno.osaká<6B>ashiri.hokkaido.jðÀy.cáÀtáƒrborte.î…a.prïÀ`® ÀNóƒsìˆåÀRprod.fastly.neô²¹¼¸º·¸¶¶µ´´°õŸ³«utilitie󒲞000.hõ›±”kapp.comˆ°ˆemm.comŠ.bg„
|
|
@ -0,0 +1,144 @@
|
||||||
|
/*
|
||||||
|
* Copyright(c) 2017 Tim Ruehsen
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of this software and associated documentation files (the "Software"),
|
||||||
|
* to deal in the Software without restriction, including without limitation
|
||||||
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
* and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
* Software is furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* This file is part of libpsl.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "../config.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#include "fuzzer.h"
|
||||||
|
|
||||||
|
#ifdef TEST_RUN
|
||||||
|
|
||||||
|
#include <dirent.h>
|
||||||
|
|
||||||
|
static void test_all_from(const char *dirname)
|
||||||
|
{
|
||||||
|
DIR *dirp;
|
||||||
|
struct dirent *dp;
|
||||||
|
|
||||||
|
if ((dirp = opendir(dirname))) {
|
||||||
|
while ((dp = readdir(dirp))) {
|
||||||
|
if (*dp->d_name == '.') continue;
|
||||||
|
|
||||||
|
char fname[strlen(dirname) + strlen(dp->d_name) + 2];
|
||||||
|
snprintf(fname, sizeof(fname), "%s/%s", dirname, dp->d_name);
|
||||||
|
|
||||||
|
int fd;
|
||||||
|
if ((fd = open(fname, O_RDONLY)) == -1) {
|
||||||
|
fprintf(stderr, "Failed to open %s (%d)\n", fname, errno);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct stat st;
|
||||||
|
if (fstat(fd, &st) != 0) {
|
||||||
|
fprintf(stderr, "Failed to stat %d (%d)\n", fd, errno);
|
||||||
|
close(fd);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t *data = malloc(st.st_size);
|
||||||
|
ssize_t n;
|
||||||
|
if ((n = read(fd, data, st.st_size)) == st.st_size) {
|
||||||
|
printf("testing %zu bytes from '%s'\n", st.st_size, fname);
|
||||||
|
LLVMFuzzerTestOneInput(data, st.st_size);
|
||||||
|
} else
|
||||||
|
fprintf(stderr, "Failed to read %zu bytes from %s (%d), got %zd\n", st.st_size, fname, errno, n);
|
||||||
|
|
||||||
|
free(data);
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
closedir(dirp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
/* if VALGRIND testing is enabled, we have to call ourselves with valgrind checking */
|
||||||
|
if (argc == 1) {
|
||||||
|
const char *valgrind = getenv("TESTS_VALGRIND");
|
||||||
|
|
||||||
|
if (valgrind && *valgrind) {
|
||||||
|
size_t cmdsize = strlen(valgrind) + strlen(argv[0]) + 32;
|
||||||
|
char *cmd = alloca(cmdsize);
|
||||||
|
|
||||||
|
snprintf(cmd, cmdsize, "TESTS_VALGRIND="" %s %s", valgrind, argv[0]);
|
||||||
|
return system(cmd) != 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *target = strrchr(argv[0], '/');
|
||||||
|
target = target ? target + 1 : argv[0];
|
||||||
|
|
||||||
|
char corporadir[sizeof(SRCDIR) + 1 + strlen(target) + 8];
|
||||||
|
snprintf(corporadir, sizeof(corporadir), SRCDIR "/%s.in", target);
|
||||||
|
|
||||||
|
test_all_from(corporadir);
|
||||||
|
|
||||||
|
snprintf(corporadir, sizeof(corporadir), SRCDIR "/%s.repro", target);
|
||||||
|
|
||||||
|
test_all_from(corporadir);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#ifndef __AFL_LOOP
|
||||||
|
static int __AFL_LOOP(int n)
|
||||||
|
{
|
||||||
|
static int first = 1;
|
||||||
|
|
||||||
|
if (first) {
|
||||||
|
first = 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
unsigned char buf[64 * 1024];
|
||||||
|
|
||||||
|
while (__AFL_LOOP(10000)) { // only works with afl-clang-fast
|
||||||
|
ret = fread(buf, 1, sizeof(buf), stdin);
|
||||||
|
if (ret < 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
LLVMFuzzerTestOneInput(buf, ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* TEST_RUN */
|
|
@ -0,0 +1,67 @@
|
||||||
|
#!/bin/sh -eu
|
||||||
|
#
|
||||||
|
# Copyright(c) 2017 Tim Ruehsen
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
# copy of this software and associated documentation files (the "Software"),
|
||||||
|
# to deal in the Software without restriction, including without limitation
|
||||||
|
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
# and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
# Software is furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
# DEALINGS IN THE SOFTWARE.
|
||||||
|
#
|
||||||
|
# This file is part of libpsl.
|
||||||
|
|
||||||
|
srcdir="${srcdir:-.}"
|
||||||
|
export LD_LIBRARY_PATH=${srcdir}/../lib/.libs/
|
||||||
|
|
||||||
|
cat ${srcdir}/../config.log|grep afl-clang-fast >/dev/null 2>&1
|
||||||
|
if test $? != 0; then
|
||||||
|
echo "compile first library as:"
|
||||||
|
echo "CC=afl-clang-fast ./configure"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test -z "$1"; then
|
||||||
|
echo "Usage: $0 test-case"
|
||||||
|
echo "Example: $0 libpsl_fuzzer"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
rm -f $1
|
||||||
|
CFLAGS="-g -O2" CC=afl-clang-fast make "$1" || exit 1
|
||||||
|
|
||||||
|
### minimize test corpora
|
||||||
|
if test -d ${fuzzer}.in; then
|
||||||
|
mkdir -p ${fuzzer}.min
|
||||||
|
for i in `ls ${fuzzer}.in`; do
|
||||||
|
fin="${fuzzer}.in/$i"
|
||||||
|
fmin="${fuzzer}.min/$i"
|
||||||
|
if ! test -e $fmin || test $fin -nt $fmin; then
|
||||||
|
afl-tmin -i $fin -o $fmin -- ./${fuzzer}
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
TMPOUT=${fuzzer}.$$.out
|
||||||
|
mkdir -p ${TMPOUT}
|
||||||
|
|
||||||
|
if test -f ${fuzzer}.dict; then
|
||||||
|
afl-fuzz -i ${fuzzer}.min -o ${TMPOUT} -x ${fuzzer}.dict -- ./${fuzzer}
|
||||||
|
else
|
||||||
|
afl-fuzz -i ${fuzzer}.min -o ${TMPOUT} -- ./${fuzzer}
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "output was stored in $TMPOUT"
|
||||||
|
|
||||||
|
exit 0
|
|
@ -0,0 +1,49 @@
|
||||||
|
#!/bin/sh -eu
|
||||||
|
#
|
||||||
|
# Copyright(c) 2017 Tim Ruehsen
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
# copy of this software and associated documentation files (the "Software"),
|
||||||
|
# to deal in the Software without restriction, including without limitation
|
||||||
|
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
# and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
# Software is furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
# DEALINGS IN THE SOFTWARE.
|
||||||
|
#
|
||||||
|
# This file is part of libpsl.
|
||||||
|
|
||||||
|
if test -z "$1"; then
|
||||||
|
echo "Usage: $0 <fuzzer target>"
|
||||||
|
echo "Example: $0 libpsl_fuzzer"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
fuzzer=$1
|
||||||
|
workers=4
|
||||||
|
|
||||||
|
clang-5.0 \
|
||||||
|
$CFLAGS -I../include -I.. \
|
||||||
|
${fuzzer}.c -o ${fuzzer} \
|
||||||
|
-Wl,-Bstatic ../src/.libs/libpsl.a -lFuzzer \
|
||||||
|
-Wl,-Bdynamic -lidn2 -lunistring -lclang-5.0 -lstdc++
|
||||||
|
|
||||||
|
# create directory for NEW test corpora (covering new areas of code)
|
||||||
|
mkdir -p ${fuzzer}.new
|
||||||
|
|
||||||
|
if test -f ${fuzzer}.dict; then
|
||||||
|
./${fuzzer} -workers=$workers -dict=${fuzzer}.dict ${fuzzer}.new ${fuzzer}.in
|
||||||
|
else
|
||||||
|
./${fuzzer} -workers=$workers ${fuzzer}.new ${fuzzer}.in
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit 0
|
|
@ -0,0 +1,21 @@
|
||||||
|
#!/bin/bash -eu
|
||||||
|
|
||||||
|
# 1. execute 'make fuzz-coverage' in the top directory
|
||||||
|
# 2. execute './view-coverage.sh <fuzz target>
|
||||||
|
# example: ./view-coverage.sh libpsl_fuzzer
|
||||||
|
|
||||||
|
if test -z "$1"; then
|
||||||
|
echo "Usage: $0 <fuzz target>"
|
||||||
|
echo "Example: $0 libpsl_fuzzer"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
fuzzer="./"$1
|
||||||
|
LCOV_INFO=coverage.info
|
||||||
|
#make fuzz-coverage CFLAGS="$(CFLAGS) --coverage" LDFLAGS="$(LDFLAGS) --coverage"
|
||||||
|
./coverage.sh $fuzzer
|
||||||
|
lcov --capture --initial --directory ../src --directory . --output-file $LCOV_INFO
|
||||||
|
lcov --capture --directory ../src --output-file $LCOV_INFO
|
||||||
|
#lcov --remove $LCOV_INFO '*/test_linking.c' '*/css_tokenizer.lex' '*/<stdout>' '*/*.h' -o $LCOV_INFO
|
||||||
|
genhtml --prefix . --ignore-errors source $LCOV_INFO --legend --title "$1" --output-directory=lcov
|
||||||
|
xdg-open lcov/index.html
|
Loading…
Reference in New Issue