• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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