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 "softbusbroadcast_fuzzer.h"
17 #include "softbus_broadcast_manager.h"
18
19 #include <cstddef>
20 #include <securec.h>
21
22 #include "softbus_adapter_mem.h"
23 #include "softbus_errcode.h"
24
25 #define MIN_DATA_LEN 50
26
27 #define BC_INTERNAL 48
28 #define BC_ADV_TX_POWER_DEFAULT (-6)
29 #define SERVICE_UUID 0xFDEE
30 #define BC_ADV_FLAG 0x2
31 #define MANUFACTURE_COMPANY_ID 0x027D
32 #define ADV_DATA_MAX_LEN 24
33 #define RESP_DATA_MAX_LEN 26
34 #define BROADCAST_MAX_LEN (ADV_DATA_MAX_LEN + RESP_DATA_MAX_LEN)
35
36 namespace OHOS {
37
38 const uint8_t *BASE_FUZZ_DATA = nullptr;
39 size_t g_baseFuzzSize = 0;
40 size_t g_baseFuzzPos;
41
GetData()42 template <class T> T GetData()
43 {
44 T object{};
45 size_t objectSize = sizeof(object);
46 if (BASE_FUZZ_DATA == nullptr || objectSize > g_baseFuzzSize - g_baseFuzzPos) {
47 return object;
48 }
49 errno_t ret = memcpy_s(&object, objectSize, BASE_FUZZ_DATA + g_baseFuzzPos, objectSize);
50 if (ret != EOK) {
51 return {};
52 }
53 g_baseFuzzPos += objectSize;
54 return object;
55 }
56
BuildBroadcastParam(const uint8_t * data,size_t size,BroadcastParam * param)57 static int32_t BuildBroadcastParam(const uint8_t* data, size_t size, BroadcastParam *param)
58 {
59 g_baseFuzzPos = 0;
60 param->minInterval = GetData<int32_t>() % BC_INTERNAL;
61 param->maxInterval = GetData<int32_t>() % BC_INTERNAL;
62 param->advType = GetData<uint8_t>() % SOFTBUS_BC_ADV_DIRECT_IND_LOW;
63 param->ownAddrType = GetData<uint8_t>() % SOFTBUS_BC_RANDOM_STATIC_IDENTITY_ADDRESS;
64 param->peerAddrType = GetData<uint8_t>() % SOFTBUS_BC_RANDOM_STATIC_IDENTITY_ADDRESS;
65 param->channelMap = GetData<int32_t>();
66 param->txPower = BC_ADV_TX_POWER_DEFAULT;
67 param->advFilterPolicy = GetData<uint8_t>();
68 param->isSupportRpa = GetData<bool>();
69 param->duration = GetData<int32_t>();
70
71 if (memcpy_s(param->ownIrk, BC_IRK_LEN, data, BC_IRK_LEN) != EOK) {
72 return SOFTBUS_MEM_ERR;
73 }
74 if (memcpy_s(param->ownUdidHash, BC_UDID_HASH_LEN, data, BC_UDID_HASH_LEN) != EOK) {
75 return SOFTBUS_MEM_ERR;
76 }
77 return SOFTBUS_OK;
78 }
79
DestroyBleConfigAdvData(BroadcastPacket * packet)80 static void DestroyBleConfigAdvData(BroadcastPacket *packet)
81 {
82 SoftBusFree(packet->bcData.payload);
83 SoftBusFree(packet->rspData.payload);
84 packet->bcData.payload = nullptr;
85 packet->rspData.payload = nullptr;
86 }
87
BuildBroadcastPacket(const uint8_t * data,size_t size,BroadcastPacket * packet)88 static int32_t BuildBroadcastPacket(const uint8_t* data, size_t size, BroadcastPacket *packet)
89 {
90 packet->isSupportFlag = true;
91 packet->flag = BC_ADV_FLAG;
92 packet->bcData.type = BC_DATA_TYPE_SERVICE;
93 packet->bcData.id = SERVICE_UUID;
94 packet->rspData.type = BC_DATA_TYPE_MANUFACTURER;
95 packet->rspData.id = MANUFACTURE_COMPANY_ID;
96
97 packet->bcData.payload = (uint8_t *)SoftBusCalloc(ADV_DATA_MAX_LEN);
98 if (packet->bcData.payload == nullptr) {
99 return SOFTBUS_MALLOC_ERR;
100 }
101 packet->bcData.payloadLen = (size > ADV_DATA_MAX_LEN) ? ADV_DATA_MAX_LEN : size;
102 if (memcpy_s(packet->bcData.payload, ADV_DATA_MAX_LEN, data, packet->bcData.payloadLen) != EOK) {
103 SoftBusFree(packet->bcData.payload);
104 packet->rspData.payload = nullptr;
105 return SOFTBUS_MEM_ERR;
106 }
107
108 packet->rspData.payloadLen = (BROADCAST_MAX_LEN - packet->bcData.payloadLen > RESP_DATA_MAX_LEN) ?
109 RESP_DATA_MAX_LEN : (BROADCAST_MAX_LEN - packet->bcData.payloadLen);
110 if (packet->rspData.payloadLen == 0) {
111 packet->rspData.payload = nullptr;
112 return SOFTBUS_OK;
113 }
114 packet->rspData.payload = (uint8_t *)SoftBusCalloc(RESP_DATA_MAX_LEN);
115 if (packet->rspData.payload == nullptr) {
116 SoftBusFree(packet->bcData.payload);
117 packet->bcData.payload = nullptr;
118 return SOFTBUS_MALLOC_ERR;
119 }
120 if (memcpy_s(&packet->rspData.payload[0], RESP_DATA_MAX_LEN, data, packet->rspData.payloadLen) != EOK) {
121 DestroyBleConfigAdvData(packet);
122 return SOFTBUS_MEM_ERR;
123 }
124 return SOFTBUS_OK;
125 }
126
BuildScanParam(const uint8_t * data,size_t size)127 static BcScanParams BuildScanParam(const uint8_t* data, size_t size)
128 {
129 g_baseFuzzPos = 0;
130 BcScanParams scanParam;
131 scanParam.scanInterval = SOFTBUS_BC_SCAN_INTERVAL_P2;
132 scanParam.scanWindow = SOFTBUS_BC_SCAN_WINDOW_P2;
133 scanParam.scanType = GetData<bool>();
134 scanParam.scanPhy = GetData<uint8_t>() % SOFTBUS_BC_SCAN_PHY_CODED;
135 scanParam.scanFilterPolicy = GetData<uint8_t>() % SOFTBUS_BC_SCAN_FILTER_POLICY_ONLY_WHITE_LIST_AND_RPA;
136 return scanParam;
137 }
138
BuildLpBroadcastParam(const uint8_t * data,size_t size,LpBroadcastParam * lpBcParam)139 static int32_t BuildLpBroadcastParam(const uint8_t* data, size_t size, LpBroadcastParam *lpBcParam)
140 {
141 g_baseFuzzPos = 0;
142 lpBcParam->bcHandle = GetData<int32_t>();
143 int32_t ret = BuildBroadcastParam(data, size, &lpBcParam->bcParam);
144 if (ret != SOFTBUS_OK) {
145 return ret;
146 }
147 ret = BuildBroadcastPacket(data, size, &lpBcParam->packet);
148 if (ret != SOFTBUS_OK) {
149 return ret;
150 }
151
152 return SOFTBUS_OK;
153 }
154
BuildLpScanParam(const uint8_t * data,size_t size)155 static LpScanParam BuildLpScanParam(const uint8_t* data, size_t size)
156 {
157 LpScanParam lpScanParam;
158 lpScanParam.scanParam = BuildScanParam(data, size);
159
160 return lpScanParam;
161 }
162
BleAdvEnableCallback(int channel,int status)163 static void BleAdvEnableCallback(int channel, int status)
164 {
165 (void)channel;
166 (void)status;
167 }
168
BleAdvDisableCallback(int channel,int status)169 static void BleAdvDisableCallback(int channel, int status)
170 {
171 (void)channel;
172 (void)status;
173 }
174
BleAdvDataCallback(int channel,int status)175 static void BleAdvDataCallback(int channel, int status)
176 {
177 (void)channel;
178 (void)status;
179 }
180
BleAdvUpdateCallback(int channel,int status)181 static void BleAdvUpdateCallback(int channel, int status)
182 {
183 (void)channel;
184 (void)status;
185 }
186
187 static BroadcastCallback g_advCallback = {
188 .OnStartBroadcastingCallback = BleAdvEnableCallback,
189 .OnStopBroadcastingCallback = BleAdvDisableCallback,
190 .OnUpdateBroadcastingCallback = BleAdvUpdateCallback,
191 .OnSetBroadcastingCallback = BleAdvDataCallback,
192 };
193
BleOnScanStart(int listenerId,int status)194 static void BleOnScanStart(int listenerId, int status)
195 {
196 (void)listenerId;
197 (void)status;
198 }
199
BleOnScanStop(int listenerId,int status)200 static void BleOnScanStop(int listenerId, int status)
201 {
202 (void)listenerId;
203 (void)status;
204 }
205
BleScanResultCallback(int listenerId,const BroadcastReportInfo * reportInfo)206 static void BleScanResultCallback(int listenerId, const BroadcastReportInfo *reportInfo)
207 {
208 (void)listenerId;
209 (void)reportInfo;
210 }
211
212 static ScanCallback g_scanListener = {
213 .OnStartScanCallback = BleOnScanStart,
214 .OnStopScanCallback = BleOnScanStop,
215 .OnReportScanDataCallback = BleScanResultCallback,
216 };
217
StartBroadcastingFuzzTest(int32_t bcId,const uint8_t * data,size_t size)218 void StartBroadcastingFuzzTest(int32_t bcId, const uint8_t* data, size_t size)
219 {
220 BroadcastParam param;
221 BuildBroadcastParam(data, size, ¶m);
222 BroadcastPacket packet;
223 BuildBroadcastPacket(data, size, &packet);
224
225 StartBroadcasting(bcId, ¶m, &packet);
226 DestroyBleConfigAdvData(&packet);
227 }
228
UpdateBroadcastingFuzzTest(int32_t bcId,const uint8_t * data,size_t size)229 void UpdateBroadcastingFuzzTest(int32_t bcId, const uint8_t* data, size_t size)
230 {
231 BroadcastParam param;
232 BuildBroadcastParam(data, size, ¶m);
233 BroadcastPacket packet;
234 BuildBroadcastPacket(data, size, &packet);
235
236 UpdateBroadcasting(bcId, ¶m, &packet);
237 DestroyBleConfigAdvData(&packet);
238 }
239
SetBroadcastingDataFuzzTest(int32_t bcId,const uint8_t * data,size_t size)240 void SetBroadcastingDataFuzzTest(int32_t bcId, const uint8_t* data, size_t size)
241 {
242 BroadcastPacket packet;
243 BuildBroadcastPacket(data, size, &packet);
244
245 SetBroadcastingData(bcId, &packet);
246 DestroyBleConfigAdvData(&packet);
247 }
248
StopBroadcastingFuzzTest(int32_t bcId)249 void StopBroadcastingFuzzTest(int32_t bcId)
250 {
251 StopBroadcasting(bcId);
252 }
253
StartScanFuzzTest(int32_t listenerId,const uint8_t * data,size_t size)254 void StartScanFuzzTest(int32_t listenerId, const uint8_t* data, size_t size)
255 {
256 BcScanParams scanParam = BuildScanParam(data, size);
257
258 StartScan(listenerId, &scanParam);
259 }
260
StopScanFuzzTest(int32_t listenerId)261 void StopScanFuzzTest(int32_t listenerId)
262 {
263 StopScan(listenerId);
264 }
265
BroadcastSetAdvDeviceParamFuzzTest(int32_t listenerId,const uint8_t * data,size_t size)266 void BroadcastSetAdvDeviceParamFuzzTest(int32_t listenerId, const uint8_t* data, size_t size)
267 {
268 g_baseFuzzPos = 0;
269 uint8_t type = GetData<uint8_t>();
270 LpScanParam lpScanParam = BuildLpScanParam(data, size);
271 lpScanParam.listenerId = listenerId;
272 LpBroadcastParam lpBcParam;
273 BuildLpBroadcastParam(data, size, &lpBcParam);
274
275 BroadcastSetAdvDeviceParam(static_cast<LpServerType>(type), &lpBcParam, &lpScanParam);
276 DestroyBleConfigAdvData(&lpBcParam.packet);
277 }
278
BroadcastGetBroadcastHandleFuzzTest(int32_t bcId)279 void BroadcastGetBroadcastHandleFuzzTest(int32_t bcId)
280 {
281 g_baseFuzzPos = 0;
282 int32_t bcHandle = GetData<int32_t>();
283
284 BroadcastGetBroadcastHandle(bcId, &bcHandle);
285 }
286
BroadcastSetScanReportChannelToLpDeviceFuzzTest(int32_t listenerId)287 void BroadcastSetScanReportChannelToLpDeviceFuzzTest(int32_t listenerId)
288 {
289 g_baseFuzzPos = 0;
290 bool enable = GetData<bool>();
291
292 BroadcastSetScanReportChannelToLpDevice(listenerId, enable);
293 }
294
BroadcastSetLpAdvParamFuzzTest()295 void BroadcastSetLpAdvParamFuzzTest()
296 {
297 g_baseFuzzPos = 0;
298 int32_t duration = GetData<int32_t>();
299 int32_t maxExtAdvEvents = GetData<int32_t>();
300 int32_t window = GetData<int32_t>();
301 int32_t interval = GetData<int32_t>();
302 int32_t lpAdvBCHandle = GetData<int32_t>();
303
304 BroadcastSetLpAdvParam(duration, maxExtAdvEvents, window, interval, lpAdvBCHandle);
305 }
306
307 } // OHOS namespace
308
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)309 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
310 {
311 if (size < MIN_DATA_LEN) {
312 return 0;
313 }
314 OHOS::BASE_FUZZ_DATA = data;
315 OHOS::g_baseFuzzSize = size;
316
317 int32_t listenerId = -1;
318 int32_t bcId = -1;
319
320 InitBroadcastMgr();
321 RegisterBroadcaster(SRV_TYPE_DIS, &bcId, &OHOS::g_advCallback);
322 RegisterScanListener(SRV_TYPE_DIS, &listenerId, &OHOS::g_scanListener);
323
324 OHOS::StartBroadcastingFuzzTest(bcId, data, size);
325 OHOS::UpdateBroadcastingFuzzTest(bcId, data, size);
326 OHOS::SetBroadcastingDataFuzzTest(bcId, data, size);
327 OHOS::StopBroadcastingFuzzTest(bcId);
328 OHOS::StartScanFuzzTest(listenerId, data, size);
329 OHOS::StopScanFuzzTest(listenerId);
330 OHOS::BroadcastSetAdvDeviceParamFuzzTest(listenerId, data, size);
331 OHOS::BroadcastGetBroadcastHandleFuzzTest(bcId);
332 OHOS::BroadcastSetScanReportChannelToLpDeviceFuzzTest(listenerId);
333 OHOS::BroadcastSetLpAdvParamFuzzTest();
334
335 UnRegisterScanListener(listenerId);
336 UnRegisterBroadcaster(bcId);
337 DeInitBroadcastMgr();
338 return 0;
339 }
340