/src/kea-fuzzer/fuzz_mysql6.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 <asiolink/io_address.h> |
11 | | #include <database/database_connection.h> |
12 | | #include <database/server_selector.h> |
13 | | #include <dhcpsrv/subnet.h> |
14 | | #include <dhcpsrv/host.h> |
15 | | #include <dhcpsrv/cfg_option.h> |
16 | | |
17 | | #include <log/logger_support.h> |
18 | | #include <process/daemon.h> |
19 | | #include <exceptions/exceptions.h> |
20 | | |
21 | | #include <mysql_cb_impl.h> |
22 | | #include <mysql_cb_dhcp6.h> |
23 | | |
24 | | #include <cstdint> |
25 | | #include <cstddef> |
26 | | #include <string> |
27 | | #include <set> |
28 | | #include <vector> |
29 | | #include <map> |
30 | | #include <utility> |
31 | | #include <iostream> |
32 | | |
33 | | using namespace isc::asiolink; |
34 | | using namespace isc::db; |
35 | | using namespace isc::dhcp; |
36 | | using namespace isc::util; |
37 | | |
38 | | extern "C" void mysqlmock_load_bytes(const uint8_t* data, size_t size); |
39 | | |
40 | 6.76k | extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { |
41 | | // Initialise logging |
42 | 6.76k | setenv("KEA_LOGGER_DESTINATION", "/dev/null", 0); |
43 | 6.76k | setenv("KEA_LOCKFILE_DIR", "/tmp", 0); |
44 | 6.76k | setenv("KEA_PIDFILE_DIR", "/tmp", 0); |
45 | 6.76k | setenv("KEA_LFC_EXECUTABLE", "/bin/true", 0); |
46 | 6.76k | try { |
47 | 6.76k | isc::log::initLogger("fuzzer"); |
48 | 6.76k | isc::process::Daemon::loggerInit("fuzzer", false); |
49 | 6.76k | isc::process::Daemon::setDefaultLoggerName("fuzzer"); |
50 | 6.76k | } catch (...) { |
51 | | // Early exit if logging initialisation failed |
52 | 0 | return 0; |
53 | 0 | } |
54 | | |
55 | 6.76k | FuzzedDataProvider fdp(data, size); |
56 | 6.76k | mysqlmock_load_bytes(data, size); |
57 | 6.76k | DbCallback db_cb; |
58 | | |
59 | | // Prepare tags |
60 | 6.76k | std::set<std::string> tags; |
61 | 6.76k | std::string tag = fdp.ConsumeRandomLengthString(16); |
62 | 6.76k | if (tag.empty()) { |
63 | 2.46k | tag = "default-tag"; |
64 | 2.46k | } |
65 | 6.76k | tags.insert(tag); |
66 | | |
67 | | // Prepare DatabaseConnection parameter maps |
68 | 6.76k | DatabaseConnection::ParameterMap params; |
69 | 6.76k | std::string dbname = fdp.ConsumeRandomLengthString(16); |
70 | 6.76k | if (dbname.empty()) { |
71 | 3.35k | dbname = "kea_fuzz"; |
72 | 3.35k | } |
73 | 6.76k | params["name"] = dbname; |
74 | 6.76k | params[fdp.ConsumeRandomLengthString(16)] = fdp.ConsumeRandomLengthString(16); |
75 | 6.76k | params[fdp.ConsumeRandomLengthString(16)] = fdp.ConsumeRandomLengthString(16); |
76 | | |
77 | | // Prepare server selector |
78 | 6.76k | ServerSelector selector = ServerSelector::UNASSIGNED(); |
79 | 6.76k | try { |
80 | 6.76k | switch (fdp.ConsumeIntegralInRange<int>(0, 3)) { |
81 | 4.87k | case 0: selector = ServerSelector::ALL(); break; |
82 | 974 | case 1: selector = ServerSelector::ONE(tag); break; |
83 | 515 | case 2: selector = ServerSelector::MULTIPLE(tags); break; |
84 | 395 | case 3: selector = ServerSelector::ANY(); break; |
85 | 6.76k | } |
86 | 6.76k | } catch (const isc::Exception&) { |
87 | | // Silent exceptions use default UNASSIGNED |
88 | 79 | } |
89 | | |
90 | 6.76k | try { |
91 | 6.76k | MySqlConfigBackendImpl backend("v6", params, db_cb); |
92 | 6.76k | MySqlConfigBackendDHCPv6 dhcp_backend(params); |
93 | | |
94 | | // Target getGlobalParameter6 |
95 | 6.76k | try { |
96 | 6.76k | dhcp_backend.getGlobalParameter6(selector, fdp.ConsumeRandomLengthString(32)); |
97 | 6.76k | } catch (const isc::Exception& e) { |
98 | | // Slient exceptions |
99 | 2.59k | } |
100 | | |
101 | | // Target getAllSubnets6 |
102 | 6.76k | try { |
103 | 6.45k | dhcp_backend.getAllSubnets6(selector); |
104 | 6.45k | } catch (const isc::Exception& e) { |
105 | | // Slient exceptions |
106 | 1.12k | } |
107 | | |
108 | | // Target createUpdateSubnet6 |
109 | 6.45k | try { |
110 | 6.45k | IOAddress address("::1"); |
111 | | |
112 | 6.45k | uint32_t a1 = fdp.ConsumeIntegral<uint32_t>(); |
113 | 6.45k | uint32_t b1 = fdp.ConsumeIntegral<uint32_t>(); |
114 | 6.45k | uint32_t c1 = fdp.ConsumeIntegral<uint32_t>(); |
115 | 6.45k | Triplet<uint32_t> t1(a1, b1, c1); |
116 | | |
117 | 6.45k | uint32_t a2 = fdp.ConsumeIntegral<uint32_t>(); |
118 | 6.45k | uint32_t b2 = fdp.ConsumeIntegral<uint32_t>(); |
119 | 6.45k | uint32_t c2 = fdp.ConsumeIntegral<uint32_t>(); |
120 | 6.45k | Triplet<uint32_t> t2(a2, b2, c2); |
121 | | |
122 | 6.45k | uint32_t a3 = fdp.ConsumeIntegral<uint32_t>(); |
123 | 6.45k | uint32_t b3 = fdp.ConsumeIntegral<uint32_t>(); |
124 | 6.45k | uint32_t c3 = fdp.ConsumeIntegral<uint32_t>(); |
125 | 6.45k | Triplet<uint32_t> t3(a3, b3, c3); |
126 | | |
127 | 6.45k | uint32_t a4 = fdp.ConsumeIntegral<uint32_t>(); |
128 | 6.45k | uint32_t b4 = fdp.ConsumeIntegral<uint32_t>(); |
129 | 6.45k | uint32_t c4 = fdp.ConsumeIntegral<uint32_t>(); |
130 | 6.45k | Triplet<uint32_t> t4(a4, b4, c4); |
131 | | |
132 | 6.45k | SubnetID sid = static_cast<SubnetID>(fdp.ConsumeIntegralInRange<uint32_t>(1, UINT32_MAX)); |
133 | 6.45k | Subnet6Ptr subnet(Subnet6::create(address, |
134 | 6.45k | fdp.ConsumeIntegralInRange(0, 32), |
135 | 6.45k | t1, t2, t3, t4, sid)); |
136 | 6.45k | dhcp_backend.createUpdateSubnet6(selector, subnet); |
137 | 6.45k | } catch (const isc::Exception& e) { |
138 | | // Slient exceptions |
139 | 2.00k | } |
140 | | |
141 | | // Target deleteSubnet6 |
142 | 6.45k | try { |
143 | 6.45k | dhcp_backend.deleteSubnet6(selector, fdp.ConsumeRandomLengthString(32)); |
144 | 6.45k | } catch (const isc::Exception& e) { |
145 | | // Slient exceptions |
146 | 73 | } |
147 | | |
148 | | // Target createUpdateOption6 |
149 | 6.45k | try { |
150 | 6.45k | OptionBuffer opt_buf; |
151 | 6.45k | OptionPtr opt(new Option(Option::V4, fdp.ConsumeIntegralInRange<uint16_t>(1, 254), opt_buf)); |
152 | 6.45k | OptionDescriptorPtr opt_desc(new OptionDescriptor(opt, true, true)); |
153 | | |
154 | 6.45k | std::string opt_space = "dhcp4"; |
155 | 6.45k | std::string opt_name = fdp.ConsumeRandomLengthString(32); |
156 | 6.45k | if (opt_name.empty()) { |
157 | 5.12k | opt_name = "fuzz-opt"; |
158 | 5.12k | } |
159 | | |
160 | 6.45k | dhcp_backend.createUpdateOption6(selector, opt_name, opt_desc); |
161 | 6.45k | } catch (const isc::Exception& e) { |
162 | | // Slient exceptions |
163 | 73 | } |
164 | 6.45k | } catch (const isc::Exception&) { |
165 | | // Silent top-level exceptions |
166 | 307 | } |
167 | | |
168 | 6.76k | return 0; |
169 | 6.76k | } |