/src/kea-fuzzer/fuzz_dhcpsrv.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 <string> |
11 | | |
12 | | #include <cc/data.h> |
13 | | #include <cc/simple_parser.h> |
14 | | |
15 | | #include <dhcpsrv/srv_config.h> |
16 | | #include <dhcpsrv/cfg_option_def.h> |
17 | | #include <dhcpsrv/cfg_option.h> |
18 | | #include <dhcpsrv/cfg_iface.h> |
19 | | #include <dhcpsrv/cfg_duid.h> |
20 | | #include <dhcpsrv/cfg_expiration.h> |
21 | | #include <dhcpsrv/cfg_mac_source.h> |
22 | | #include <dhcpsrv/client_class_def.h> |
23 | | |
24 | | #include <dhcpsrv/parsers/dhcp_parsers.h> |
25 | | #include <dhcpsrv/parsers/option_data_parser.h> |
26 | | #include <dhcpsrv/parsers/ifaces_config_parser.h> |
27 | | #include <dhcpsrv/parsers/duid_config_parser.h> |
28 | | #include <dhcpsrv/parsers/multi_threading_config_parser.h> |
29 | | #include <dhcpsrv/parsers/sanity_checks_parser.h> |
30 | | #include <dhcpsrv/parsers/expiration_config_parser.h> |
31 | | #include <dhcpsrv/parsers/client_class_def_parser.h> |
32 | | #include <dhcpsrv/parsers/host_reservation_parser.h> |
33 | | #include <dhcpsrv/parsers/simple_parser4.h> |
34 | | #include <dhcpsrv/parsers/simple_parser6.h> |
35 | | |
36 | | #include "helper_func.h" |
37 | | |
38 | | using namespace isc; |
39 | | using namespace isc::data; |
40 | | using namespace isc::dhcp; |
41 | | |
42 | 3.51k | extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size) { |
43 | 3.51k | FuzzedDataProvider fdp(Data, Size); |
44 | 3.51k | std::string payload = fdp.ConsumeRandomLengthString(); |
45 | | |
46 | 3.51k | std::string raw_payload(reinterpret_cast<const char*>(Data), Size); |
47 | 3.51k | ElementPtr payload_elem = nullptr; |
48 | 3.51k | try { |
49 | 3.51k | payload_elem = Element::fromJSON(payload); |
50 | 3.51k | } catch (...) { |
51 | 787 | return 0; |
52 | 787 | } |
53 | | |
54 | | |
55 | 2.72k | try { |
56 | | // Simple Parsing |
57 | 2.72k | SimpleParser4::setAllDefaults(payload_elem); |
58 | 2.72k | SimpleParser4::deriveParameters(payload_elem); |
59 | 2.72k | SimpleParser6::setAllDefaults(payload_elem); |
60 | 2.72k | SimpleParser6::deriveParameters(payload_elem); |
61 | 2.72k | } catch (const isc::Exception&) {} |
62 | 2.72k | try { |
63 | | // Configuration Option definition parsing |
64 | | //ElementPtr elem = fuzz::parseJSON(payload); |
65 | 2.72k | CfgOptionDefPtr defs(new CfgOptionDef()); |
66 | 2.72k | OptionDefListParser defp4(AF_INET); |
67 | 2.72k | defp4.parse(defs, payload_elem); |
68 | | //elem = fuzz::parseJSON(fdp.ConsumeRandomLengthString()); |
69 | 2.72k | OptionDefListParser defp6(AF_INET6); |
70 | 2.72k | defp6.parse(defs, payload_elem); |
71 | 2.72k | } catch (const isc::Exception&) {} |
72 | 2.72k | try { |
73 | | |
74 | | // Configuration Option data parsing |
75 | | //ElementPtr elem = fuzz::parseJSON(payload); |
76 | 2.72k | CfgOptionPtr opts(new CfgOption()); |
77 | 2.72k | CfgOptionDefPtr defs(new CfgOptionDef()); |
78 | 2.72k | OptionDataListParser odlp4(AF_INET, defs); |
79 | 2.72k | odlp4.parse(opts, payload_elem, fdp.ConsumeBool()); |
80 | | //elem = fuzz::parseJSON(fdp.ConsumeRandomLengthString()); |
81 | 2.72k | OptionDataListParser odlp6(AF_INET6, defs); |
82 | 2.72k | odlp6.parse(opts, payload_elem, fdp.ConsumeBool()); |
83 | 2.72k | } catch (const isc::Exception&) {} |
84 | 2.72k | try { |
85 | | |
86 | | // Interfaces configuration parsing |
87 | | //ElementPtr elem = fuzz::parseJSON(payload); |
88 | 2.72k | CfgIfacePtr ifcfg(new CfgIface()); |
89 | 2.72k | IfacesConfigParser ifparser4(AF_INET, false); |
90 | 2.72k | ifparser4.parse(ifcfg, payload_elem); |
91 | 2.72k | } catch (const isc::Exception&) {} |
92 | 2.72k | try { |
93 | | //ElementPtr elem = fuzz::parseJSON(payload); |
94 | 2.72k | CfgIfacePtr ifcfg(new CfgIface()); |
95 | 2.72k | IfacesConfigParser ifparser6(AF_INET6, false); |
96 | 2.72k | ifparser6.parse(ifcfg, payload_elem); |
97 | 2.72k | } catch (const isc::Exception&) {} |
98 | 2.72k | try { |
99 | | |
100 | | // DUID configuration parsing |
101 | 2.72k | ElementPtr elem = fuzz::parseJSON(payload); |
102 | 2.72k | CfgDUIDPtr duid(new CfgDUID()); |
103 | 2.72k | DUIDConfigParser duidp; |
104 | 2.72k | duidp.parse(duid, elem); |
105 | 2.72k | } catch (const isc::Exception&) {} |
106 | 2.72k | try { |
107 | | |
108 | | // Configuration expiration parsing |
109 | | //ElementPtr elem = fuzz::parseJSON(payload); |
110 | 2.72k | CfgExpirationPtr exp(new CfgExpiration()); |
111 | 2.72k | ExpirationConfigParser expp; |
112 | 2.72k | expp.parse(payload_elem, exp); |
113 | 2.72k | } catch (const isc::Exception&) {} |
114 | 2.72k | try { |
115 | | |
116 | | // MAC list parsing |
117 | 2.72k | CfgMACSource macs; |
118 | 2.72k | MACSourcesListConfigParser macp; |
119 | | //ElementPtr elem = fuzz::parseJSON(payload); |
120 | 2.72k | macp.parse(macs, payload_elem); |
121 | 2.72k | } catch (const isc::Exception&) {} |
122 | 2.72k | try { |
123 | | |
124 | | // Multi-Threading configuration parsing |
125 | 2.72k | SrvConfig srv; |
126 | | //ElementPtr elem = fuzz::parseJSON(payload); |
127 | 2.72k | MultiThreadingConfigParser mtcp; |
128 | 2.72k | mtcp.parse(srv, payload_elem); |
129 | 2.72k | } catch (const isc::Exception&) {} |
130 | | |
131 | 2.72k | try { |
132 | | |
133 | | // Sanity Check parsing |
134 | 2.72k | SrvConfig srv; |
135 | | //ElementPtr elem = fuzz::parseJSON(payload); |
136 | 2.72k | SanityChecksParser scp; |
137 | 2.72k | scp.parse(srv, payload_elem); |
138 | 2.72k | } catch (const isc::Exception&) {} |
139 | 2.72k | try { |
140 | | |
141 | | // Client Class definition parsing |
142 | | // ElementPtr elem = fuzz::parseJSON(payload); |
143 | 2.72k | ClientClassDictionaryPtr dict(new ClientClassDictionary()); |
144 | 2.72k | ClientClassDefParser ccdp; |
145 | 2.72k | ccdp.parse(dict, payload_elem, AF_INET); |
146 | 2.72k | ccdp.parse(dict, payload_elem, AF_INET6); |
147 | 2.72k | } catch (const isc::Exception&) { |
148 | | // Slient exceptions |
149 | 2.72k | } |
150 | | |
151 | | |
152 | 2.72k | try { |
153 | | // SubnetConfigParser parsing |
154 | | //ElementPtr elem = fuzz::parseJSON(payload); |
155 | 2.72k | Subnet4ConfigParser scf(fdp.ConsumeBool()); |
156 | 2.72k | scf.parse(payload_elem, fdp.ConsumeBool()); |
157 | 2.72k | } |
158 | 2.72k | catch (const isc::Exception&) { |
159 | | // Slient exceptions |
160 | 2.72k | } |
161 | | |
162 | | |
163 | | // ControlSocketsParser |
164 | 2.72k | try { |
165 | 2.72k | ElementPtr elem = fuzz::parseJSON(payload); |
166 | 2.72k | SrvConfig srv; |
167 | 2.72k | ControlSocketsParser csp; |
168 | 2.72k | csp.parse(srv, elem); |
169 | 2.72k | } catch (const isc::Exception&) { |
170 | | // Slient exceptions |
171 | 2.70k | } |
172 | | |
173 | 2.72k | try { |
174 | | // Subnet6ConfigParser parsing |
175 | 2.72k | ElementPtr elem = fuzz::parseJSON(payload); |
176 | 2.72k | Subnet6ConfigParser scf(fdp.ConsumeBool()); |
177 | 2.72k | scf.parse(elem, fdp.ConsumeBool()); |
178 | 2.72k | } catch (const isc::Exception&) { |
179 | | // Slient exceptions |
180 | 2.72k | } |
181 | | |
182 | 2.72k | try { |
183 | | // D2ClientConfigParser parsing |
184 | 2.72k | ElementPtr elem = fuzz::parseJSON(payload); |
185 | 2.72k | D2ClientConfigParser d2p; |
186 | 2.72k | d2p.parse(elem); |
187 | 2.72k | } catch (const isc::Exception&) { |
188 | | // Slient exceptions |
189 | 2.72k | } |
190 | | |
191 | | // Host Reservation parsing |
192 | 2.72k | try { |
193 | | // Host Reservation parsing |
194 | 2.72k | ElementPtr elem = fuzz::parseJSON(payload); |
195 | 2.72k | HostReservationParser4 hrp; |
196 | 2.72k | hrp.parse(SubnetID(10), elem, fdp.ConsumeBool()); |
197 | 2.72k | } catch (const isc::Exception&) { |
198 | | // Slient exceptions |
199 | 2.64k | } |
200 | | |
201 | 2.72k | try { |
202 | | // Host Reservation parsing |
203 | 2.72k | ElementPtr elem = fuzz::parseJSON(payload); |
204 | 2.72k | HostReservationParser6 hrp; |
205 | 2.72k | hrp.parse(SubnetID(10), elem, fdp.ConsumeBool()); |
206 | 2.72k | } catch (const isc::Exception&) { |
207 | | // Slient exceptions |
208 | 2.65k | } |
209 | | |
210 | 2.72k | return 0; |
211 | 2.72k | } |