Commit 09bfc191 authored by Daniel Salzman's avatar Daniel Salzman

Merge branch 'tests-fuzz' into 'master'

Update the libFuzzer support and run fuzzed inputs on normal make check in Gitlab CI

See merge request !834
parents 03c53dea 014540a0
......@@ -57,6 +57,7 @@
/src/libknot.pc
/src/libknot/version.h
/src/knot/modules/static_modules.h
/test-driver
# dnstap
/src/contrib/dnstap/Makefile
......
......@@ -3,6 +3,7 @@ variables:
LC_ALL: C
GIT_STRATEGY: fetch
DOCKER_DRIVER: overlay2
GIT_SUBMODULE_STRATEGY: recursive
stages:
- image
......
[submodule "tests-fuzz/packet_libfuzzer.in"]
path = tests-fuzz/packet_libfuzzer.in
url = ../fuzzing/packet_libfuzzer.in.git
[submodule "tests-fuzz/zscanner_libfuzzer.in"]
path = tests-fuzz/zscanner_libfuzzer.in
url = ../fuzzing/zscanner_libfuzzer.in.git
......@@ -485,12 +485,13 @@ src/zscanner/tests/processing.h
src/zscanner/tests/tests.c
src/zscanner/tests/tests.h
src/zscanner/tests/zscanner-tool.c
tests-fuzz/afl-loop.h
tests-fuzz/packet.c
tests-fuzz/main.c
tests-fuzz/packet_libfuzzer.c
tests-fuzz/wrap/afl-loop.h
tests-fuzz/wrap/server.c
tests-fuzz/wrap/tcp-handler.c
tests-fuzz/wrap/udp-handler.c
tests-fuzz/zscanner_libfuzzer.c
tests/contrib/test_base32hex.c
tests/contrib/test_base64.c
tests/contrib/test_dynarray.c
......
......@@ -523,17 +523,7 @@ AX_CODE_COVERAGE
AX_SANITIZER
AS_IF([test -n "$sanitize_CFLAGS"], [CFLAGS="$CFLAGS $sanitize_CFLAGS"])
# LibFuzzer
AC_ARG_WITH([libfuzzer],
AC_HELP_STRING([--with-libfuzzer=path], [Path to LibFuzzer static library]),
[libfuzzer_LIBS="$withval"], [libfuzzer_LIBS=no]
)
AS_IF([test "$libfuzzer_LIBS" != no -a "$sanitize_coverage_enabled" != yes], [
AC_MSG_ERROR([Sanitizer coverage required for LibFuzzer.])
])
AM_CONDITIONAL([HAVE_LIBFUZZER], [test "$libfuzzer_LIBS" != "no"])
AC_SUBST([libfuzzer_LIBS])
AM_CONDITIONAL([SANITIZE_FUZZER], [test "$with_sanitize_fuzzer" != "no"])
AS_IF([test "$enable_documentation" = "yes"],[
......@@ -587,10 +577,12 @@ result_msg_base=" $PACKAGE $VERSION
Utilities with Dnstap: ${opt_dnstap}
Systemd integration: ${enable_systemd}
PKCS #11 support: ${enable_pkcs11}
ED25519 support: ${enable_ed25519}
Ed25519 support: ${enable_ed25519}
Code coverage: ${enable_code_coverage}
Sanitizer: ${with_sanitize}
LibFuzzer: ${libfuzzer_LIBS}"
Sanitizer coverage: ${with_sanitize_coverage}
LibFuzzer: ${with_sanitize_fuzzer}
"
result_msg_esc=$(echo -n "$result_msg_base" | sed '$!s/$/\\n/' | tr -d '\n')
result_msg_add="
......
# ===========================================================================
# https://www.gnu.org/software/autoconf-archive/ax_compare_version.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_COMPARE_VERSION(VERSION_A, OP, VERSION_B, [ACTION-IF-TRUE], [ACTION-IF-FALSE])
#
# DESCRIPTION
#
# This macro compares two version strings. Due to the various number of
# minor-version numbers that can exist, and the fact that string
# comparisons are not compatible with numeric comparisons, this is not
# necessarily trivial to do in a autoconf script. This macro makes doing
# these comparisons easy.
#
# The six basic comparisons are available, as well as checking equality
# limited to a certain number of minor-version levels.
#
# The operator OP determines what type of comparison to do, and can be one
# of:
#
# eq - equal (test A == B)
# ne - not equal (test A != B)
# le - less than or equal (test A <= B)
# ge - greater than or equal (test A >= B)
# lt - less than (test A < B)
# gt - greater than (test A > B)
#
# Additionally, the eq and ne operator can have a number after it to limit
# the test to that number of minor versions.
#
# eq0 - equal up to the length of the shorter version
# ne0 - not equal up to the length of the shorter version
# eqN - equal up to N sub-version levels
# neN - not equal up to N sub-version levels
#
# When the condition is true, shell commands ACTION-IF-TRUE are run,
# otherwise shell commands ACTION-IF-FALSE are run. The environment
# variable 'ax_compare_version' is always set to either 'true' or 'false'
# as well.
#
# Examples:
#
# AX_COMPARE_VERSION([3.15.7],[lt],[3.15.8])
# AX_COMPARE_VERSION([3.15],[lt],[3.15.8])
#
# would both be true.
#
# AX_COMPARE_VERSION([3.15.7],[eq],[3.15.8])
# AX_COMPARE_VERSION([3.15],[gt],[3.15.8])
#
# would both be false.
#
# AX_COMPARE_VERSION([3.15.7],[eq2],[3.15.8])
#
# would be true because it is only comparing two minor versions.
#
# AX_COMPARE_VERSION([3.15.7],[eq0],[3.15])
#
# would be true because it is only comparing the lesser number of minor
# versions of the two values.
#
# Note: The characters that separate the version numbers do not matter. An
# empty string is the same as version 0. OP is evaluated by autoconf, not
# configure, so must be a string, not a variable.
#
# The author would like to acknowledge Guido Draheim whose advice about
# the m4_case and m4_ifvaln functions make this macro only include the
# portions necessary to perform the specific comparison specified by the
# OP argument in the final configure script.
#
# LICENSE
#
# Copyright (c) 2008 Tim Toolan <toolan@ele.uri.edu>
#
# Copying and distribution of this file, with or without modification, are
# permitted in any medium without royalty provided the copyright notice
# and this notice are preserved. This file is offered as-is, without any
# warranty.
#serial 12
dnl #########################################################################
AC_DEFUN([AX_COMPARE_VERSION], [
AC_REQUIRE([AC_PROG_AWK])
# Used to indicate true or false condition
ax_compare_version=false
# Convert the two version strings to be compared into a format that
# allows a simple string comparison. The end result is that a version
# string of the form 1.12.5-r617 will be converted to the form
# 0001001200050617. In other words, each number is zero padded to four
# digits, and non digits are removed.
AS_VAR_PUSHDEF([A],[ax_compare_version_A])
A=`echo "$1" | sed -e 's/\([[0-9]]*\)/Z\1Z/g' \
-e 's/Z\([[0-9]]\)Z/Z0\1Z/g' \
-e 's/Z\([[0-9]][[0-9]]\)Z/Z0\1Z/g' \
-e 's/Z\([[0-9]][[0-9]][[0-9]]\)Z/Z0\1Z/g' \
-e 's/[[^0-9]]//g'`
AS_VAR_PUSHDEF([B],[ax_compare_version_B])
B=`echo "$3" | sed -e 's/\([[0-9]]*\)/Z\1Z/g' \
-e 's/Z\([[0-9]]\)Z/Z0\1Z/g' \
-e 's/Z\([[0-9]][[0-9]]\)Z/Z0\1Z/g' \
-e 's/Z\([[0-9]][[0-9]][[0-9]]\)Z/Z0\1Z/g' \
-e 's/[[^0-9]]//g'`
dnl # In the case of le, ge, lt, and gt, the strings are sorted as necessary
dnl # then the first line is used to determine if the condition is true.
dnl # The sed right after the echo is to remove any indented white space.
m4_case(m4_tolower($2),
[lt],[
ax_compare_version=`echo "x$A
x$B" | sed 's/^ *//' | sort -r | sed "s/x${A}/false/;s/x${B}/true/;1q"`
],
[gt],[
ax_compare_version=`echo "x$A
x$B" | sed 's/^ *//' | sort | sed "s/x${A}/false/;s/x${B}/true/;1q"`
],
[le],[
ax_compare_version=`echo "x$A
x$B" | sed 's/^ *//' | sort | sed "s/x${A}/true/;s/x${B}/false/;1q"`
],
[ge],[
ax_compare_version=`echo "x$A
x$B" | sed 's/^ *//' | sort -r | sed "s/x${A}/true/;s/x${B}/false/;1q"`
],[
dnl Split the operator from the subversion count if present.
m4_bmatch(m4_substr($2,2),
[0],[
# A count of zero means use the length of the shorter version.
# Determine the number of characters in A and B.
ax_compare_version_len_A=`echo "$A" | $AWK '{print(length)}'`
ax_compare_version_len_B=`echo "$B" | $AWK '{print(length)}'`
# Set A to no more than B's length and B to no more than A's length.
A=`echo "$A" | sed "s/\(.\{$ax_compare_version_len_B\}\).*/\1/"`
B=`echo "$B" | sed "s/\(.\{$ax_compare_version_len_A\}\).*/\1/"`
],
[[0-9]+],[
# A count greater than zero means use only that many subversions
A=`echo "$A" | sed "s/\(\([[0-9]]\{4\}\)\{m4_substr($2,2)\}\).*/\1/"`
B=`echo "$B" | sed "s/\(\([[0-9]]\{4\}\)\{m4_substr($2,2)\}\).*/\1/"`
],
[.+],[
AC_WARNING(
[illegal OP numeric parameter: $2])
],[])
# Pad zeros at end of numbers to make same length.
ax_compare_version_tmp_A="$A`echo $B | sed 's/./0/g'`"
B="$B`echo $A | sed 's/./0/g'`"
A="$ax_compare_version_tmp_A"
# Check for equality or inequality as necessary.
m4_case(m4_tolower(m4_substr($2,0,2)),
[eq],[
test "x$A" = "x$B" && ax_compare_version=true
],
[ne],[
test "x$A" != "x$B" && ax_compare_version=true
],[
AC_WARNING([illegal OP parameter: $2])
])
])
AS_VAR_POPDEF([A])dnl
AS_VAR_POPDEF([B])dnl
dnl # Execute ACTION-IF-TRUE / ACTION-IF-FALSE.
if test "$ax_compare_version" = "true" ; then
m4_ifvaln([$4],[$4],[:])dnl
m4_ifvaln([$5],[else $5])dnl
fi
]) dnl AX_COMPARE_VERSION
# Copyright 2015 CZ.NIC, z.s.p.o.
# Copyright 2015-2017 CZ.NIC, z.s.p.o.
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 3, as published
......@@ -19,6 +19,7 @@
#
# - sanitize_enabled yes|no
# - sanitize_coverage_enabled yes|no
# - sanitize_fuzzer_enabled yes|no
# - sanitize_CFLAGS -fsanitize=... -fsanitize-coverage=...
#
AC_DEFUN([AX_SANITIZER], [
......@@ -34,27 +35,55 @@ AC_DEFUN([AX_SANITIZER], [
[],
[with_sanitize_coverage=no]
)
AC_ARG_WITH([sanitize-fuzzer],
[AS_HELP_STRING([--with-sanitize-fuzzer], [Compile with sanitizer fuzzer (require clang >= 6.0) [default=no]])], [
# Enable SanitizerCoverage if needed by libFuzzer
AS_IF([test "$with_sanitize_coverage" = "no"],[
AC_MSG_NOTICE([Enabling sanitizer coverage because it's required for sanitizer fuzzer])
with_sanitize_coverage=yes
])],
[with_sanitize_fuzzer=no]
)
# Using -fsanitize=fuzzer requires clang >= 6.0
AS_IF([test "$with_sanitize_fuzzer" != "no"],[
# Get clang version if empty
AS_IF([test -z "$CC_CLANG_VERSION"],[AX_CC_CLANG])
AX_COMPARE_VERSION([$CC_CLANG_VERSION],ge,[6.0],[],[
AC_MSG_ERROR([clang >= 6.0 required for sanitize fuzzer])])])
# Default values
AS_IF([test "$with_sanitize" = "yes"], [ with_sanitize=address ])
AS_IF([test "$with_sanitize_coverage" = "yes"], [ with_sanitize_coverage=edge,indirect-calls,8bit-counters ])
AS_IF([test "$with_sanitize_fuzzer" = "yes"], [ with_sanitize_fuzzer=fuzzer-no-link ])
AS_IF([test "$with_sanitize_coverage" = "yes"], [ with_sanitize_coverage=edge,indirect-calls,trace-pc-guard ])
# Either --with-sanitize or --with-sanitize-fuzzer is needed for --with-sanitize-coverage
AS_IF([test "$with_sanitize" = "no" -a "$with_sanitize_fuzzer" = "no" -a "$with_sanitize_coverage" != "no"],[
AC_MSG_ERROR([--with-sanitize-coverage cannot be used without --with-sanitize or --with-sanitize-fuzzer])])
# Construct output variables
sanitize_enabled=no
sanitize_coverage_enabled=no
sanitize_fuzzer_enable=no
sanitize_CFLAGS=
AS_IF([test "$with_sanitize" != "no" -o "$with_sanitize_fuzzer" != "no"], [
AS_IF([test "$with_sanitize" != "no"], [
sanitize_CFLAGS="-fsanitize=${with_sanitize}"
sanitize_enabled=yes
AS_IF([test "$with_sanitize_fuzzer" != "no"], [ # --with-sanitize and --with-sanitize-fuzzer
sanitize_CFLAGS="-fsanitize=${with_sanitize},${with_sanitize_fuzzer}"
sanitize_fuzzer_enabled=yes
],[ # only --with-sanitize
sanitize_CFLAGS="-fsanitize=${with_sanitize}"
])
],[ # only --with-sanitize-fuzzer
AS_IF([test "$with_sanitize_fuzzer" != "no"], [
sanitize_CFLAGS="-fsanitize=${with_sanitize_fuzzer}"
sanitize_fuzzer_enabled=yes
])])
AS_IF([test "$with_sanitize_coverage" != "no"], [
sanitize_CFLAGS="$sanitize_CFLAGS -fsanitize-coverage=${with_sanitize_coverage}"
sanitize_coverage_enabled=yes
])
], [
sanitize_CFLAGS=
AS_IF([test "$with_sanitize_coverage" != "no"], [
AC_MSG_WARN([--with-sanitize-coverage cannot be used without --with-sanitize])
])
])
# Test compiler support
save_CFLAGS="$CFLAGS"
......@@ -67,5 +96,6 @@ AC_DEFUN([AX_SANITIZER], [
AC_MSG_ERROR([Sanitizer options are not supported.])
])
CFLAGS="$save_CFLAGS"
])
]) # AX_SANITIZER
......@@ -2,6 +2,9 @@
/Makefile
/knotd_stdio
/packet
/packet_libfuzzer
/wrap/main.c
/*.trs
/*.log
/packet_libfuzzer
/zscanner_libfuzzer
......@@ -4,31 +4,27 @@ AM_CPPFLAGS = \
-I$(top_srcdir)/src/dnssec/lib \
-DCONFIG_DIR='"${config_dir}"' \
-DSTORAGE_DIR='"${storage_dir}"' \
-DRUN_DIR='"${run_dir}"'
-DRUN_DIR='"${run_dir}"' \
-DSRCDIR=\"$(abs_srcdir)\"
LDADD = \
$(top_builddir)/src/libknot.la
FUZZERS = \
packet_libfuzzer \
zscanner_libfuzzer
check_PROGRAMS = \
knotd_stdio \
packet
check_PROGRAMS = $(FUZZERS)
if HAVE_LIBFUZZER
check_PROGRAMS += packet_libfuzzer
packet_libfuzzer_LDADD = $(LDADD) $(libfuzzer_LIBS) -lstdc++
endif
packet_libfuzzer_SOURCES = packet_libfuzzer.c
packet_libfuzzer_LDADD = $(top_builddir)/src/libknot.la
packet_SOURCES = packet.c afl-loop.h
knotd_stdio_SOURCES = wrap/server.c wrap/tcp-handler.c wrap/udp-handler.c afl-loop.h
nodist_knotd_stdio_SOURCES = wrap/main.c
knotd_stdio_CPPFLAGS = $(AM_CPPFLAGS) $(liburcu_CFLAGS)
knotd_stdio_LDADD = \
$(top_builddir)/src/libknotd.la $(top_builddir)/src/libcontrib.la \
$(liburcu_LIBS)
BUILT_SOURCES = wrap/main.c
CLEANFILES = wrap/main.c
wrap/main.c: Makefile $(top_builddir)/src/utils/knotd/main.c
echo '#include "afl-loop.h"' > $@
$(SED) -e 's/for (;;)/while (__AFL_LOOP(1000))/' $(top_srcdir)/src/utils/knotd/main.c >>$@
zscanner_libfuzzer_SOURCES = zscanner_libfuzzer.c
zscanner_libfuzzer_LDADD = $(top_builddir)/src/zscanner/libzscanner.la
check-compile: $(check_PROGRAMS)
if SANITIZE_FUZZER
packet_libfuzzer_LDFLAGS = -fsanitize=fuzzer
zscanner_libfuzzer_LDFLAGS = -fsanitize=fuzzer
else
packet_libfuzzer_SOURCES += main.c
zscanner_libfuzzer_SOURCES += main.c
AM_CPPFLAGS += -DTEST_RUN
TESTS = $(FUZZERS)
endif
# Fuzzing
Knot DNS 2.0 includes two fuzzing tests in `tests-fuzz/`: a) a simple
test harness that exercises the packet parsing logic in
`packet.c` and more through test that replaces UDP handler with reads
from stdin in `knotd_stdio.c`. This compiles into a test harness that
is designed to be used with lcamtuf's [American Fuzzy Lop (AFL)
fuzzer](http://lcamtuf.coredump.cx/afl/). We will use knotd_stdio in
the following examples.
## How it works
AFL 1.83b includes an experimental feature called ["persistent
mode"](http://lcamtuf.blogspot.com/2015/06/new-in-afl-persistent-mode.html)
that can be used to control AFL's fork server to fuzz inputs and
exercise the program without restarting it. You can use this new
feature along with the included Knot DNS test harness.
## Using the AFL persistent harness
### Gathering seed inputs
Gathering DNS packets for use in fuzzing is left to the tester, but
note that the fuzzing shim includes an environment variable to support
test cases minimization with `afl-cmin`:
```
$ cat > knot-afl.conf << EOF
server:
listen: 0.0.0.0@5353
log:
- target: stderr
any: error
control:
listen: /tmp/knot.sock
EOF
$ afl-cmin -i ~/knot-seeds -o ~/knot-seeds-cmin -m 1000000 -t 400000 -- tests-fuzz/knotd_stdio -c knot-afl.conf
```
You might want to configure some sample zones and have a test set of
fuzzing data that would end up querying those zones.
### Compiling the test harness.
See the AFL [blog post](http://lcamtuf.blogspot.com/2015/06/new-in-afl-persistent-mode.html)
and README for details on how to use LLVM mode and compile binaries
for use with persistent mode. For reference, you can use these
commands to build Knot with the fuzzing harness:
```
$ CC=afl-clang-fast ./configure --disable-shared
$ make check
```
### Fuzz
A basic AFL run can then be kicked off as follows:
```
AFL_PERSISTENT=1 afl-fuzz -i my_seeds -o my_output_dir -t 10000 -m 100000 -- tests-fuzz/knotd_stdio -c knot-afl.conf
```
Note that AFL can be scaled up by supplying the `-M` flag and starting
multiple instances of the fuzzer.
https://gitlab.labs.nic.cz/knot/knot-dns/wikis/Fuzzing
/*
* 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.
*/
#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>
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
#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 %llu bytes from '%s'\n", (unsigned long long) st.st_size, fname);
fflush(stdout);
LLVMFuzzerTestOneInput(data, st.st_size);
fflush(stderr);
} else {
fprintf(stderr, "Failed to read %llu bytes from %s (%d), got %zd\n",
(unsigned long long) st.st_size, fname, errno, n);
}
free(data);
close(fd);
}
closedir(dirp);
}
}
int main(int argc, char **argv)
{
const char *target = strrchr(argv[0], '/');
target = target ? target + 1 : argv[0];
char corporadir[sizeof(SRCDIR) + 1 + strlen(target) + 8];
if (strncmp(target, "lt-", 3) == 0) {
target += 3;
}
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)
{
unsigned char buf[64 * 1024];
while (__AFL_LOOP(10000)) { // only works with afl-clang-fast
int ret = fread(buf, 1, sizeof(buf), stdin);
if (ret < 0) {
return 0;
}
LLVMFuzzerTestOneInput(buf, ret);
}
return 0;
}
#endif /* TEST_RUN */
/* Copyright (C) 2015 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
/* Copyright (C) 2017 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -16,22 +16,18 @@
#include <assert.h>
#include <stdint.h>
#include <stdio.h>
#include <signal.h>
#include "libknot/libknot.h"
int LLVMFuzzerTestOneInput(const unsigned char *data, size_t size)
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
{
uint8_t *copy = malloc(size);
assert(copy);
uint8_t copy[size];
memcpy(copy, data, size);
knot_pkt_t *pkt = knot_pkt_new(copy, size, NULL);
assert(pkt);
knot_pkt_parse(pkt, 0);
knot_pkt_free(&pkt);
free(copy);
return 0;
}
Subproject commit 69e4a98151063910675bce46efcdd151348dae9d
/* Copyright (C) 2015 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
/* Copyright (C) 2017 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -16,23 +16,18 @@
#include <assert.h>
#include <stdint.h>
#include <stdio.h>
#include <signal.h>
#include "libknot/libknot.h"
#include "afl-loop.h"
#include "zscanner/scanner.h"
int main(void)
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
{
while (__AFL_LOOP(1000)) {
uint8_t buffer[UINT16_MAX + 1] = { 0 };
size_t len = fread(buffer, 1, sizeof(buffer), stdin);
zs_scanner_t s = { 0 };
assert(zs_init(&s, ".", 1, 0) == 0);
assert(zs_set_input_string(&s, (const char *)data, size) == 0);
knot_pkt_t *pkt = knot_pkt_new(buffer, len, NULL);
assert(pkt);
int r = knot_pkt_parse(pkt, 0);
knot_pkt_free(&pkt);
zs_parse_all(&s);
return (r == KNOT_EOK ? 0 : 1);
}
zs_deinit(&s);
return 0;
}
Subproject commit 91e31ee437c5ca34cfe836187136cefa54f887db
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment