summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Hanselmann <public@hansmi.ch>2021-05-29 20:23:30 +0200
committerMichael Hanselmann <public@hansmi.ch>2021-06-20 22:57:56 +0200
commit7097884249d4542e407aca4c3a7e9f4f1b4e6644 (patch)
treeb5c125a6e153d6427bb3397f2fabb6d2efd11d9c
parent68d143f59258c249473ea743213e72bfd78d6a07 (diff)
Add fuzzer for filters
Filters are exposed to the peer and parser bugs could be dangerous. None were found during the implementation of this fuzzer. A minor change is made to the filter code to reject separators which aren't exactly one character long (as documented as a requirement). Signed-off-by: Michael Hanselmann <public@hansmi.ch>
-rw-r--r--fuzzing/meson.build1
-rw-r--r--fuzzing/usbredirfilterfuzz.cc107
2 files changed, 108 insertions, 0 deletions
diff --git a/fuzzing/meson.build b/fuzzing/meson.build
index ae6c0fd..0cfd5d7 100644
--- a/fuzzing/meson.build
+++ b/fuzzing/meson.build
@@ -34,6 +34,7 @@ endif
fuzz_targets = {
'usbredirparserfuzz': [usbredir_parser_lib_dep],
+ 'usbredirfilterfuzz': [usbredir_parser_lib_dep],
}
foreach target_name, deps : fuzz_targets
diff --git a/fuzzing/usbredirfilterfuzz.cc b/fuzzing/usbredirfilterfuzz.cc
new file mode 100644
index 0000000..e5d180f
--- /dev/null
+++ b/fuzzing/usbredirfilterfuzz.cc
@@ -0,0 +1,107 @@
+/* usbredirfilterfuzz.cc -- fuzzing for usbredirfilter
+
+ Copyright 2021 Michael Hanselmann
+
+ 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 the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This program 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <cstdio>
+#include <limits>
+#include <memory>
+#include <string>
+
+#include <fuzzer/FuzzedDataProvider.h>
+
+#include "usbredirfilter.h"
+
+namespace {
+struct FilterDeleter {
+ void operator()(void *ptr) {
+ usbredirfilter_free(ptr);
+ }
+};
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
+{
+ static FILE *dev_null = nullptr;
+
+ if (dev_null == nullptr) {
+ dev_null = fopen("/dev/null", "wb");
+ if (dev_null == nullptr) {
+ perror("open /dev/null");
+ abort();
+ }
+ }
+
+ FuzzedDataProvider fdp{data, size};
+ std::unique_ptr<usbredirfilter_rule, FilterDeleter> rules;
+ int ret, rules_count;
+
+ const std::string
+ token_sep = fdp.ConsumeBytesAsString(1),
+ rule_sep = fdp.ConsumeBytesAsString(1);
+
+ {
+ usbredirfilter_rule *rules_ptr = nullptr;
+
+ ret = usbredirfilter_string_to_rules(
+ fdp.ConsumeRandomLengthString().c_str(),
+ token_sep.c_str(), rule_sep.c_str(),
+ &rules_ptr, &rules_count);
+
+ if (ret != 0 || rules_ptr == nullptr) {
+ return 1;
+ }
+
+ rules.reset(rules_ptr);
+ }
+
+ usbredirfilter_verify(rules.get(), rules_count);
+ usbredirfilter_print(rules.get(), rules_count, dev_null);
+
+ {
+ std::unique_ptr<char, FilterDeleter> str;
+
+ str.reset(usbredirfilter_rules_to_string(rules.get(), rules_count,
+ token_sep.c_str(),
+ rule_sep.c_str()));
+ }
+
+ {
+ const int interface_count = fdp.ConsumeIntegralInRange(1, 128);
+ std::vector<uint8_t>
+ interface_class = fdp.ConsumeBytes<uint8_t>(interface_count),
+ interface_subclass = fdp.ConsumeBytes<uint8_t>(interface_count),
+ interface_protocol = fdp.ConsumeBytes<uint8_t>(interface_count);
+
+ // Fill with zeros up to the desired length
+ interface_class.resize(interface_count, 0);
+ interface_subclass.resize(interface_count, 0);
+ interface_protocol.resize(interface_count, 0);
+
+ usbredirfilter_check(rules.get(), rules_count,
+ fdp.ConsumeIntegral<uint8_t>(), fdp.ConsumeIntegral<uint8_t>(),
+ fdp.ConsumeIntegral<uint8_t>(),
+ &interface_class[0], &interface_subclass[0], &interface_protocol[0],
+ interface_count,
+ fdp.ConsumeIntegral<uint16_t>(), fdp.ConsumeIntegral<uint16_t>(),
+ fdp.ConsumeIntegral<uint16_t>(),
+ fdp.ConsumeIntegral<uint8_t>());
+ }
+
+ return 0;
+}
+
+/* vim: set sw=4 sts=4 et : */