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 }