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 <securec.h>
17 #include <thread>
18
19 #include "common_net_diag_callback_test.h"
20 #include "iservice_registry.h"
21 #include "net_diag_callback_stub.h"
22 #include "netsys_native_client.h"
23 #include "notify_callback_stub.h"
24 #include "singleton.h"
25 #include "system_ability_definition.h"
26 #define private public
27 #include "iptables_wrapper.h"
28 #include "netsys_native_service.h"
29 #include "netsys_native_service_stub.h"
30
31 namespace OHOS {
32 namespace NetManagerStandard {
33 namespace {
34 const uint8_t *g_baseFuzzData = nullptr;
35 size_t g_baseFuzzSize = 0;
36 size_t g_baseFuzzPos;
37 constexpr size_t STR_LEN = 10;
38 constexpr int32_t NUMBER_TWO = 2;
39 constexpr int32_t NUMBER_ONE = 1;
40 bool g_isWaitAsync = false;
41 } // namespace
42
NetDiagGetData()43 template <class T> T NetDiagGetData()
44 {
45 T object{};
46 size_t netDiagSize = sizeof(object);
47 if (g_baseFuzzData == nullptr || netDiagSize > g_baseFuzzSize - g_baseFuzzPos) {
48 return object;
49 }
50 errno_t ret = memcpy_s(&object, netDiagSize, g_baseFuzzData + g_baseFuzzPos, netDiagSize);
51 if (ret != EOK) {
52 return {};
53 }
54 g_baseFuzzPos += netDiagSize;
55 return object;
56 }
57
NetDiagGetString(int strlen)58 std::string NetDiagGetString(int strlen)
59 {
60 char cstr[strlen];
61 cstr[strlen - 1] = '\0';
62 for (int i = 0; i < strlen - 1; i++) {
63 cstr[i] = NetDiagGetData<char>();
64 }
65 std::string str(cstr);
66 return str;
67 }
68
69 static bool g_isInited = false;
Init()70 __attribute__((no_sanitize("cfi"))) void Init()
71 {
72 nmd::IptablesWrapper::GetInstance();
73 g_isInited = DelayedSingleton<NetsysNative::NetsysNativeService>::GetInstance()->Init();
74 }
75
OnRemoteRequest(uint32_t code,MessageParcel & data)76 __attribute__((no_sanitize("cfi"))) int32_t OnRemoteRequest(uint32_t code, MessageParcel &data)
77 {
78 if (!g_isInited) {
79 Init();
80 }
81
82 MessageParcel reply;
83 MessageOption option;
84
85 return DelayedSingleton<NetsysNative::NetsysNativeService>::GetInstance()->OnRemoteRequest(code, data, reply,
86 option);
87 }
88
WriteInterfaceToken(MessageParcel & data)89 bool WriteInterfaceToken(MessageParcel &data)
90 {
91 return data.WriteInterfaceToken(NetsysNative::NetsysNativeServiceStub::GetDescriptor());
92 }
93
WriteInterfaceTokenCallback(MessageParcel & data)94 bool WriteInterfaceTokenCallback(MessageParcel &data)
95 {
96 return data.WriteInterfaceToken(NetsysNative::NotifyCallbackStub::GetDescriptor());
97 }
98
IsDataAndSizeValid(const uint8_t * data,size_t size,MessageParcel & dataParcel)99 bool IsDataAndSizeValid(const uint8_t *data, size_t size, MessageParcel &dataParcel)
100 {
101 if ((data == nullptr) || (size == 0)) {
102 return false;
103 }
104 g_baseFuzzData = data;
105 g_baseFuzzSize = size;
106 g_baseFuzzPos = 0;
107
108 return WriteInterfaceToken(dataParcel);
109 }
110
NetDiagGetSocketInfoFuzzTest(const uint8_t * data,size_t size)111 void NetDiagGetSocketInfoFuzzTest(const uint8_t *data, size_t size)
112 {
113 MessageParcel dataParcel;
114 if (!IsDataAndSizeValid(data, size, dataParcel)) {
115 return;
116 }
117 const int maxProtoType = 5;
118 NetsysNative::NetDiagProtocolType protoclType =
119 static_cast<NetsysNative::NetDiagProtocolType>(NetDiagGetData<uint8_t>() % maxProtoType);
120 dataParcel.WriteUint8(static_cast<uint8_t>(protoclType));
121 OnRemoteRequest(static_cast<uint32_t>(NetsysNative::NetsysInterfaceCode::NETSYS_NETDIAG_GET_SOCKETS_INFO),
122 dataParcel);
123 }
124
NetDiagGetRouteTableFuzzTest(const uint8_t * data,size_t size)125 void NetDiagGetRouteTableFuzzTest(const uint8_t *data, size_t size)
126 {
127 MessageParcel dataParcel;
128 if (!IsDataAndSizeValid(data, size, dataParcel)) {
129 return;
130 }
131 OnRemoteRequest(static_cast<uint32_t>(NetsysNative::NetsysInterfaceCode::NETSYS_NETDIAG_GET_ROUTE_TABLE),
132 dataParcel);
133 }
134
NetDiagUpdateInterfaceConfigFuzzTest(const uint8_t * data,size_t size)135 __attribute__((no_sanitize("cfi"))) void NetDiagUpdateInterfaceConfigFuzzTest(const uint8_t *data, size_t size)
136 {
137 MessageParcel dataParcel;
138 if (!IsDataAndSizeValid(data, size, dataParcel)) {
139 return;
140 }
141 bool isAdd = (NetDiagGetData<int32_t>() % NUMBER_TWO == NUMBER_ONE) ? true : false;
142 OHOS::NetsysNative::NetDiagIfaceConfig config;
143 config.ifaceName_ = NetDiagGetString(STR_LEN);
144 config.linkEncap_ = NetDiagGetString(STR_LEN);
145 config.macAddr_ = NetDiagGetString(STR_LEN);
146 config.ipv4Addr_ = NetDiagGetString(STR_LEN);
147 config.ipv4Bcast_ = NetDiagGetString(STR_LEN);
148 config.ipv4Mask_ = NetDiagGetString(STR_LEN);
149 config.mtu_ = NetDiagGetData<uint32_t>();
150 config.txQueueLen_ = NetDiagGetData<uint32_t>();
151 config.rxBytes_ = NetDiagGetData<int32_t>();
152 config.txBytes_ = NetDiagGetData<int32_t>();
153
154 if (!config.Marshalling(dataParcel)) {
155 return;
156 }
157 dataParcel.WriteString(NetDiagGetString(STR_LEN));
158 dataParcel.WriteBool(isAdd);
159 OnRemoteRequest(static_cast<uint32_t>(NetsysNative::NetsysInterfaceCode::NETSYS_NETDIAG_UPDATE_IFACE_CONFIG),
160 dataParcel);
161 }
162
NetDiagSetInterfaceActiveFuzzTest(const uint8_t * data,size_t size)163 void NetDiagSetInterfaceActiveFuzzTest(const uint8_t *data, size_t size)
164 {
165 MessageParcel dataParcel;
166 if (!IsDataAndSizeValid(data, size, dataParcel)) {
167 return;
168 }
169 const int numberTow = 2;
170 std::string iFaceName = NetDiagGetString(STR_LEN);
171 bool isUp = NetDiagGetData<uint32_t>() % numberTow == 0;
172
173 dataParcel.WriteString(iFaceName);
174 dataParcel.WriteBool(isUp);
175
176 OnRemoteRequest(static_cast<uint32_t>(NetsysNative::NetsysInterfaceCode::NETSYS_NETDIAG_SET_IFACE_ACTIVE_STATE),
177 dataParcel);
178 }
179
NetDiagGetInterfaceConfigFuzzTest(const uint8_t * data,size_t size)180 void NetDiagGetInterfaceConfigFuzzTest(const uint8_t *data, size_t size)
181 {
182 MessageParcel dataParcel;
183 if (!IsDataAndSizeValid(data, size, dataParcel)) {
184 return;
185 }
186
187 std::string iFaceName = NetDiagGetString(STR_LEN);
188 dataParcel.WriteString(iFaceName);
189 OnRemoteRequest(static_cast<uint32_t>(NetsysNative::NetsysInterfaceCode::NETSYS_NETDIAG_GET_IFACE_CONFIG),
190 dataParcel);
191 }
192
NetDiagPingFuzzTest(const uint8_t * data,size_t size)193 __attribute__((no_sanitize("cfi"))) void NetDiagPingFuzzTest(const uint8_t *data, size_t size)
194 {
195 const int maxWaitSecond = 10;
196 const int numberTow = 2;
197 MessageParcel dataParcel;
198 if (!IsDataAndSizeValid(data, size, dataParcel)) {
199 return;
200 }
201 OHOS::NetsysNative::NetDiagPingOption pingOption;
202 pingOption.destination_ = NetDiagGetString(STR_LEN);
203 pingOption.source_ = NetDiagGetString(STR_LEN);
204 pingOption.count_ = NetDiagGetData<int16_t>();
205 pingOption.dataSize_ = NetDiagGetData<int16_t>();
206 pingOption.mark_ = NetDiagGetData<int16_t>();
207 pingOption.ttl_ = NetDiagGetData<int16_t>();
208 pingOption.timeOut_ = NetDiagGetData<int16_t>();
209 pingOption.duration_ = NetDiagGetData<int16_t>();
210 pingOption.flood_ = NetDiagGetData<int16_t>() % numberTow == 0;
211
212 if (!pingOption.Marshalling(dataParcel)) {
213 return;
214 }
215
216 sptr<NetsysNative::NetDiagCallbackStubTest> callBack = new NetsysNative::NetDiagCallbackStubTest();
217 if (!dataParcel.WriteRemoteObject(callBack->AsObject().GetRefPtr())) {
218 return;
219 }
220
221 g_isWaitAsync = true;
222 OnRemoteRequest(static_cast<uint32_t>(NetsysNative::NetsysInterfaceCode::NETSYS_NETDIAG_PING_HOST), dataParcel);
223 std::chrono::steady_clock::time_point tp1 = std::chrono::steady_clock::now();
224 while (g_isWaitAsync) {
225 std::this_thread::sleep_for(std::chrono::seconds(1));
226 std::chrono::steady_clock::time_point tp2 = std::chrono::steady_clock::now();
227 if (std::chrono::duration_cast<std::chrono::seconds>(tp2 - tp1).count() > maxWaitSecond) {
228 break;
229 }
230 }
231 }
232 } // namespace NetManagerStandard
233 } // namespace OHOS
234
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)235 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
236 {
237 /* Run your code on data */
238 OHOS::NetManagerStandard::NetDiagGetSocketInfoFuzzTest(data, size);
239 OHOS::NetManagerStandard::NetDiagGetRouteTableFuzzTest(data, size);
240 OHOS::NetManagerStandard::NetDiagUpdateInterfaceConfigFuzzTest(data, size);
241 OHOS::NetManagerStandard::NetDiagSetInterfaceActiveFuzzTest(data, size);
242 OHOS::NetManagerStandard::NetDiagGetInterfaceConfigFuzzTest(data, size);
243 OHOS::NetManagerStandard::NetDiagPingFuzzTest(data, size);
244 return 0;
245 }