• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <cstdint>
17 #include <string>
18 #include <vector>
19 #include <cstring>
20 
21 #include "securec.h"
22 #include "dhcp_logger.h"
23 #include "dhcp_dhcpd.h"
24 #include "dhcp_config.h"
25 #include "address_utils.h"
26 #include "dhcp_fuzz_common_func.h"
27 #include "dhcpdhcpd_fuzzer.h"
28 
29 using namespace std;
30 namespace OHOS {
31 namespace DHCP {
32 
33 constexpr size_t U32_AT_SIZE_ZERO = 4;
34 constexpr size_t MIN_STRING_SIZE = 8;
35 constexpr size_t MAX_IP_STRING_SIZE = 16;
36 constexpr int TWO = 2;
37 
TestStopDhcpServerMain(const uint8_t * data,size_t size)38 void TestStopDhcpServerMain(const uint8_t* data, size_t size) {
39 }
40 
TestRegisterDeviceConnectCallBack(const uint8_t * data,size_t size)41 void TestRegisterDeviceConnectCallBack(const uint8_t* data, size_t size)
42 {
43     DeviceConnectFun testCallback = [](const char* ifname) {
44         if (ifname) {
45         }
46     };
47 
48     RegisterDeviceConnectCallBack(testCallback);
49 
50     RegisterDeviceConnectCallBack(nullptr);
51 }
52 
TestParseIpAddr(const uint8_t * data,size_t size)53 void TestParseIpAddr(const uint8_t* data, size_t size)
54 {
55     if (size < U32_AT_SIZE_ZERO) {
56         return;
57     }
58 
59     size_t pos = 0;
60     uint32_t ipStringLen = U32_AT(data + pos) % MAX_IP_STRING_SIZE;
61     pos += sizeof(uint32_t);
62 
63     if (pos + ipStringLen > size) {
64         return;
65     }
66 
67     string ipString(reinterpret_cast<const char*>(data + pos), ipStringLen);
68     if (!ipString.empty()) {
69         ipString[ipString.length() - 1] = '\0';
70 
71         ParseIpAddr(ipString.c_str());
72     }
73 }
74 
TestDhcpConfigOperations(const uint8_t * data,size_t size)75 void TestDhcpConfigOperations(const uint8_t* data, size_t size)
76 {
77     if (size < sizeof(DhcpConfig)) {
78         return;
79     }
80 
81     DhcpConfig config;
82     if (memset_s(&config, sizeof(DhcpConfig), 0, sizeof(DhcpConfig)) != EOK) {
83         return;
84     }
85 
86     size_t pos = 0;
87     if (size >= pos + sizeof(uint32_t)) {
88         config.serverId = U32_AT(data + pos);
89         pos += sizeof(uint32_t);
90     }
91 
92     if (size >= pos + sizeof(uint32_t)) {
93         config.netmask = U32_AT(data + pos);
94         pos += sizeof(uint32_t);
95     }
96 
97     if (size >= pos + sizeof(uint32_t)) {
98         config.gateway = U32_AT(data + pos);
99         pos += sizeof(uint32_t);
100     }
101 
102     if (size >= pos + sizeof(uint32_t)) {
103         config.pool.beginAddress = U32_AT(data + pos);
104         pos += sizeof(uint32_t);
105     }
106 
107     if (size >= pos + sizeof(uint32_t)) {
108         config.pool.endAddress = U32_AT(data + pos);
109         pos += sizeof(uint32_t);
110     }
111 
112     if (size >= pos + sizeof(uint32_t)) {
113         config.leaseTime = U32_AT(data + pos);
114         pos += sizeof(uint32_t);
115     }
116 
117     if (size >= pos + sizeof(uint32_t)) {
118         config.renewalTime = U32_AT(data + pos);
119         pos += sizeof(uint32_t);
120     }
121 
122     if (size >= pos + sizeof(uint32_t)) {
123         config.rebindingTime = U32_AT(data + pos);
124         pos += sizeof(uint32_t);
125     }
126 
127     if (size >= pos + IFACE_NAME_SIZE) {
128         if (memcpy_s(config.ifname, IFACE_NAME_SIZE, data + pos, IFACE_NAME_SIZE) != EOK) {
129             return;
130         }
131         config.ifname[IFACE_NAME_SIZE - 1] = '\0';
132     }
133 }
134 
TestArgumentOperations(const uint8_t * data,size_t size)135 void TestArgumentOperations(const uint8_t* data, size_t size)
136 {
137     if (size < U32_AT_SIZE_ZERO + MIN_STRING_SIZE * TWO) {
138         return;
139     }
140 
141     size_t pos = 0;
142     uint32_t keyLen = U32_AT(data + pos) % 32;
143     pos += sizeof(uint32_t);
144 
145     if (pos + keyLen > size) {
146         return;
147     }
148 
149     string argKey(reinterpret_cast<const char*>(data + pos), keyLen);
150     pos += keyLen;
151 
152     if (pos + sizeof(uint32_t) > size) {
153         return;
154     }
155 
156     uint32_t valueLen = U32_AT(data + pos) % 64;
157     pos += sizeof(uint32_t);
158 
159     if (pos + valueLen > size) {
160         return;
161     }
162 
163     string argValue(reinterpret_cast<const char*>(data + pos), valueLen);
164 
165     if (!argKey.empty()) {
166         argKey[argKey.length() - 1] = '\0';
167     }
168     if (!argValue.empty()) {
169         argValue[argValue.length() - 1] = '\0';
170     }
171 }
172 
TestStringOperations(const uint8_t * data,size_t size)173 void TestStringOperations(const uint8_t* data, size_t size)
174 {
175     if (size < U32_AT_SIZE_ZERO) {
176         return;
177     }
178 
179     size_t pos = 0;
180     uint32_t strLen = U32_AT(data + pos) % 256;
181     pos += sizeof(uint32_t);
182 
183     if (pos + strLen > size) {
184         return;
185     }
186 
187     vector<char> testString(strLen + 1, 0);
188     if (strLen > 0) {
189         if (memcpy_s(testString.data(), strLen, data + pos, strLen) != EOK) {
190             return;
191         }
192     }
193     testString[strLen] = '\0';
194 
195     if (strLen > 0) {
196         ParseIpAddr(testString.data());
197     }
198 }
199 
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)200 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
201 {
202     if ((data == nullptr) || (size <= OHOS::DHCP::U32_AT_SIZE_ZERO)) {
203         return 0;
204     }
205 
206     TestStartDhcpServerMain(data, size);
207     TestStopDhcpServerMain(data, size);
208     TestRegisterDeviceConnectCallBack(data, size);
209     TestParseIpAddr(data, size);
210     TestDhcpConfigOperations(data, size);
211     TestArgumentOperations(data, size);
212     TestStringOperations(data, size);
213 
214     return 0;
215 }
216 
217 }  // namespace DHCP
218 }  // namespace OHOS