/src/kea-fuzzer/fuzz_hook_flex_id4.cc
Line | Count | Source |
1 | | // Copyright (C) 2025 Ada Logcis Ltd. |
2 | | // |
3 | | // This Source Code Form is subject to the terms of the Mozilla Public |
4 | | // License, v. 2.0. If a copy of the MPL was not distributed with this |
5 | | // file, You can obtain one at http://mozilla.org/MPL/2.0/. |
6 | | //////////////////////////////////////////////////////////////////////////////// |
7 | | #include <config.h> |
8 | | #include <fuzzer/FuzzedDataProvider.h> |
9 | | |
10 | | #include <dhcp/dhcp4.h> |
11 | | #include <dhcp/pkt4.h> |
12 | | #include <dhcp/libdhcp++.h> |
13 | | #include <dhcp4/ctrl_dhcp4_srv.h> |
14 | | #include <dhcpsrv/callout_handle_store.h> |
15 | | #include <log/logger_support.h> |
16 | | #include <util/filesystem.h> |
17 | | |
18 | | #include <cstddef> |
19 | | #include <cstdint> |
20 | | #include <vector> |
21 | | #include <list> |
22 | | #include <memory> |
23 | | #include <iostream> |
24 | | #include <filesystem> |
25 | | #include <fstream> |
26 | | #include <string> |
27 | | #include <cstdio> |
28 | | |
29 | | #include "helper_func.h" |
30 | | |
31 | | using namespace isc::dhcp; |
32 | | using namespace isc::hooks; |
33 | | using namespace isc::util; |
34 | | |
35 | | extern "C" int pkt4_receive(CalloutHandle& handle); |
36 | | |
37 | 5.65k | extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { |
38 | 5.65k | if (size < 236) { |
39 | | // package size requires at least 236 bytes |
40 | 30 | return 0; |
41 | 30 | } |
42 | | |
43 | | // Initialise logging |
44 | 5.62k | setenv("KEA_LOGGER_DESTINATION", "/dev/null", 0); |
45 | 5.62k | setenv("KEA_LOCKFILE_DIR", "/tmp", 0); |
46 | 5.62k | setenv("KEA_PIDFILE_DIR", "/tmp", 0); |
47 | 5.62k | setenv("KEA_LFC_EXECUTABLE", "/bin/true", 0); |
48 | 5.62k | try { |
49 | 5.62k | isc::log::initLogger("fuzzer"); |
50 | 5.62k | isc::process::Daemon::loggerInit("fuzzer", false); |
51 | 5.62k | isc::process::Daemon::setDefaultLoggerName("fuzzer"); |
52 | 5.62k | } catch (...) { |
53 | | // Early exit if logging initialisation failed |
54 | 0 | return 0; |
55 | 0 | } |
56 | | |
57 | 5.62k | Pkt4Ptr pkt; |
58 | | |
59 | | // Package parsing |
60 | 5.62k | try { |
61 | | // Add fixed magic cookie and correct hardware address |
62 | 5.62k | std::vector<uint8_t> buf(data, data + size); |
63 | 5.62k | if (size >= 240) { |
64 | | // Max hardware address length is 20 |
65 | 5.56k | buf[2] = 20; |
66 | | |
67 | | // Magic cookie fixed value 0x63825363 |
68 | 5.56k | buf[236] = 0x63; |
69 | 5.56k | buf[237] = 0x82; |
70 | 5.56k | buf[238] = 0x53; |
71 | 5.56k | buf[239] = 0x63; |
72 | 5.56k | } |
73 | | |
74 | 5.62k | pkt = Pkt4Ptr(new Pkt4(buf.data(), buf.size())); |
75 | 5.62k | pkt->unpack(); |
76 | 5.62k | } catch (...) { |
77 | | // Early exit if package parsing failed. |
78 | 2.81k | return 0; |
79 | 2.81k | } |
80 | | |
81 | | // Configure random value in packet |
82 | 2.80k | FuzzedDataProvider fdp(data, size); |
83 | 2.80k | uint8_t typeChoice = fdp.ConsumeIntegralInRange<uint8_t>(0, 8); |
84 | 2.80k | pkt->setType(static_cast<DHCPMessageType>(typeChoice)); |
85 | | |
86 | 2.80k | CalloutHandlePtr handle = getCalloutHandle(pkt); |
87 | | |
88 | | // Fuzz pkt4_receive |
89 | 2.80k | try { |
90 | 2.80k | handle->setArgument("query4", pkt); |
91 | 2.80k | pkt4_receive(*handle); |
92 | 2.80k | } catch (const isc::Exception& e) { |
93 | | // Slient exceptions |
94 | 0 | } catch (const boost::exception& e) { |
95 | | // Slient exceptions |
96 | 0 | } |
97 | | |
98 | | // Clean handle to avoid mem leak |
99 | 2.80k | if (handle) { |
100 | 2.80k | handle->deleteAllArguments(); |
101 | 2.80k | } |
102 | | |
103 | 2.80k | return 0; |
104 | 2.80k | } |