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 OH_WebSocketClient_Connect(client, str.c_str(), client->requestOptions);
112 }
113
SetSendDataTest(const uint8_t * data,size_t size)114 void SetSendDataTest(const uint8_t *data, size_t size)
115 {
116 if ((data == nullptr) || (size < 1)) {
117 return;
118 }
119 SetGlobalFuzzData(data, size);
120 struct WebSocket *client = new WebSocket();
121 const char *senddata = "Hello, world,websocket!";
122 int32_t sendLength = std::strlen(senddata);
123 OH_WebSocketClient_Send(client, const_cast<char *>(senddata), sendLength);
124 }
125
SetSendDataLengthTest(const uint8_t * data,size_t size)126 void SetSendDataLengthTest(const uint8_t *data, size_t size)
127 {
128 if ((data == nullptr) || (size < 1)) {
129 return;
130 }
131 SetGlobalFuzzData(data, size);
132 struct WebSocket *client = new WebSocket();
133 const char *senddata = "Hello, world,websocket!";
134 int32_t sendLength = size;
135 OH_WebSocketClient_Send(client, const_cast<char *>(senddata), sendLength);
136 }
137
SetCloseOptionTest(const uint8_t * data,size_t size)138 void SetCloseOptionTest(const uint8_t *data, size_t size)
139 {
140 if ((data == nullptr) || (size < 1)) {
141 return;
142 }
143 SetGlobalFuzzData(data, size);
144 struct WebSocket *client = new WebSocket();
145
146 struct WebSocket_CloseOption CloseOption;
147 CloseOption.code = LWS_CLOSE_STATUS_NORMAL;
148 CloseOption.reason = " ";
149 OH_WebSocketClient_Close(client, CloseOption);
150 }
151
152 } // namespace WebSocketClient
153 } // namespace NetStack
154 } // namespace OHOS
155
156 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)157 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
158 {
159 /* Run your code on data */
160 OHOS::NetStack::WebSocketClient::SetAddHeaderTest(data, size);
161 OHOS::NetStack::WebSocketClient::SetRequestOptionsTest(data, size);
162 OHOS::NetStack::WebSocketClient::SetConnectUrlTest(data, size);
163 OHOS::NetStack::WebSocketClient::SetSendDataTest(data, size);
164 OHOS::NetStack::WebSocketClient::SetSendDataLengthTest(data, size);
165 OHOS::NetStack::WebSocketClient::SetCloseOptionTest(data, size);
166 return 0;
167 }