1 /*
2 * Copyright (c) 2023-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 "vpnclient_fuzzer.h"
17
18 #include <cstddef>
19 #include <cstdint>
20 #include <securec.h>
21
22 #include "i_vpn_event_callback.h"
23 #include "netmanager_ext_test_security.h"
24 #include "networkvpn_service.h"
25 #include "refbase.h"
26
27 namespace OHOS {
28 namespace NetManagerStandard {
29 namespace {
30
31 constexpr size_t STR_LEN = 16;
32
33 size_t g_baseFuzzPos = 0;
34 size_t g_baseFuzzSize = 0;
35 const uint8_t *g_baseFuzzData = nullptr;
36 } // namespace
37
InitGlobalData(const uint8_t * data,size_t size)38 bool InitGlobalData(const uint8_t *data, size_t size)
39 {
40 if (data == nullptr || size == 0) {
41 return false;
42 }
43 g_baseFuzzPos = 0;
44 g_baseFuzzSize = size;
45 g_baseFuzzData = data;
46 return true;
47 }
48
GetData()49 template <class T> T GetData()
50 {
51 T object{};
52 size_t objectSize = sizeof(object);
53 if (g_baseFuzzData == nullptr || objectSize > g_baseFuzzSize - g_baseFuzzPos) {
54 return object;
55 }
56 errno_t ret = memcpy_s(&object, objectSize, g_baseFuzzData + g_baseFuzzPos, objectSize);
57 if (ret != EOK) {
58 return {};
59 }
60 g_baseFuzzPos += objectSize;
61 return object;
62 }
63
GetStringData()64 std::string GetStringData()
65 {
66 char cstr[STR_LEN] = {0};
67 for (uint32_t i = 0; i < STR_LEN - 1; i++) {
68 cstr[i] = GetData<char>();
69 }
70 return std::string(cstr);
71 }
72
GetAddressData()73 INetAddr GetAddressData()
74 {
75 INetAddr netAddr;
76 netAddr.type_ = GetData<uint8_t>();
77 netAddr.family_ = GetData<uint8_t>();
78 netAddr.prefixlen_ = GetData<uint8_t>();
79 netAddr.address_ = GetStringData();
80 netAddr.netMask_ = GetStringData();
81 netAddr.hostName_ = GetStringData();
82 netAddr.port_ = GetData<uint8_t>();
83 return netAddr;
84 }
85
GetRouteData()86 Route GetRouteData()
87 {
88 Route route;
89 route.iface_ = GetStringData();
90 route.destination_ = GetAddressData();
91 route.gateway_ = GetAddressData();
92 route.mtu_ = GetData<int32_t>();
93 route.isHost_ = GetData<bool>();
94 route.hasGateway_ = GetData<bool>();
95 route.isDefaultRoute_ = GetData<bool>();
96 return route;
97 }
98
99 class VpnEventCallbackTest : public IRemoteStub<IVpnEventCallback> {
100 public:
OnVpnStateChanged(const bool & isConnected)101 void OnVpnStateChanged(const bool &isConnected) override{};
OnVpnMultiUserSetUp()102 void OnVpnMultiUserSetUp() override{};
103 };
104
OnRemoteRequest(INetworkVpnService::MessageCode code,MessageParcel & data)105 __attribute__((no_sanitize("cfi"))) int32_t OnRemoteRequest(INetworkVpnService::MessageCode code, MessageParcel &data)
106 {
107 MessageParcel reply;
108 MessageOption option;
109 return DelayedSingleton<NetworkVpnService>::GetInstance()->OnRemoteRequest(static_cast<uint32_t>(code), data,
110 reply, option);
111 }
112
PrepareFuzzTest(const uint8_t * data,size_t size)113 void PrepareFuzzTest(const uint8_t *data, size_t size)
114 {
115 if (!InitGlobalData(data, size)) {
116 return;
117 }
118 NetManagerExtAccessToken token;
119 MessageParcel dataParcel;
120 if (!dataParcel.WriteInterfaceToken(NetworkVpnServiceStub::GetDescriptor())) {
121 return;
122 }
123 int32_t num = GetData<int32_t>();
124 if (!dataParcel.WriteInt32(num)) {
125 return;
126 }
127 OnRemoteRequest(INetworkVpnService::MessageCode::CMD_PREPARE, dataParcel);
128 }
129
ProtectFuzzTest(const uint8_t * data,size_t size)130 void ProtectFuzzTest(const uint8_t *data, size_t size)
131 {
132 if (!InitGlobalData(data, size)) {
133 return;
134 }
135 NetManagerExtAccessToken token;
136 MessageParcel dataParcel;
137 if (!dataParcel.WriteInterfaceToken(NetworkVpnServiceStub::GetDescriptor())) {
138 return;
139 }
140 int32_t num = GetData<int32_t>();
141 if (!dataParcel.WriteInt32(num)) {
142 return;
143 }
144 OnRemoteRequest(INetworkVpnService::MessageCode::CMD_PROTECT, dataParcel);
145 }
146
SetUpVpnFuzzTest(const uint8_t * data,size_t size)147 void SetUpVpnFuzzTest(const uint8_t *data, size_t size)
148 {
149 if (!InitGlobalData(data, size)) {
150 return;
151 }
152
153 NetManagerExtAccessToken token;
154 MessageParcel dataParcel;
155 if (!dataParcel.WriteInterfaceToken(NetworkVpnServiceStub::GetDescriptor())) {
156 return;
157 }
158 sptr<VpnConfig> config = new (std::nothrow) VpnConfig();
159 config->addresses_.emplace_back(GetAddressData());
160 config->routes_.emplace_back(GetRouteData());
161 config->mtu_ = GetData<int32_t>();
162 config->isAcceptIPv4_ = GetData<bool>();
163 config->isAcceptIPv6_ = GetData<bool>();
164 config->isLegacy_ = GetData<bool>();
165 config->isMetered_ = GetData<bool>();
166 config->isBlocking_ = GetData<bool>();
167 config->dnsAddresses_.emplace_back(GetStringData());
168 config->searchDomains_.emplace_back(GetStringData());
169 config->acceptedApplications_.emplace_back(GetStringData());
170 config->acceptedApplications_.emplace_back(GetStringData());
171 if (!config->Marshalling(dataParcel)) {
172 return;
173 }
174 OnRemoteRequest(INetworkVpnService::MessageCode::CMD_START_VPN, dataParcel);
175 }
176
DestroyVpnFuzzTest(const uint8_t * data,size_t size)177 void DestroyVpnFuzzTest(const uint8_t *data, size_t size)
178 {
179 if (!InitGlobalData(data, size)) {
180 return;
181 }
182 NetManagerExtAccessToken token;
183 MessageParcel dataParcel;
184 if (!dataParcel.WriteInterfaceToken(NetworkVpnServiceStub::GetDescriptor())) {
185 return;
186 }
187 int32_t num = GetData<int32_t>();
188 if (!dataParcel.WriteInt32(num)) {
189 return;
190 }
191 OnRemoteRequest(INetworkVpnService::MessageCode::CMD_STOP_VPN, dataParcel);
192 }
193
RegisterVpnEventFuzzTest(const uint8_t * data,size_t size)194 void RegisterVpnEventFuzzTest(const uint8_t *data, size_t size)
195 {
196 if (!InitGlobalData(data, size)) {
197 return;
198 }
199 NetManagerExtAccessToken token;
200 MessageParcel dataParcel;
201 if (!dataParcel.WriteInterfaceToken(NetworkVpnServiceStub::GetDescriptor())) {
202 return;
203 }
204
205 sptr<IVpnEventCallback> callback = new (std::nothrow) VpnEventCallbackTest();
206 if (callback == nullptr || !dataParcel.WriteRemoteObject(callback->AsObject().GetRefPtr())) {
207 return;
208 }
209 int32_t num = GetData<int32_t>();
210 if (!dataParcel.WriteInt32(num)) {
211 return;
212 }
213 OnRemoteRequest(INetworkVpnService::MessageCode::CMD_REGISTER_EVENT_CALLBACK, dataParcel);
214 }
215
UnregisterVpnEventFuzzTest(const uint8_t * data,size_t size)216 void UnregisterVpnEventFuzzTest(const uint8_t *data, size_t size)
217 {
218 if (!InitGlobalData(data, size)) {
219 return;
220 }
221 NetManagerExtAccessToken token;
222 MessageParcel dataParcel;
223 if (!dataParcel.WriteInterfaceToken(NetworkVpnServiceStub::GetDescriptor())) {
224 return;
225 }
226
227 sptr<IVpnEventCallback> callback = new (std::nothrow) VpnEventCallbackTest();
228 if (callback == nullptr || !dataParcel.WriteRemoteObject(callback->AsObject().GetRefPtr())) {
229 return;
230 }
231 int32_t num = GetData<int32_t>();
232 if (!dataParcel.WriteInt32(num)) {
233 return;
234 }
235 OnRemoteRequest(INetworkVpnService::MessageCode::CMD_UNREGISTER_EVENT_CALLBACK, dataParcel);
236 }
237 } // namespace NetManagerStandard
238 } // namespace OHOS
239
240 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)241 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
242 {
243 /* Run your code on data */
244 OHOS::NetManagerStandard::PrepareFuzzTest(data, size);
245 OHOS::NetManagerStandard::ProtectFuzzTest(data, size);
246 OHOS::NetManagerStandard::SetUpVpnFuzzTest(data, size);
247 OHOS::NetManagerStandard::DestroyVpnFuzzTest(data, size);
248 OHOS::NetManagerStandard::RegisterVpnEventFuzzTest(data, size);
249 OHOS::NetManagerStandard::UnregisterVpnEventFuzzTest(data, size);
250 return 0;
251 }
252