From: Alan T. DeKok Date: Thu, 14 Oct 2021 14:07:04 +0000 (-0400) Subject: add fuzzer for string parsers X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ba2f3dee0817ba6caa4b94bc1484f0d465df08a7;p=thirdparty%2Ffreeradius-server.git add fuzzer for string parsers we know things will likely crash because some string parsers don't respect "end". But it already caught some issues. --- diff --git a/src/bin/all.mk b/src/bin/all.mk index 1c0a74d8cd2..9448c726267 100644 --- a/src/bin/all.mk +++ b/src/bin/all.mk @@ -23,7 +23,7 @@ SUBMAKEFILES := \ # The fuzzer binary needs special magic to run, as it doesn't parse # command-line options. See fuzzer.mk for details. # -FUZZER_PROTOCOLS = radius dhcpv4 dhcpv6 dns tacacs vmps tftp +FUZZER_PROTOCOLS = radius dhcpv4 dhcpv6 dns tacacs vmps tftp util # # Add the fuzzer only if everything was built with the fuzzing flags. diff --git a/src/lib/util/fuzzer.c b/src/lib/util/fuzzer.c new file mode 100644 index 00000000000..3a5bdd604ea --- /dev/null +++ b/src/lib/util/fuzzer.c @@ -0,0 +1,74 @@ +/* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/** Functions to manipulate DNS labels + * + * @file src/lib/util/fuzzer.c + * + * @copyright 2021 Network RADIUS SAS (legal@networkradius.com) + */ +RCSID("$Id$") + +#include +#include + +static int decode_test_ctx(void **out, UNUSED TALLOC_CTX *ctx) +{ + *out = NULL; + return 0; +} + +/* + * Try to parse the input as a (mostly text) string. + * + * This isn't perfect, but it allows simple fuzzing of the parsers for all of the data types. + */ +static ssize_t util_decode_proto(TALLOC_CTX *ctx, UNUSED fr_pair_list_t *out, uint8_t const *data, size_t data_len, UNUSED void *proto_ctx) +{ + ssize_t rcode; + fr_type_t type; + fr_value_box_t *box; + + if (data_len == 1) return data_len; + + type = data[0]; + switch (type) { + case FR_TYPE_LEAF: + break; + + default: + return data_len; + } + + box = fr_value_box_alloc(ctx, type, NULL, true); + if (!box) return -1; + + /* + * Some things in value_box_from_str() don't yet respect + * data_len. This means that we _know_ there will be + * buffer over-runs, so some issues will have to be + * ignored for now. :( + */ + rcode = fr_value_box_from_str(box, box, type, NULL, (char const *) data + 1, data_len - 1, 0, true); + talloc_free(box); + return rcode; +} + +extern fr_test_point_proto_decode_t util_tp_decode_proto; +fr_test_point_proto_decode_t util_tp_decode_proto = { + .test_ctx = decode_test_ctx, + .func = util_decode_proto +}; diff --git a/src/lib/util/libfreeradius-util.mk b/src/lib/util/libfreeradius-util.mk index 528462e290c..6dc64456420 100644 --- a/src/lib/util/libfreeradius-util.mk +++ b/src/lib/util/libfreeradius-util.mk @@ -86,6 +86,13 @@ SOURCES := \ value.c \ version.c +# +# Add the fuzzer only if everything was built with the fuzzing flags. +# +ifneq "$(findstring fuzzer,${CFLAGS})" "" +SOURCES += fuzzer.c +endif + HEADERS := $(subst src/lib/,,$(wildcard src/lib/util/*.h)) SRC_CFLAGS := -D_LIBRADIUS -DNO_ASSERT -I$(top_builddir)/src diff --git a/src/tests/fuzzer-corpus/util.tar b/src/tests/fuzzer-corpus/util.tar new file mode 100644 index 00000000000..343566253d2 --- /dev/null +++ b/src/tests/fuzzer-corpus/util.tar @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8e758917b17272b5fbd5b47c001ce246f6f19d1f49d710cb6c1673a410861d66 +size 284160