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, &param);
222     BroadcastPacket packet;
223     BuildBroadcastPacket(data, size, &packet);
224 
225     StartBroadcasting(bcId, &param, &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, &param);
233     BroadcastPacket packet;
234     BuildBroadcastPacket(data, size, &packet);
235 
236     UpdateBroadcasting(bcId, &param, &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