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 "dschedsoftbussession_fuzzer.h"
17
18 #include <cstddef>
19 #include <cstdint>
20 #include <fuzzer/FuzzedDataProvider.h>
21 #include <securec.h>
22
23 #include "dsched_data_buffer.h"
24 #include "dsched_softbus_session.h"
25
26 namespace OHOS {
27 namespace DistributedSchedule {
28 namespace {
29 constexpr size_t FOO_MAX_LEN = 1024;
30 constexpr size_t U32_AT_SIZE = 4;
31 constexpr int32_t POS_0 = 0;
32 constexpr int32_t POS_1 = 1;
33 constexpr int32_t POS_2 = 2;
34 constexpr int32_t POS_3 = 3;
35 constexpr int32_t OFFSET_24 = 24;
36 constexpr int32_t OFFSET_16 = 16;
37 constexpr int32_t OFFSET_8 = 8;
38 constexpr int32_t MAX_DATALEN = 2048;
39 constexpr int32_t MAX_FDP_RANGE = 1024;
40 constexpr size_t MIN_FRAG_BUFFER_SIZE = 16;
41 constexpr size_t MIN_NO_FRAG_BUFFER_SIZE = 8;
42 constexpr size_t MIN_NO_FRAG_BUF_SIZE = 8;
43 constexpr size_t MAX_NO_FRAG_BUF_SIZE = 256;
44 constexpr size_t MIN_FRAG_BUF_SIZE = 16;
45 constexpr size_t MAX_FRAG_BUF_SIZE = 512;
46 constexpr uint8_t MIN_FRAG_FLAG = 0;
47 constexpr uint8_t MAX_FRAG_FLAG = 3;
48 constexpr uint32_t MIN_DATA_LEN = 0;
49 constexpr int32_t TOTAL_LEN_MULTIPLIER = 2;
50
51
ConsumeDataLen(FuzzedDataProvider & fdp)52 inline uint32_t ConsumeDataLen(FuzzedDataProvider& fdp)
53 {
54 return fdp.ConsumeIntegralInRange<uint32_t>(1, MAX_FDP_RANGE);
55 }
56
ConsumeTotalLen(FuzzedDataProvider & fdp,uint32_t dataLen)57 inline uint32_t ConsumeTotalLen(FuzzedDataProvider& fdp, uint32_t dataLen)
58 {
59 return fdp.ConsumeIntegralInRange<uint32_t>(dataLen, MAX_DATALEN);
60 }
61
ConsumeSessionTotalLen(FuzzedDataProvider & fdp,uint32_t dataLen)62 inline uint32_t ConsumeSessionTotalLen(FuzzedDataProvider& fdp, uint32_t dataLen)
63 {
64 return fdp.ConsumeIntegralInRange<uint32_t>(dataLen, MAX_DATALEN);
65 }
66 }
67
Get32Data(const uint8_t * ptr,size_t size)68 int32_t Get32Data(const uint8_t* ptr, size_t size)
69 {
70 if (size > FOO_MAX_LEN || size < U32_AT_SIZE) {
71 return 0;
72 }
73 char *ch = static_cast<char*>(malloc(size + 1));
74 if (ch == nullptr) {
75 return 0;
76 }
77 (void)memset_s(ch, size + 1, 0x00, size + 1);
78 if (memcpy_s(ch, size + 1, ptr, size) != EOK) {
79 free(ch);
80 ch = nullptr;
81 return 0;
82 }
83 int32_t data = (ch[POS_0] << OFFSET_24) | (ch[POS_1] << OFFSET_16) | (ch[POS_2] << OFFSET_8) | ch[POS_3];
84 free(ch);
85 ch = nullptr;
86 return data;
87 }
88
FuzzOnBytesReceived(const uint8_t * data,size_t size)89 void FuzzOnBytesReceived(const uint8_t* data, size_t size)
90 {
91 if ((data == nullptr) || (size < U32_AT_SIZE)) {
92 return;
93 }
94 FuzzedDataProvider fdp(data, size);
95
96 size_t bufSize = fdp.ConsumeIntegralInRange<size_t>(MIN_FRAG_BUF_SIZE, MAX_FRAG_BUF_SIZE);
97 std::shared_ptr<DSchedDataBuffer> buffer = std::make_shared<DSchedDataBuffer>(bufSize);
98 std::vector<uint8_t> bufContent = fdp.ConsumeBytes<uint8_t>(bufSize);
99 if (memcpy_s(buffer->Data(), bufSize, bufContent.data(), bufContent.size()) != EOK) {
100 return;
101 }
102 DSchedSoftbusSession dschedSoftbusSession;
103 dschedSoftbusSession.OnBytesReceived(buffer);
104 dschedSoftbusSession.OnConnect();
105 dschedSoftbusSession.GetPeerDeviceId();
106 int32_t dataType = Get32Data(data, size);
107 dschedSoftbusSession.SendData(buffer, dataType);
108 dschedSoftbusSession.OnDisconnect();
109 }
110
FuzzAssembleNoFrag(const uint8_t * data,size_t size)111 void FuzzAssembleNoFrag(const uint8_t* data, size_t size)
112 {
113 if ((data == nullptr) || (size < U32_AT_SIZE)) {
114 return;
115 }
116 FuzzedDataProvider fdp(data, size);
117
118 size_t bufSize = fdp.ConsumeIntegralInRange<size_t>(MIN_FRAG_BUF_SIZE, MAX_FRAG_BUF_SIZE);
119 std::shared_ptr<DSchedDataBuffer> buffer = std::make_shared<DSchedDataBuffer>(bufSize);
120 std::vector<uint8_t> bufContent = fdp.ConsumeBytes<uint8_t>(bufSize);
121 if (memcpy_s(buffer->Data(), bufSize, bufContent.data(), bufContent.size()) != EOK) {
122 return;
123 }
124 int32_t accountId = fdp.ConsumeIntegral<int32_t>();
125 DSchedSoftbusSession dschedSoftbusSession;
126 dschedSoftbusSession.ResetAssembleFrag();
127
128 dschedSoftbusSession.UnPackSendData(buffer, accountId);
129 dschedSoftbusSession.UnPackStartEndData(buffer, accountId);
130 }
131
FuzzDSchedSoftbusSessionConstructor(const uint8_t * data,size_t size)132 void FuzzDSchedSoftbusSessionConstructor(const uint8_t* data, size_t size)
133 {
134 if ((data == nullptr) || (size < U32_AT_SIZE)) {
135 return;
136 }
137 FuzzedDataProvider fdp(data, size);
138 SessionInfo sessionInfo;
139 sessionInfo.sessionId = fdp.ConsumeIntegral<int32_t>();
140 sessionInfo.myDeviceId = fdp.ConsumeRandomLengthString();
141 sessionInfo.peerDeviceId = fdp.ConsumeRandomLengthString();
142 sessionInfo.sessionName = fdp.ConsumeRandomLengthString();
143 sessionInfo.isServer = fdp.ConsumeBool();
144
145 DSchedSoftbusSession dschedSoftbusSession(sessionInfo);
146 dschedSoftbusSession.OnConnect();
147 dschedSoftbusSession.OnDisconnect();
148 dschedSoftbusSession.GetPeerDeviceId();
149 }
150
FuzzCheckUnPackBuffer(const uint8_t * data,size_t size)151 void FuzzCheckUnPackBuffer(const uint8_t* data, size_t size)
152 {
153 if ((data == nullptr) || (size < U32_AT_SIZE)) {
154 return;
155 }
156 FuzzedDataProvider fdp(data, size);
157
158 DSchedSoftbusSession::SessionDataHeader headerPara;
159 headerPara.seqNum = fdp.ConsumeIntegral<uint32_t>();
160 headerPara.subSeq = fdp.ConsumeIntegral<uint16_t>();
161 headerPara.dataLen = ConsumeDataLen(fdp);
162 headerPara.totalLen = ConsumeTotalLen(fdp, headerPara.dataLen);
163
164 DSchedSoftbusSession dschedSoftbusSession;
165
166 dschedSoftbusSession.isWaiting_ = fdp.ConsumeBool();
167 dschedSoftbusSession.nowSeq_ = fdp.ConsumeIntegral<uint32_t>();
168 dschedSoftbusSession.nowSubSeq_ = fdp.ConsumeIntegral<uint16_t>();
169 dschedSoftbusSession.totalLen_ = ConsumeSessionTotalLen(fdp, headerPara.dataLen);
170 dschedSoftbusSession.offset_ = fdp.ConsumeIntegralInRange<uint32_t>(0, dschedSoftbusSession.totalLen_);
171
172 dschedSoftbusSession.CheckUnPackBuffer(headerPara);
173 }
174
AssembleNoFragFuzzTest(const uint8_t * data,size_t size)175 void AssembleNoFragFuzzTest(const uint8_t* data, size_t size)
176 {
177 if (!data || size < MIN_NO_FRAG_BUFFER_SIZE) {
178 return;
179 }
180 FuzzedDataProvider fdp(data, size);
181
182 size_t bufSize = fdp.ConsumeIntegralInRange<size_t>(MIN_NO_FRAG_BUF_SIZE, MAX_NO_FRAG_BUF_SIZE);
183 std::shared_ptr<DSchedDataBuffer> buffer = std::make_shared<DSchedDataBuffer>(bufSize);
184 std::vector<uint8_t> bufContent = fdp.ConsumeBytes<uint8_t>(bufSize);
185 if (memcpy_s(buffer->Data(), bufSize, bufContent.data(), bufContent.size()) != EOK) {
186 return;
187 }
188
189 DSchedSoftbusSession::SessionDataHeader headerPara;
190 headerPara.dataLen = fdp.ConsumeIntegralInRange<uint32_t>(MIN_DATA_LEN, bufSize);
191 headerPara.totalLen = headerPara.dataLen;
192 headerPara.dataType = fdp.ConsumeIntegral<uint32_t>();
193
194 DSchedSoftbusSession session;
195 session.AssembleNoFrag(buffer, headerPara);
196 }
197
AssembleFragFuzzTest(const uint8_t * data,size_t size)198 void AssembleFragFuzzTest(const uint8_t* data, size_t size)
199 {
200 if (!data || size < MIN_FRAG_BUFFER_SIZE) {
201 return;
202 }
203 FuzzedDataProvider fdp(data, size);
204
205 size_t bufSize = fdp.ConsumeIntegralInRange<size_t>(MIN_FRAG_BUF_SIZE, MAX_FRAG_BUF_SIZE);
206 std::shared_ptr<DSchedDataBuffer> buffer = std::make_shared<DSchedDataBuffer>(bufSize);
207 std::vector<uint8_t> bufContent = fdp.ConsumeBytes<uint8_t>(bufSize);
208 if (memcpy_s(buffer->Data(), bufSize, bufContent.data(), bufContent.size()) != EOK) {
209 return;
210 }
211 DSchedSoftbusSession::SessionDataHeader headerPara;
212 headerPara.fragFlag = fdp.ConsumeIntegralInRange<uint8_t>(MIN_FRAG_FLAG, MAX_FRAG_FLAG);
213 headerPara.seqNum = fdp.ConsumeIntegral<uint32_t>();
214 headerPara.subSeq = fdp.ConsumeIntegral<uint16_t>();
215 headerPara.dataLen = fdp.ConsumeIntegralInRange<uint32_t>(MIN_DATA_LEN, bufSize);
216 headerPara.totalLen = fdp.ConsumeIntegralInRange<uint32_t>(headerPara.dataLen, bufSize * TOTAL_LEN_MULTIPLIER);
217 headerPara.dataType = fdp.ConsumeIntegral<uint32_t>();
218
219 DSchedSoftbusSession session;
220 session.AssembleFrag(buffer, headerPara);
221 }
222 }
223 }
224
225 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)226 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
227 {
228 OHOS::DistributedSchedule::FuzzOnBytesReceived(data, size);
229 OHOS::DistributedSchedule::FuzzAssembleNoFrag(data, size);
230 OHOS::DistributedSchedule::FuzzDSchedSoftbusSessionConstructor(data, size);
231 OHOS::DistributedSchedule::FuzzCheckUnPackBuffer(data, size);
232 OHOS::DistributedSchedule::AssembleNoFragFuzzTest(data, size);
233 OHOS::DistributedSchedule::AssembleFragFuzzTest(data, size);
234 return 0;
235 }
236