1 /*
2  * Copyright (c) 2022-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 "ethernet_client_fuzzer.h"
17 
18 #include <cstddef>
19 #include <cstdint>
20 #include <iosfwd>
21 #include <memory>
22 #include <new>
23 #include <securec.h>
24 #include <string>
25 
26 #include "mac_address_info.h"
27 #include "netmanager_ext_test_security.h"
28 #include "refbase.h"
29 #include "singleton.h"
30 
31 #include "dev_interface_state.h"
32 #define private public
33 #include "ethernet_client.h"
34 #include "ethernet_service.h"
35 #include "interface_configuration.h"
36 #include "interface_state_callback_stub.h"
37 
38 namespace OHOS {
39 namespace NetManagerStandard {
40 namespace {
41 const uint8_t *g_baseFuzzData = nullptr;
42 static constexpr uint32_t CREATE_BOOL_TYPE_VALUE = 2;
43 size_t g_baseFuzzSize = 0;
44 size_t g_baseFuzzPos;
45 constexpr size_t IFACE_LEN = 5;
46 } // namespace
47 
GetData()48 template <class T> T GetData()
49 {
50     T object{};
51     size_t objectSize = sizeof(object);
52     if (g_baseFuzzData == nullptr || objectSize > g_baseFuzzSize - g_baseFuzzPos) {
53         return object;
54     }
55     errno_t ret = memcpy_s(&object, objectSize, g_baseFuzzData + g_baseFuzzPos, objectSize);
56     if (ret != EOK) {
57         return {};
58     }
59     g_baseFuzzPos += objectSize;
60     return object;
61 }
62 
63 class MonitorInterfaceStateCallback : public InterfaceStateCallbackStub {
64 public:
OnInterfaceAdded(const std::string & ifName)65     int32_t OnInterfaceAdded(const std::string &ifName) override
66     {
67         return 0;
68     }
69 
OnInterfaceRemoved(const std::string & ifName)70     int32_t OnInterfaceRemoved(const std::string &ifName) override
71     {
72         return 0;
73     }
74 
OnInterfaceChanged(const std::string & ifName,bool up)75     int32_t OnInterfaceChanged(const std::string &ifName, bool up) override
76     {
77         return 0;
78     }
79 };
80 
GetStringFromData(int strlen)81 std::string GetStringFromData(int strlen)
82 {
83     char cstr[strlen];
84     cstr[strlen - 1] = '\0';
85     for (int i = 0; i < strlen - 1; i++) {
86         cstr[i] = GetData<char>();
87     }
88     std::string str(cstr);
89     return str;
90 }
91 
92 static bool g_isInited = false;
93 
Init()94 void Init()
95 {
96     if (!g_isInited) {
97         DelayedSingleton<EthernetService>::GetInstance()->Init();
98         g_isInited = true;
99     }
100 }
101 
WriteInterfaceToken(MessageParcel & data)102 bool WriteInterfaceToken(MessageParcel &data)
103 {
104     if (!data.WriteInterfaceToken(EthernetServiceStub::GetDescriptor())) {
105         return false;
106     }
107     return true;
108 }
109 
IsDataAndWriteVaild(const uint8_t * data,size_t size,MessageParcel & parcel)110 bool IsDataAndWriteVaild(const uint8_t *data, size_t size, MessageParcel &parcel)
111 {
112     if ((data == nullptr) || (size == 0)) {
113         return false;
114     }
115     NetManagerExtAccessToken token;
116     g_baseFuzzData = data;
117     g_baseFuzzSize = size;
118     g_baseFuzzPos = 0;
119 
120     std::string iface = GetStringFromData(IFACE_LEN);
121     WriteInterfaceToken(parcel);
122     if (!parcel.WriteString(iface)) {
123         return false;
124     }
125 
126     return true;
127 }
128 
129 
OnRemoteRequest(uint32_t code,MessageParcel & data)130 int32_t OnRemoteRequest(uint32_t code, MessageParcel &data)
131 {
132     if (!g_isInited) {
133         Init();
134     }
135 
136     MessageParcel reply;
137     MessageOption option;
138     return DelayedSingleton<EthernetService>::GetInstance()->OnRemoteRequest(code, data, reply, option);
139 }
140 
GetMacAddressFuzzTest(const uint8_t * data,size_t size)141 void GetMacAddressFuzzTest(const uint8_t *data, size_t size)
142 {
143     if ((data == nullptr) || (size == 0)) {
144         return;
145     }
146     g_baseFuzzData = data;
147     g_baseFuzzSize = size;
148     g_baseFuzzPos = 0;
149     NetManagerExtAccessToken token;
150     MessageParcel parcel;
151     std::string iface = GetStringFromData(IFACE_LEN);
152     WriteInterfaceToken(parcel);
153     if (!parcel.WriteString(iface)) {
154         return;
155     }
156     OnRemoteRequest(static_cast<uint32_t>(EthernetInterfaceCode::CMD_GET_MAC_ADDR_INFO), parcel);
157 }
158 
SetIfaceConfigFuzzTest(const uint8_t * data,size_t size)159 void SetIfaceConfigFuzzTest(const uint8_t *data, size_t size)
160 {
161     MessageParcel parcel;
162     if (!IsDataAndWriteVaild(data, size, parcel)) {
163         return;
164     }
165     auto ic = std::make_unique<InterfaceConfiguration>();
166     if (!ic->Marshalling(parcel)) {
167         return;
168     }
169     OnRemoteRequest(static_cast<uint32_t>(EthernetInterfaceCode::CMD_SET_IF_CFG), parcel);
170 }
171 
GetIfaceConfigFuzzTest(const uint8_t * data,size_t size)172 void GetIfaceConfigFuzzTest(const uint8_t *data, size_t size)
173 {
174     if ((data == nullptr) || (size == 0)) {
175         return;
176     }
177     g_baseFuzzData = data;
178     g_baseFuzzSize = size;
179     g_baseFuzzPos = 0;
180     NetManagerExtAccessToken token;
181     MessageParcel parcel;
182     std::string iface = GetStringFromData(IFACE_LEN);
183     WriteInterfaceToken(parcel);
184     if (!parcel.WriteString(iface)) {
185         return;
186     }
187     OnRemoteRequest(static_cast<uint32_t>(EthernetInterfaceCode::CMD_GET_IF_CFG), parcel);
188 }
189 
IsIfaceActiveFuzzTest(const uint8_t * data,size_t size)190 void IsIfaceActiveFuzzTest(const uint8_t *data, size_t size)
191 {
192     if ((data == nullptr) || (size == 0)) {
193         return;
194     }
195     g_baseFuzzData = data;
196     g_baseFuzzSize = size;
197     g_baseFuzzPos = 0;
198     NetManagerExtAccessToken token;
199     MessageParcel parcel;
200     std::string iface = GetStringFromData(IFACE_LEN);
201     WriteInterfaceToken(parcel);
202     if (!parcel.WriteString(iface)) {
203         return;
204     }
205     OnRemoteRequest(static_cast<uint32_t>(EthernetInterfaceCode::CMD_IS_ACTIVATE), parcel);
206 }
207 
GetAllActiveIfacesFuzzTest(const uint8_t * data,size_t size)208 void GetAllActiveIfacesFuzzTest(const uint8_t *data, size_t size)
209 {
210     if ((data == nullptr) || (size == 0)) {
211         return;
212     }
213     NetManagerExtAccessToken token;
214     MessageParcel parcel;
215     WriteInterfaceToken(parcel);
216     OnRemoteRequest(static_cast<uint32_t>(EthernetInterfaceCode::CMD_GET_ACTIVATE_INTERFACE), parcel);
217 }
218 
ResetFactoryFuzzTest(const uint8_t * data,size_t size)219 void ResetFactoryFuzzTest(const uint8_t *data, size_t size)
220 {
221     if ((data == nullptr) || (size == 0)) {
222         return;
223     }
224     NetManagerExtAccessToken token;
225     MessageParcel parcel;
226     WriteInterfaceToken(parcel);
227     OnRemoteRequest(static_cast<uint32_t>(EthernetInterfaceCode::CMD_RESET_FACTORY), parcel);
228 }
229 
UnregisterIfacesStateChangedFuzzTest(const uint8_t * data,size_t size)230 void UnregisterIfacesStateChangedFuzzTest(const uint8_t *data, size_t size)
231 {
232     if ((data == nullptr) || (size == 0)) {
233         return;
234     }
235     NetManagerExtAccessToken token;
236     g_baseFuzzData = data;
237     g_baseFuzzSize = size;
238     g_baseFuzzPos = 0;
239     sptr<InterfaceStateCallback> interfaceCallback = new (std::nothrow) MonitorInterfaceStateCallback();
240     DelayedSingleton<EthernetClient>::GetInstance()->RegisterIfacesStateChanged(interfaceCallback);
241     DelayedSingleton<EthernetClient>::GetInstance()->UnregisterIfacesStateChanged(interfaceCallback);
242 }
243 
OnRegisterIfacesStateChangedFuzzTest(const uint8_t * data,size_t size)244 void OnRegisterIfacesStateChangedFuzzTest(const uint8_t *data, size_t size)
245 {
246     if ((data == nullptr) || (size == 0)) {
247         return;
248     }
249     MessageParcel parcel;
250     sptr<IRemoteObject> remote;
251     parcel.WriteRemoteObject(remote);
252     OnRemoteRequest(static_cast<uint32_t>(EthernetInterfaceCode::CMD_REGISTER_INTERFACE_CB), parcel);
253     OnRemoteRequest(static_cast<uint32_t>(EthernetInterfaceCode::CMD_UNREGISTER_INTERFACE_CB), parcel);
254 }
255 
SetInterfaceUpFuzzTest(const uint8_t * data,size_t size)256 void SetInterfaceUpFuzzTest(const uint8_t *data, size_t size)
257 {
258     MessageParcel parcel;
259     if (!IsDataAndWriteVaild(data, size, parcel)) {
260         return;
261     }
262     OnRemoteRequest(static_cast<uint32_t>(EthernetInterfaceCode::CMD_SET_INTERFACE_UP), parcel);
263 }
264 
SetInterfaceDownFuzzTest(const uint8_t * data,size_t size)265 void SetInterfaceDownFuzzTest(const uint8_t *data, size_t size)
266 {
267     MessageParcel parcel;
268     if (!IsDataAndWriteVaild(data, size, parcel)) {
269         return;
270     }
271     OnRemoteRequest(static_cast<uint32_t>(EthernetInterfaceCode::CMD_SET_INTERFACE_DOWN), parcel);
272 }
273 
GetInterfaceConfigFuzzTest(const uint8_t * data,size_t size)274 void GetInterfaceConfigFuzzTest(const uint8_t *data, size_t size)
275 {
276     MessageParcel parcel;
277     if (!IsDataAndWriteVaild(data, size, parcel)) {
278         return;
279     }
280     OnRemoteRequest(static_cast<uint32_t>(EthernetInterfaceCode::CMD_GET_INTERFACE_CONFIG), parcel);
281 }
282 
SetInterfaceConfigFuzzTest(const uint8_t * data,size_t size)283 void SetInterfaceConfigFuzzTest(const uint8_t *data, size_t size)
284 {
285     if ((data == nullptr) || (size == 0)) {
286         return;
287     }
288     NetManagerExtAccessToken token;
289     g_baseFuzzData = data;
290     g_baseFuzzSize = size;
291     g_baseFuzzPos = 0;
292     MessageParcel parcel;
293     std::string randStr = GetStringFromData(IFACE_LEN);
294     WriteInterfaceToken(parcel);
295     if (!parcel.WriteString(randStr)) {
296         return;
297     }
298     if (!parcel.WriteString(randStr)) {
299         return;
300     }
301     if (!parcel.WriteString(randStr)) {
302         return;
303     }
304     if (!parcel.WriteString(randStr)) {
305         return;
306     }
307     if (!parcel.WriteInt32(GetData<int32_t>())) {
308         return;
309     }
310     if (!parcel.WriteInt32(1)) {
311         return;
312     }
313     if (!parcel.WriteString(randStr)) {
314         return;
315     }
316     OnRemoteRequest(static_cast<uint32_t>(EthernetInterfaceCode::CMD_SET_INTERFACE_CONFIG), parcel);
317 }
318 
EthernetServiceCommonFuzzTest(const uint8_t * data,size_t size)319 void EthernetServiceCommonFuzzTest(const uint8_t *data, size_t size)
320 {
321     if ((data == nullptr) || (size == 0)) {
322         return;
323     }
324     g_baseFuzzData = data;
325     g_baseFuzzSize = size;
326     g_baseFuzzPos = 0;
327 
328     auto ethernetServiceCommon = std::make_unique<EthernetServiceCommon>();
329 
330     ethernetServiceCommon->ResetEthernetFactory();
331 }
332 
EthernetManagementFuzzTest(const uint8_t * data,size_t size)333 void EthernetManagementFuzzTest(const uint8_t *data, size_t size)
334 {
335     if ((data == nullptr) || (size == 0)) {
336         return;
337     }
338     g_baseFuzzData = data;
339     g_baseFuzzSize = size;
340     g_baseFuzzPos = 0;
341 
342     auto ethernetManagement = std::make_unique<EthernetManagement>();
343     EthernetDhcpCallback::DhcpResult dhcpResult;
344     ethernetManagement->UpdateDevInterfaceLinkInfo(dhcpResult);
345 
346     std::string dev = GetStringFromData(IFACE_LEN);
347     bool up = GetData<uint32_t>() % CREATE_BOOL_TYPE_VALUE == 0;
348     ethernetManagement->UpdateInterfaceState(dev, up);
349 
350     std::string iface = GetStringFromData(IFACE_LEN);
351     std::vector<MacAddressInfo> mai;
352     ethernetManagement->GetMacAddress(mai);
353 
354     sptr<InterfaceConfiguration> cfg;
355     ethernetManagement->UpdateDevInterfaceCfg(iface, cfg);
356 
357     sptr<InterfaceConfiguration> ifaceConfig;
358     ethernetManagement->GetDevInterfaceCfg(iface, ifaceConfig);
359 
360     int32_t activeStatus = 0;
361     ethernetManagement->IsIfaceActive(iface, activeStatus);
362 
363     std::vector<std::string> result;
364     ethernetManagement->GetAllActiveIfaces(result);
365 
366     ethernetManagement->ResetFactory();
367     std::string devName = GetStringFromData(IFACE_LEN);
368     ethernetManagement->DevInterfaceAdd(devName);
369     ethernetManagement->DevInterfaceRemove(devName);
370 }
371 
EthernetDhcpControllerFuzzTest(const uint8_t * data,size_t size)372 void EthernetDhcpControllerFuzzTest(const uint8_t *data, size_t size)
373 {
374     if ((data == nullptr) || (size == 0)) {
375         return;
376     }
377     g_baseFuzzData = data;
378     g_baseFuzzSize = size;
379     g_baseFuzzPos = 0;
380 
381     auto ethernetDhcpController = std::make_unique<EthernetDhcpController>();
382 
383     sptr<EthernetDhcpCallback> callback;
384     ethernetDhcpController->RegisterDhcpCallback(callback);
385 
386     std::string iface = GetStringFromData(IFACE_LEN);
387     bool bIpv6 = GetData<uint32_t>() % CREATE_BOOL_TYPE_VALUE == 0;
388     ethernetDhcpController->StartClient(iface, bIpv6);
389 
390     ethernetDhcpController->StopClient(iface, bIpv6);
391 }
392 } // namespace NetManagerStandard
393 } // namespace OHOS
394 
395 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)396 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
397 {
398     /* Run your code on data */
399     OHOS::NetManagerStandard::SetIfaceConfigFuzzTest(data, size);
400     OHOS::NetManagerStandard::GetIfaceConfigFuzzTest(data, size);
401     OHOS::NetManagerStandard::IsIfaceActiveFuzzTest(data, size);
402     OHOS::NetManagerStandard::GetAllActiveIfacesFuzzTest(data, size);
403     OHOS::NetManagerStandard::ResetFactoryFuzzTest(data, size);
404     OHOS::NetManagerStandard::UnregisterIfacesStateChangedFuzzTest(data, size);
405     OHOS::NetManagerStandard::OnRegisterIfacesStateChangedFuzzTest(data, size);
406     OHOS::NetManagerStandard::SetInterfaceUpFuzzTest(data, size);
407     OHOS::NetManagerStandard::SetInterfaceDownFuzzTest(data, size);
408     OHOS::NetManagerStandard::GetInterfaceConfigFuzzTest(data, size);
409     OHOS::NetManagerStandard::SetInterfaceConfigFuzzTest(data, size);
410     OHOS::NetManagerStandard::EthernetServiceCommonFuzzTest(data, size);
411     OHOS::NetManagerStandard::EthernetManagementFuzzTest(data, size);
412     OHOS::NetManagerStandard::EthernetDhcpControllerFuzzTest(data, size);
413     return 0;
414 }
415