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 <cstring>
17 #include <map>
18 #include <securec.h>
19 #include <string>
20 #include <vector>
21
22 #include <csignal>
23 #include <cstring>
24 #include <functional>
25 #include <iostream>
26
27 #include "net_websocket.h"
28 #include "netstack_log.h"
29 #include "secure_char.h"
30
31 namespace OHOS {
32 namespace NetStack {
33 namespace WebSocketClient {
34 const uint8_t *g_baseFuzzData = nullptr;
35 size_t g_baseFuzzSize = 0;
36 size_t g_baseFuzzPos = 0;
37 constexpr size_t STR_LEN = 255;
38 const int32_t LWS_CLOSE_STATUS_NORMAL = 1000;
GetData()39 template <class T> T GetData()
40 {
41 T object{};
42 size_t objectSize = sizeof(object);
43 if (g_baseFuzzData == nullptr || g_baseFuzzSize <= g_baseFuzzPos || objectSize > g_baseFuzzSize - g_baseFuzzPos) {
44 return object;
45 }
46 errno_t ret = memcpy_s(&object, objectSize, g_baseFuzzData + g_baseFuzzPos, objectSize);
47 if (ret != EOK) {
48 return object;
49 }
50 g_baseFuzzPos += objectSize;
51 return object;
52 }
53
SetGlobalFuzzData(const uint8_t * data,size_t size)54 void SetGlobalFuzzData(const uint8_t *data, size_t size)
55 {
56 g_baseFuzzData = data;
57 g_baseFuzzSize = size;
58 g_baseFuzzPos = 0;
59 }
60
GetStringFromData(int strlen)61 std::string GetStringFromData(int strlen)
62 {
63 if (strlen < 1) {
64 return "";
65 }
66
67 char cstr[strlen];
68 cstr[strlen - 1] = '\0';
69 for (int i = 0; i < strlen - 1; i++) {
70 cstr[i] = GetData<char>();
71 }
72 std::string str(cstr);
73 return str;
74 }
75
SetAddHeaderTest(const uint8_t * data,size_t size)76 void SetAddHeaderTest(const uint8_t *data, size_t size)
77 {
78 if ((data == nullptr) || (size < 1)) {
79 return;
80 }
81 SetGlobalFuzzData(data, size);
82 std::string str = GetStringFromData(STR_LEN);
83 struct WebSocket *client = nullptr;
84 struct WebSocket_Header header1;
85 header1.fieldName = str.c_str();
86 header1.fieldValue = str.c_str();
87 header1.next = nullptr;
88 OH_WebSocketClient_AddHeader(client, header1);
89 }
90
SetRequestOptionsTest(const uint8_t * data,size_t size)91 void SetRequestOptionsTest(const uint8_t *data, size_t size)
92 {
93 if ((data == nullptr) || (size < 1)) {
94 return;
95 }
96 SetGlobalFuzzData(data, size);
97 struct WebSocket *client = new WebSocket();
98 const char *url1 = "www.baidu.com";
99
100 OH_WebSocketClient_Connect(client, url1, client->requestOptions);
101 }
102
SetConnectUrlTest(const uint8_t * data,size_t size)103 void SetConnectUrlTest(const uint8_t *data, size_t size)
104 {
105 if ((data == nullptr) || (size < 1)) {
106 return;
107 }
108 SetGlobalFuzzData(data, size);
109 std::string str = GetStringFromData(STR_LEN);
110 struct WebSocket *client = new WebSocket();
111 const char *url1 = str.c_str();
112 OH_WebSocketClient_Connect(client, url1, client->requestOptions);
113 }
114
SetSendDataTest(const uint8_t * data,size_t size)115 void SetSendDataTest(const uint8_t *data, size_t size)
116 {
117 if ((data == nullptr) || (size < 1)) {
118 return;
119 }
120 SetGlobalFuzzData(data, size);
121 struct WebSocket *client = new WebSocket();
122 const char *senddata = "Hello, world,websocket!";
123 int32_t sendLength = std::strlen(senddata);
124 OH_WebSocketClient_Send(client, const_cast<char *>(senddata), sendLength);
125 }
126
SetSendDataLengthTest(const uint8_t * data,size_t size)127 void SetSendDataLengthTest(const uint8_t *data, size_t size)
128 {
129 if ((data == nullptr) || (size < 1)) {
130 return;
131 }
132 SetGlobalFuzzData(data, size);
133 struct WebSocket *client = new WebSocket();
134 const char *senddata = "Hello, world,websocket!";
135 int32_t sendLength = size;
136 OH_WebSocketClient_Send(client, const_cast<char *>(senddata), sendLength);
137 }
138
SetCloseOptionTest(const uint8_t * data,size_t size)139 void SetCloseOptionTest(const uint8_t *data, size_t size)
140 {
141 if ((data == nullptr) || (size < 1)) {
142 return;
143 }
144 SetGlobalFuzzData(data, size);
145 struct WebSocket *client = new WebSocket();
146
147 struct WebSocket_CloseOption CloseOption;
148 CloseOption.code = LWS_CLOSE_STATUS_NORMAL;
149 CloseOption.reason = " ";
150 OH_WebSocketClient_Close(client, CloseOption);
151 }
152
153 } // namespace WebSocketClient
154 } // namespace NetStack
155 } // namespace OHOS
156
157 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)158 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
159 {
160 /* Run your code on data */
161 OHOS::NetStack::WebSocketClient::SetAddHeaderTest(data, size);
162 OHOS::NetStack::WebSocketClient::SetRequestOptionsTest(data, size);
163 OHOS::NetStack::WebSocketClient::SetConnectUrlTest(data, size);
164 OHOS::NetStack::WebSocketClient::SetSendDataTest(data, size);
165 OHOS::NetStack::WebSocketClient::SetSendDataLengthTest(data, size);
166 OHOS::NetStack::WebSocketClient::SetCloseOptionTest(data, size);
167 return 0;
168 }