summaryrefslogtreecommitdiffstats
path: root/fuzz/fuzz_packets_kea_dhcp4.cc
diff options
context:
space:
mode:
authorAndrei Pavel <andrei@isc.org>2024-10-15 11:41:41 +0200
committerAndrei Pavel <andrei@isc.org>2024-10-23 15:40:31 +0200
commita96168e7625541f15fc58811104c8da0303646f4 (patch)
treeae63bde11d86d1276c6efe4bb000a24c5e6486c7 /fuzz/fuzz_packets_kea_dhcp4.cc
parent[#3605] Remove extra semis (diff)
downloadkea-a96168e7625541f15fc58811104c8da0303646f4.tar.xz
kea-a96168e7625541f15fc58811104c8da0303646f4.zip
[#3605] Integrate a new fuzzing solution in Kea
The solution is based on clusterfuzzlite, libfuzzer, and oss-fuzz technologies. - Add the .clusterfuzzlite directory. - Add the fuzz CI stage and fuzzing CI jobs. - Add the fuzzing targets in the fuzz directory. - Document fuzzing in doxygen.
Diffstat (limited to 'fuzz/fuzz_packets_kea_dhcp4.cc')
-rw-r--r--fuzz/fuzz_packets_kea_dhcp4.cc121
1 files changed, 121 insertions, 0 deletions
diff --git a/fuzz/fuzz_packets_kea_dhcp4.cc b/fuzz/fuzz_packets_kea_dhcp4.cc
new file mode 100644
index 0000000000..ae335fdc61
--- /dev/null
+++ b/fuzz/fuzz_packets_kea_dhcp4.cc
@@ -0,0 +1,121 @@
+// Copyright (C) 2024 Internet Systems Consortium, Inc. ("ISC")
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#include <config.h>
+
+#include <fuzz.h>
+
+#include <cc/command_interpreter.h>
+#include <cc/user_context.h>
+#include <dhcp4/ctrl_dhcp4_srv.h>
+#include <dhcp4/json_config_parser.h>
+#include <dhcp4/parser_context.h>
+#include <dhcpsrv/packet_fuzzer.h>
+#include <util/encode/encode.h>
+
+#include <cassert>
+#include <cstdlib>
+#include <util/filesystem.h>
+#include <vector>
+
+using namespace isc;
+using namespace isc::config;
+using namespace isc::util;
+using namespace std;
+
+namespace {
+
+static string const KEA_DHCP4_CONF(KEA_FUZZ_DIR + "/kea-dhcp4.conf");
+static string KEA_DHCP4_FUZZING_INTERFACE;
+static string KEA_DHCP4_FUZZING_ADDRESS;
+
+} // namespace
+
+extern "C" {
+
+int
+LLVMFuzzerInitialize() {
+ static bool initialized(DoInitialization());
+ assert(initialized);
+
+ setenv("KEA_DHCP4_FUZZING_ROTATE_PORT", "true", 0);
+
+ char const* interface(getenv("KEA_DHCP4_FUZZING_INTERFACE"));
+ KEA_DHCP4_FUZZING_INTERFACE = string(interface ? interface : "lo");
+
+ char const* address(getenv("KEA_DHCP4_FUZZING_ADDRESS"));
+ KEA_DHCP4_FUZZING_ADDRESS = string(address ? address : "127.0.0.1");
+
+ writeToFile(KEA_DHCP4_CONF, R"(
+ {
+ "Dhcp4": {
+ "interfaces-config": {
+ "dhcp-socket-type": "udp",
+ "interfaces": [
+ ")" + KEA_DHCP4_FUZZING_INTERFACE + R"("
+ ]
+ },
+ "lease-database": {
+ "persist": false,
+ "type": "memfile"
+ },
+ "subnet4": [
+ {
+ "id": 1,
+ "pools": [
+ {
+ "pool": "10.0.0.0/8"
+ }
+ ],
+ "subnet": "10.0.0.0/8"
+ }
+ ]
+ }
+ }
+ )");
+
+ // Iterate through the interfaces and expect no errors.
+ for (IfacePtr const& interface : IfaceMgr::instance().getIfaces()) {
+ for (string const& error : interface->getErrors()) {
+ cout << error << endl;
+ }
+ assert(interface->getErrors().empty());
+ }
+
+ return 0;
+}
+
+int
+LLVMFuzzerTearDown() {
+ try {
+ remove(KEA_DHCP4_CONF.c_str());
+ } catch (...) {
+ }
+ return 0;
+}
+
+int
+LLVMFuzzerTestOneInput(uint8_t const* data, size_t size) {
+ vector<uint8_t> byte_stream;
+ bool const valid(byteStreamToPacketData(data, size, byte_stream));
+ if (!valid) {
+ cout << "Invalid input. Skipping..." << endl;
+ return 0;
+ }
+
+ ControlledDhcpv4Srv server;
+ server.init(KEA_DHCP4_CONF);
+
+ // Fuzz.
+ PacketFuzzer fuzzer(ControlledDhcpv4Srv::getInstance()->getServerPort(),
+ KEA_DHCP4_FUZZING_INTERFACE, KEA_DHCP4_FUZZING_ADDRESS);
+ fuzzer.transfer(byte_stream.data(), byte_stream.size());
+ ControlledDhcpv4Srv::getInstance()->runOne();
+
+ return 0;
+}
+
+} // extern "C"