1 /*
2 * Copyright (C) 2024 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 "dhcpfunction_fuzzer.h"
17
18 #include <cstddef>
19 #include <cstdint>
20 #include <unistd.h>
21 #include <algorithm>
22 #include "securec.h"
23 #include "dhcp_function.h"
24
25 namespace OHOS {
26 namespace DHCP {
27 constexpr size_t DHCP_SLEEP_1 = 2;
28 constexpr int TWO = 2;
29 constexpr size_t MAX_STRING_SIZE = 1024; // Maximum safe string size for fuzz testing
30 constexpr size_t MIN_DATA_SIZE = 1; // Minimum data size required
31 constexpr size_t MIN_SIZE_FOR_THREE_BYTES = 3;
32 std::shared_ptr<DhcpFunction> pDhcpFunction = std::make_shared<DhcpFunction>();
33
Ip4StrConToIntTest(const uint8_t * data,size_t size)34 void Ip4StrConToIntTest(const uint8_t* data, size_t size)
35 {
36 if (size < MIN_DATA_SIZE) {
37 return;
38 }
39 uint32_t index = 0;
40 uint32_t uIp = static_cast<uint32_t>(data[index++]);
41 size_t strSize = (size > MAX_STRING_SIZE) ? MAX_STRING_SIZE : size;
42 std::string strIp = std::string(reinterpret_cast<const char*>(data), strSize);
43 bool bHost = (static_cast<int>(data[0]) % TWO) ? true : false;
44 pDhcpFunction->Ip4StrConToInt(strIp, uIp, bHost);
45 }
46
Ip6StrConToCharTest(const uint8_t * data,size_t size)47 void Ip6StrConToCharTest(const uint8_t* data, size_t size)
48 {
49 if (size == 0) {
50 return;
51 }
52 size_t strSize = (size > MAX_STRING_SIZE) ? MAX_STRING_SIZE : size;
53 std::string strIp = std::string(reinterpret_cast<const char*>(data), strSize);
54 uint8_t chIp[sizeof(struct in6_addr)] = {0};
55 pDhcpFunction->Ip6StrConToChar(strIp, chIp, sizeof(struct in6_addr));
56 }
57
CheckIpStrTest(const uint8_t * data,size_t size)58 void CheckIpStrTest(const uint8_t* data, size_t size)
59 {
60 if (size == 0) {
61 return;
62 }
63 size_t strSize = (size > MAX_STRING_SIZE) ? MAX_STRING_SIZE : size;
64 std::string strIp = std::string(reinterpret_cast<const char*>(data), strSize);
65 pDhcpFunction->CheckIpStr(strIp);
66 }
67
IsExistFileTest(const uint8_t * data,size_t size)68 void IsExistFileTest(const uint8_t* data, size_t size)
69 {
70 if (size == 0) {
71 return;
72 }
73 size_t strSize = (size > MAX_STRING_SIZE) ? MAX_STRING_SIZE : size;
74 std::string filename = std::string(reinterpret_cast<const char*>(data), strSize);
75 pDhcpFunction->IsExistFile(filename);
76 }
77
CreateFileTest(const uint8_t * data,size_t size)78 void CreateFileTest(const uint8_t* data, size_t size)
79 {
80 if (size == 0) {
81 return;
82 }
83 size_t strSize = (size > MAX_STRING_SIZE) ? MAX_STRING_SIZE : size;
84 std::string filename = std::string(reinterpret_cast<const char*>(data), strSize);
85 std::string filedata = std::string(reinterpret_cast<const char*>(data), strSize);
86 pDhcpFunction->CreateFile(filename, filedata);
87 }
88
RemoveFileTest(const uint8_t * data,size_t size)89 void RemoveFileTest(const uint8_t* data, size_t size)
90 {
91 if (size == 0) {
92 return;
93 }
94 size_t strSize = (size > MAX_STRING_SIZE) ? MAX_STRING_SIZE : size;
95 std::string filename = std::string(reinterpret_cast<const char*>(data), strSize);
96 pDhcpFunction->RemoveFile(filename);
97 }
98
FormatStringTest(const uint8_t * data,size_t size)99 void FormatStringTest(const uint8_t* data, size_t size)
100 {
101 struct DhcpPacketResult result;
102 memset_s(&result, sizeof(result), 0, sizeof(result));
103 strncpy_s(result.strYiaddr, INET_ADDRSTRLEN, "*", INET_ADDRSTRLEN - 1);
104 strncpy_s(result.strOptServerId, INET_ADDRSTRLEN, "*", INET_ADDRSTRLEN - 1);
105 strncpy_s(result.strOptSubnet, INET_ADDRSTRLEN, "*", INET_ADDRSTRLEN - 1);
106 strncpy_s(result.strOptDns1, INET_ADDRSTRLEN, "*", INET_ADDRSTRLEN - 1);
107 strncpy_s(result.strOptDns2, INET_ADDRSTRLEN, "*", INET_ADDRSTRLEN - 1);
108 strncpy_s(result.strOptRouter1, INET_ADDRSTRLEN, "*", INET_ADDRSTRLEN - 1);
109 strncpy_s(result.strOptRouter2, INET_ADDRSTRLEN, "*", INET_ADDRSTRLEN - 1);
110 strncpy_s(result.strOptVendor, DHCP_FILE_MAX_BYTES, "*", DHCP_FILE_MAX_BYTES - 1);
111 pDhcpFunction->FormatString(result);
112 }
113
CreateDirsTest(const uint8_t * data,size_t size)114 void CreateDirsTest(const uint8_t* data, size_t size)
115 {
116 if (size == 0) {
117 return;
118 }
119 int mode = DIR_DEFAULT_MODE;
120 size_t strSize = (size > MAX_STRING_SIZE) ? MAX_STRING_SIZE : size;
121 std::string dirs = std::string(reinterpret_cast<const char*>(data), strSize);
122 pDhcpFunction->CreateDirs(dirs, mode);
123 }
124
125
GetLocalMacTest(const uint8_t * data,size_t size)126 void GetLocalMacTest(const uint8_t* data, size_t size)
127 {
128 if (size == 0) {
129 return;
130 }
131 size_t strSize = (size > MAX_STRING_SIZE) ? MAX_STRING_SIZE : size;
132 std::string ethInf = std::string(reinterpret_cast<const char*>(data), strSize);
133 std::string ethMac = std::string(reinterpret_cast<const char*>(data), strSize);
134 pDhcpFunction->GetLocalMac(ethInf, ethMac);
135 }
136
CheckRangeNetworkTest(const uint8_t * data,size_t size)137 void CheckRangeNetworkTest(const uint8_t* data, size_t size)
138 {
139 if (size == 0) {
140 return;
141 }
142 size_t strSize = (size > MAX_STRING_SIZE) ? MAX_STRING_SIZE : size;
143 std::string strInf = std::string(reinterpret_cast<const char*>(data), strSize);
144 std::string strBegin = std::string(reinterpret_cast<const char*>(data), strSize);
145 std::string strEnd = std::string(reinterpret_cast<const char*>(data), strSize);
146 pDhcpFunction->CheckRangeNetwork(strInf, strBegin, strEnd);
147 }
148
CheckSameNetworkTest(const uint8_t * data,size_t size)149 void CheckSameNetworkTest(const uint8_t* data, size_t size)
150 {
151 if (size < MIN_SIZE_FOR_THREE_BYTES) {
152 return;
153 }
154 int index = 0;
155 uint32_t srcIp = static_cast<uint8_t>(data[index++]);
156 uint32_t dstIp = static_cast<uint8_t>(data[index++]);
157 uint32_t maskIp = static_cast<uint8_t>(data[index++]);
158 pDhcpFunction->CheckSameNetwork(srcIp, dstIp, maskIp);
159 }
160
161 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)162 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
163 {
164 if (data == nullptr || size == 0) {
165 return 0;
166 }
167
168 sleep(DHCP_SLEEP_1);
169 OHOS::DHCP::Ip4StrConToIntTest(data, size);
170 OHOS::DHCP::Ip6StrConToCharTest(data, size);
171 OHOS::DHCP::CheckIpStrTest(data, size);
172 OHOS::DHCP::IsExistFileTest(data, size);
173 OHOS::DHCP::CreateFileTest(data, size);
174 OHOS::DHCP::RemoveFileTest(data, size);
175 OHOS::DHCP::FormatStringTest(data, size);
176 OHOS::DHCP::CreateDirsTest(data, size);
177 OHOS::DHCP::GetLocalMacTest(data, size);
178 OHOS::DHCP::CheckRangeNetworkTest(data, size);
179 OHOS::DHCP::CheckSameNetworkTest(data, size);
180 return 0;
181 }
182 } // namespace DHCP
183 } // namespace OHOS
184