diff options
author | Andrei Pavel <andrei@isc.org> | 2024-10-15 11:41:41 +0200 |
---|---|---|
committer | Andrei Pavel <andrei@isc.org> | 2024-10-23 15:40:31 +0200 |
commit | a96168e7625541f15fc58811104c8da0303646f4 (patch) | |
tree | ae63bde11d86d1276c6efe4bb000a24c5e6486c7 /fuzz/fuzz_packets_kea_dhcp4.cc | |
parent | [#3605] Remove extra semis (diff) | |
download | kea-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.cc | 121 |
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" |