1 /*
2  * Copyright (c) 2023 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 "softbussocketrecv_fuzzer.h"
17 
18 #include <cstddef>
19 #include <cstdint>
20 #include <securec.h>
21 
22 #include "comm_log.h"
23 #include "softbus_adapter_socket.h"
24 #include "softbus_adapter_define.h"
25 #include "softbus_adapter_mem.h"
26 
27 namespace OHOS {
28 const int PROTOCOL_MAXLEN = 100;
29 
30 struct SocketProtocol {
31     unsigned int cmd;
32     char data[PROTOCOL_MAXLEN];
33 };
34 
35 const uint8_t *g_baseFuzzData = nullptr;
36 size_t g_baseFuzzSize = 0;
37 size_t g_baseFuzzPos;
38 
GetData()39 template <class T> T GetData()
40 {
41     T objetct{};
42     size_t objetctSize = sizeof(objetct);
43     if (g_baseFuzzData == nullptr || objetctSize > g_baseFuzzSize - g_baseFuzzPos) {
44         COMM_LOGE(COMM_TEST, "data Invalid");
45         return objetct;
46     }
47     errno_t ret = memcpy_s(&objetct, objetctSize, g_baseFuzzData + g_baseFuzzPos, objetctSize);
48     if (ret != EOK) {
49         COMM_LOGE(COMM_TEST, "memcpy err");
50         return {};
51     }
52     g_baseFuzzPos += objetctSize;
53     return objetct;
54 }
55 
SoftBusSocketRecvFuzzTest(const uint8_t * data,size_t size)56 void SoftBusSocketRecvFuzzTest(const uint8_t* data, size_t size)
57 {
58     if (data == nullptr || size < sizeof(int32_t)) {
59         COMM_LOGE(COMM_TEST, "Invalid param");
60         return;
61     }
62 
63     g_baseFuzzSize = size;
64     g_baseFuzzData = data;
65     g_baseFuzzPos = 0;
66     struct SocketProtocol buf;
67     memset_s(&buf, sizeof(struct SocketProtocol), 0, sizeof(struct SocketProtocol));
68     int32_t socketFd = GetData<int32_t>();
69     uint32_t len = GetData<uint32_t>();
70     int32_t flags = GetData<int32_t>();
71     SoftBusSocketRecv(socketFd, &buf, len, flags);
72     return;
73 }
74 
SoftBusSocketRecvFromFuzzTest(const uint8_t * data,size_t size)75 void SoftBusSocketRecvFromFuzzTest(const uint8_t* data, size_t size)
76 {
77     if (data == nullptr || size < sizeof(int32_t)) {
78         COMM_LOGE(COMM_TEST, "Invalid param");
79         return;
80     }
81 
82     g_baseFuzzSize = size;
83     g_baseFuzzData = data;
84     g_baseFuzzPos = 0;
85     struct SocketProtocol buf;
86     memset_s(&buf, sizeof(struct SocketProtocol), 0, sizeof(struct SocketProtocol));
87     int32_t socketFd = GetData<int32_t>();
88     uint32_t len = GetData<uint32_t>();
89     int32_t flags = GetData<int32_t>();
90     SoftBusSockAddr  fromAddr;
91     memset_s(&fromAddr, sizeof(SoftBusSockAddr), 0, sizeof(SoftBusSockAddr));
92     int32_t fromAddrLen;
93     SoftBusSocketRecvFrom(socketFd, &buf, len, flags, &fromAddr, &fromAddrLen);
94     return;
95 }
96 
SoftBusSocketSendFuzzTest(const uint8_t * data,size_t size)97 void SoftBusSocketSendFuzzTest(const uint8_t* data, size_t size)
98 {
99     if (data == nullptr || size < sizeof(int32_t)) {
100         COMM_LOGE(COMM_TEST, "Invalid param");
101         return;
102     }
103 
104     g_baseFuzzSize = size;
105     g_baseFuzzData = data;
106     g_baseFuzzPos = 0;
107     uint8_t *buf = static_cast<uint8_t*>(SoftBusCalloc(size * sizeof(uint8_t)));
108     if (buf == nullptr) {
109         COMM_LOGE(COMM_TEST, "calloc faild");
110         return;
111     }
112     if (memcpy_s(buf, size, data, size) != EOK) {
113         COMM_LOGE(COMM_TEST, "memcpy err");
114         SoftBusFree(buf);
115         return;
116     }
117     int32_t socketFd = GetData<int32_t>();
118     uint32_t len = size;
119     int32_t flags = GetData<int32_t>();
120 
121     SoftBusSocketSend(socketFd, buf, len, flags);
122     SoftBusFree(buf);
123     return;
124 }
125 
SoftBusSocketSendToFuzzTest(const uint8_t * data,size_t size)126 void SoftBusSocketSendToFuzzTest(const uint8_t* data, size_t size)
127 {
128     if (data == nullptr || size < sizeof(SoftBusSockAddr)) {
129         COMM_LOGE(COMM_TEST, "Invalid param");
130         return;
131     }
132 
133     g_baseFuzzSize = size;
134     g_baseFuzzData = data;
135     g_baseFuzzPos = 0;
136     uint8_t *buf = static_cast<uint8_t*>(SoftBusCalloc(size * sizeof(uint8_t)));
137     if (buf == nullptr) {
138         COMM_LOGE(COMM_TEST, "calloc faild");
139         return;
140     }
141     if (memcpy_s(buf, size, data, size) != EOK) {
142         SoftBusFree(buf);
143         return;
144     }
145     int32_t socketFd = GetData<int32_t>();
146     uint32_t len = size;
147     int32_t flags = GetData<int32_t>();
148     SoftBusSockAddr toAddr = {0};
149     if (memcpy_s(&toAddr, sizeof(SoftBusSockAddr), data, sizeof(SoftBusSockAddr)) != EOK) {
150         COMM_LOGE(COMM_TEST, "memcpy err");
151         SoftBusFree(buf);
152         return;
153     }
154     int32_t toAddrLen = GetData<int32_t>();
155     SoftBusSocketSendTo(socketFd, buf, len, flags, &toAddr, toAddrLen);
156     SoftBusFree(buf);
157     return;
158 }
159 
160 }
161 
162 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)163 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
164 {
165     /* Run your code on data */
166     OHOS::SoftBusSocketRecvFuzzTest(data, size);
167     OHOS::SoftBusSocketRecvFromFuzzTest(data, size);
168     OHOS::SoftBusSocketSendFuzzTest(data, size);
169     OHOS::SoftBusSocketSendToFuzzTest(data, size);
170     return 0;
171 }