/src/open62541_15/tests/fuzz/fuzz_server_services.cc
Line | Count | Source |
1 | | /* This Source Code Form is subject to the terms of the Mozilla Public |
2 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
3 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. |
4 | | * |
5 | | */ |
6 | | |
7 | | #include <open62541/plugin/log_stdout.h> |
8 | | #include <open62541/server_config_default.h> |
9 | | #include <open62541/types.h> |
10 | | |
11 | | #include "ua_server_internal.h" |
12 | | #include "ua_services.h" |
13 | | |
14 | | typedef enum { |
15 | | SERVICE_FINDSERVERS = 0, |
16 | | SERVICE_GETENDPOINTS, |
17 | | SERVICE_REGISTERSERVER, |
18 | | SERVICE_REGISTERSERVER2, |
19 | | SERVICE_FINDSERVERSONNETWORK, |
20 | | SERVICE_CREATESESSION, |
21 | | SERVICE_ACTIVATESESSION, |
22 | | SERVICE_CLOSESESSION, |
23 | | SERVICE_CANCEL, |
24 | | SERVICE_CREATESUBSCRIPTION, |
25 | | SERVICE_MODIFYSUBSCRIPTION, |
26 | | SERVICE_SETPUBLISHINGMODE, |
27 | | SERVICE_DELETESUBSCRIPTIONS, |
28 | | SERVICE_CREATEMONITOREDITEMS, |
29 | | SERVICE_MODIFYMONITOREDITEMS, |
30 | | SERVICE_SETMONITORINGMODE, |
31 | | SERVICE_DELETEMONITOREDITEMS, |
32 | | SERVICE_COUNT |
33 | | } ServiceType; |
34 | | |
35 | 3.02k | extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { |
36 | 3.02k | if(size < 2) |
37 | 2 | return 0; |
38 | | |
39 | 3.01k | UA_ServerConfig config; |
40 | 3.01k | memset(&config, 0, sizeof(UA_ServerConfig)); |
41 | 3.01k | UA_StatusCode retval = UA_ServerConfig_setDefault(&config); |
42 | 3.01k | if(retval != UA_STATUSCODE_GOOD) { |
43 | 0 | UA_ServerConfig_clean(&config); |
44 | 0 | return 0; |
45 | 0 | } |
46 | | |
47 | 3.01k | UA_Server *server = UA_Server_newWithConfig(&config); |
48 | 3.01k | if(!server) { |
49 | 0 | UA_ServerConfig_clean(&config); |
50 | 0 | return 0; |
51 | 0 | } |
52 | | |
53 | 3.01k | UA_SecureChannel channel; |
54 | 3.01k | UA_SecureChannel_init(&channel); |
55 | 3.01k | channel.state = UA_SECURECHANNELSTATE_OPEN; |
56 | | |
57 | 3.01k | UA_Session session; |
58 | 3.01k | UA_Session_init(&session); |
59 | 3.01k | session.activated = true; |
60 | 3.01k | UA_NodeId_init(&session.sessionId); |
61 | 3.01k | session.sessionId.identifierType = UA_NODEIDTYPE_NUMERIC; |
62 | 3.01k | session.sessionId.identifier.numeric = 1; |
63 | | |
64 | | // Use the first byte to decide which service to call |
65 | 3.01k | uint8_t serviceChoice = data[0] % SERVICE_COUNT; |
66 | 3.01k | data++; |
67 | 3.01k | size--; |
68 | | |
69 | 3.01k | UA_ByteString msg = {size, (UA_Byte *) (void *) data}; |
70 | | |
71 | 3.01k | switch((ServiceType)serviceChoice) { |
72 | 160 | case SERVICE_FINDSERVERS: { |
73 | 160 | UA_FindServersRequest request; |
74 | 160 | UA_FindServersResponse response; |
75 | 160 | UA_FindServersResponse_init(&response); |
76 | 160 | if(UA_decodeBinary(&msg, &request, &UA_TYPES[UA_TYPES_FINDSERVERSREQUEST], NULL) == UA_STATUSCODE_GOOD) { |
77 | 53 | UA_LOCK(&server->serviceMutex); |
78 | 53 | Service_FindServers(server, &session, &request, &response); |
79 | 53 | UA_UNLOCK(&server->serviceMutex); |
80 | 53 | UA_FindServersRequest_clear(&request); |
81 | 53 | } |
82 | 160 | UA_FindServersResponse_clear(&response); |
83 | 160 | break; |
84 | 0 | } |
85 | 76 | case SERVICE_GETENDPOINTS: { |
86 | 76 | UA_GetEndpointsRequest request; |
87 | 76 | UA_GetEndpointsResponse response; |
88 | 76 | UA_GetEndpointsResponse_init(&response); |
89 | 76 | if(UA_decodeBinary(&msg, &request, &UA_TYPES[UA_TYPES_GETENDPOINTSREQUEST], NULL) == UA_STATUSCODE_GOOD) { |
90 | 24 | UA_LOCK(&server->serviceMutex); |
91 | 24 | Service_GetEndpoints(server, &session, &request, &response); |
92 | 24 | UA_UNLOCK(&server->serviceMutex); |
93 | 24 | UA_GetEndpointsRequest_clear(&request); |
94 | 24 | } |
95 | 76 | UA_GetEndpointsResponse_clear(&response); |
96 | 76 | break; |
97 | 0 | } |
98 | 0 | #ifdef UA_ENABLE_DISCOVERY |
99 | 89 | case SERVICE_REGISTERSERVER: { |
100 | 89 | UA_RegisterServerRequest request; |
101 | 89 | UA_RegisterServerResponse response; |
102 | 89 | UA_RegisterServerResponse_init(&response); |
103 | 89 | if(UA_decodeBinary(&msg, &request, &UA_TYPES[UA_TYPES_REGISTERSERVERREQUEST], NULL) == UA_STATUSCODE_GOOD) { |
104 | 4 | UA_LOCK(&server->serviceMutex); |
105 | 4 | Service_RegisterServer(server, &session, &request, &response); |
106 | 4 | UA_UNLOCK(&server->serviceMutex); |
107 | 4 | UA_RegisterServerRequest_clear(&request); |
108 | 4 | } |
109 | 89 | UA_RegisterServerResponse_clear(&response); |
110 | 89 | break; |
111 | 0 | } |
112 | 112 | case SERVICE_REGISTERSERVER2: { |
113 | 112 | UA_RegisterServer2Request request; |
114 | 112 | UA_RegisterServer2Response response; |
115 | 112 | UA_RegisterServer2Response_init(&response); |
116 | 112 | if(UA_decodeBinary(&msg, &request, &UA_TYPES[UA_TYPES_REGISTERSERVER2REQUEST], NULL) == UA_STATUSCODE_GOOD) { |
117 | 9 | UA_LOCK(&server->serviceMutex); |
118 | 9 | Service_RegisterServer2(server, &session, &request, &response); |
119 | 9 | UA_UNLOCK(&server->serviceMutex); |
120 | 9 | UA_RegisterServer2Request_clear(&request); |
121 | 9 | } |
122 | 112 | UA_RegisterServer2Response_clear(&response); |
123 | 112 | break; |
124 | 0 | } |
125 | 0 | # ifdef UA_ENABLE_DISCOVERY_MULTICAST |
126 | 48 | case SERVICE_FINDSERVERSONNETWORK: { |
127 | 48 | UA_FindServersOnNetworkRequest request; |
128 | 48 | UA_FindServersOnNetworkResponse response; |
129 | 48 | UA_FindServersOnNetworkResponse_init(&response); |
130 | 48 | if(UA_decodeBinary(&msg, &request, &UA_TYPES[UA_TYPES_FINDSERVERSONNETWORKREQUEST], NULL) == UA_STATUSCODE_GOOD) { |
131 | 3 | UA_LOCK(&server->serviceMutex); |
132 | 3 | Service_FindServersOnNetwork(server, &session, &request, &response); |
133 | 3 | UA_UNLOCK(&server->serviceMutex); |
134 | 3 | UA_FindServersOnNetworkRequest_clear(&request); |
135 | 3 | } |
136 | 48 | UA_FindServersOnNetworkResponse_clear(&response); |
137 | 48 | break; |
138 | 0 | } |
139 | 0 | # endif |
140 | 0 | #endif |
141 | 43 | case SERVICE_CREATESESSION: { |
142 | 43 | UA_CreateSessionRequest request; |
143 | 43 | UA_CreateSessionResponse response; |
144 | 43 | UA_CreateSessionResponse_init(&response); |
145 | 43 | if(UA_decodeBinary(&msg, &request, &UA_TYPES[UA_TYPES_CREATESESSIONREQUEST], NULL) == UA_STATUSCODE_GOOD) { |
146 | 0 | UA_LOCK(&server->serviceMutex); |
147 | 0 | Service_CreateSession(server, &channel, &request, &response); |
148 | 0 | UA_UNLOCK(&server->serviceMutex); |
149 | 0 | UA_CreateSessionRequest_clear(&request); |
150 | 0 | } |
151 | 43 | UA_CreateSessionResponse_clear(&response); |
152 | 43 | break; |
153 | 0 | } |
154 | 90 | case SERVICE_ACTIVATESESSION: { |
155 | 90 | UA_ActivateSessionRequest request; |
156 | 90 | UA_ActivateSessionResponse response; |
157 | 90 | UA_ActivateSessionResponse_init(&response); |
158 | 90 | if(UA_decodeBinary(&msg, &request, &UA_TYPES[UA_TYPES_ACTIVATESESSIONREQUEST], NULL) == UA_STATUSCODE_GOOD) { |
159 | 4 | UA_LOCK(&server->serviceMutex); |
160 | 4 | Service_ActivateSession(server, &channel, &request, &response); |
161 | 4 | UA_UNLOCK(&server->serviceMutex); |
162 | 4 | UA_ActivateSessionRequest_clear(&request); |
163 | 4 | } |
164 | 90 | UA_ActivateSessionResponse_clear(&response); |
165 | 90 | break; |
166 | 0 | } |
167 | 33 | case SERVICE_CLOSESESSION: { |
168 | 33 | UA_CloseSessionRequest request; |
169 | 33 | UA_CloseSessionResponse response; |
170 | 33 | UA_CloseSessionResponse_init(&response); |
171 | 33 | if(UA_decodeBinary(&msg, &request, &UA_TYPES[UA_TYPES_CLOSESESSIONREQUEST], NULL) == UA_STATUSCODE_GOOD) { |
172 | 5 | UA_LOCK(&server->serviceMutex); |
173 | 5 | Service_CloseSession(server, &channel, &request, &response); |
174 | 5 | UA_UNLOCK(&server->serviceMutex); |
175 | 5 | UA_CloseSessionRequest_clear(&request); |
176 | 5 | } |
177 | 33 | UA_CloseSessionResponse_clear(&response); |
178 | 33 | break; |
179 | 0 | } |
180 | 29 | case SERVICE_CANCEL: { |
181 | 29 | UA_CancelRequest request; |
182 | 29 | UA_CancelResponse response; |
183 | 29 | UA_CancelResponse_init(&response); |
184 | 29 | if(UA_decodeBinary(&msg, &request, &UA_TYPES[UA_TYPES_CANCELREQUEST], NULL) == UA_STATUSCODE_GOOD) { |
185 | 2 | UA_LOCK(&server->serviceMutex); |
186 | 2 | Service_Cancel(server, &session, &request, &response); |
187 | 2 | UA_UNLOCK(&server->serviceMutex); |
188 | 2 | UA_CancelRequest_clear(&request); |
189 | 2 | } |
190 | 29 | UA_CancelResponse_clear(&response); |
191 | 29 | break; |
192 | 0 | } |
193 | 0 | #ifdef UA_ENABLE_SUBSCRIPTIONS |
194 | 1.69k | case SERVICE_CREATESUBSCRIPTION: { |
195 | 1.69k | UA_CreateSubscriptionRequest request; |
196 | 1.69k | UA_CreateSubscriptionResponse response; |
197 | 1.69k | UA_CreateSubscriptionResponse_init(&response); |
198 | 1.69k | if(UA_decodeBinary(&msg, &request, &UA_TYPES[UA_TYPES_CREATESUBSCRIPTIONREQUEST], NULL) == UA_STATUSCODE_GOOD) { |
199 | 406 | UA_LOCK(&server->serviceMutex); |
200 | 406 | Service_CreateSubscription(server, &session, &request, &response); |
201 | 406 | UA_UNLOCK(&server->serviceMutex); |
202 | 406 | UA_CreateSubscriptionRequest_clear(&request); |
203 | 406 | } |
204 | 1.69k | UA_CreateSubscriptionResponse_clear(&response); |
205 | 1.69k | break; |
206 | 0 | } |
207 | 56 | case SERVICE_MODIFYSUBSCRIPTION: { |
208 | 56 | UA_ModifySubscriptionRequest request; |
209 | 56 | UA_ModifySubscriptionResponse response; |
210 | 56 | UA_ModifySubscriptionResponse_init(&response); |
211 | 56 | if(UA_decodeBinary(&msg, &request, &UA_TYPES[UA_TYPES_MODIFYSUBSCRIPTIONREQUEST], NULL) == UA_STATUSCODE_GOOD) { |
212 | 5 | UA_LOCK(&server->serviceMutex); |
213 | 5 | Service_ModifySubscription(server, &session, &request, &response); |
214 | 5 | UA_UNLOCK(&server->serviceMutex); |
215 | 5 | UA_ModifySubscriptionRequest_clear(&request); |
216 | 5 | } |
217 | 56 | UA_ModifySubscriptionResponse_clear(&response); |
218 | 56 | break; |
219 | 0 | } |
220 | 60 | case SERVICE_SETPUBLISHINGMODE: { |
221 | 60 | UA_SetPublishingModeRequest request; |
222 | 60 | UA_SetPublishingModeResponse response; |
223 | 60 | UA_SetPublishingModeResponse_init(&response); |
224 | 60 | if(UA_decodeBinary(&msg, &request, &UA_TYPES[UA_TYPES_SETPUBLISHINGMODEREQUEST], NULL) == UA_STATUSCODE_GOOD) { |
225 | 23 | UA_LOCK(&server->serviceMutex); |
226 | 23 | Service_SetPublishingMode(server, &session, &request, &response); |
227 | 23 | UA_UNLOCK(&server->serviceMutex); |
228 | 23 | UA_SetPublishingModeRequest_clear(&request); |
229 | 23 | } |
230 | 60 | UA_SetPublishingModeResponse_clear(&response); |
231 | 60 | break; |
232 | 0 | } |
233 | 37 | case SERVICE_DELETESUBSCRIPTIONS: { |
234 | 37 | UA_DeleteSubscriptionsRequest request; |
235 | 37 | UA_DeleteSubscriptionsResponse response; |
236 | 37 | UA_DeleteSubscriptionsResponse_init(&response); |
237 | 37 | if(UA_decodeBinary(&msg, &request, &UA_TYPES[UA_TYPES_DELETESUBSCRIPTIONSREQUEST], NULL) == UA_STATUSCODE_GOOD) { |
238 | 18 | UA_LOCK(&server->serviceMutex); |
239 | 18 | Service_DeleteSubscriptions(server, &session, &request, &response); |
240 | 18 | UA_UNLOCK(&server->serviceMutex); |
241 | 18 | UA_DeleteSubscriptionsRequest_clear(&request); |
242 | 18 | } |
243 | 37 | UA_DeleteSubscriptionsResponse_clear(&response); |
244 | 37 | break; |
245 | 0 | } |
246 | 186 | case SERVICE_CREATEMONITOREDITEMS: { |
247 | 186 | UA_CreateMonitoredItemsRequest request; |
248 | 186 | UA_CreateMonitoredItemsResponse response; |
249 | 186 | UA_CreateMonitoredItemsResponse_init(&response); |
250 | 186 | if(UA_decodeBinary(&msg, &request, &UA_TYPES[UA_TYPES_CREATEMONITOREDITEMSREQUEST], NULL) == UA_STATUSCODE_GOOD) { |
251 | 99 | UA_LOCK(&server->serviceMutex); |
252 | 99 | Service_CreateMonitoredItems(server, &session, &request, &response); |
253 | 99 | UA_UNLOCK(&server->serviceMutex); |
254 | 99 | UA_CreateMonitoredItemsRequest_clear(&request); |
255 | 99 | } |
256 | 186 | UA_CreateMonitoredItemsResponse_clear(&response); |
257 | 186 | break; |
258 | 0 | } |
259 | 243 | case SERVICE_MODIFYMONITOREDITEMS: { |
260 | 243 | UA_ModifyMonitoredItemsRequest request; |
261 | 243 | UA_ModifyMonitoredItemsResponse response; |
262 | 243 | UA_ModifyMonitoredItemsResponse_init(&response); |
263 | 243 | if(UA_decodeBinary(&msg, &request, &UA_TYPES[UA_TYPES_MODIFYMONITOREDITEMSREQUEST], NULL) == UA_STATUSCODE_GOOD) { |
264 | 95 | UA_LOCK(&server->serviceMutex); |
265 | 95 | Service_ModifyMonitoredItems(server, &session, &request, &response); |
266 | 95 | UA_UNLOCK(&server->serviceMutex); |
267 | 95 | UA_ModifyMonitoredItemsRequest_clear(&request); |
268 | 95 | } |
269 | 243 | UA_ModifyMonitoredItemsResponse_clear(&response); |
270 | 243 | break; |
271 | 0 | } |
272 | 38 | case SERVICE_SETMONITORINGMODE: { |
273 | 38 | UA_SetMonitoringModeRequest request; |
274 | 38 | UA_SetMonitoringModeResponse response; |
275 | 38 | UA_SetMonitoringModeResponse_init(&response); |
276 | 38 | if(UA_decodeBinary(&msg, &request, &UA_TYPES[UA_TYPES_SETMONITORINGMODEREQUEST], NULL) == UA_STATUSCODE_GOOD) { |
277 | 2 | UA_LOCK(&server->serviceMutex); |
278 | 2 | Service_SetMonitoringMode(server, &session, &request, &response); |
279 | 2 | UA_UNLOCK(&server->serviceMutex); |
280 | 2 | UA_SetMonitoringModeRequest_clear(&request); |
281 | 2 | } |
282 | 38 | UA_SetMonitoringModeResponse_clear(&response); |
283 | 38 | break; |
284 | 0 | } |
285 | 27 | case SERVICE_DELETEMONITOREDITEMS: { |
286 | 27 | UA_DeleteMonitoredItemsRequest request; |
287 | 27 | UA_DeleteMonitoredItemsResponse response; |
288 | 27 | UA_DeleteMonitoredItemsResponse_init(&response); |
289 | 27 | if(UA_decodeBinary(&msg, &request, &UA_TYPES[UA_TYPES_DELETEMONITOREDITEMSREQUEST], NULL) == UA_STATUSCODE_GOOD) { |
290 | 2 | UA_LOCK(&server->serviceMutex); |
291 | 2 | Service_DeleteMonitoredItems(server, &session, &request, &response); |
292 | 2 | UA_UNLOCK(&server->serviceMutex); |
293 | 2 | UA_DeleteMonitoredItemsRequest_clear(&request); |
294 | 2 | } |
295 | 27 | UA_DeleteMonitoredItemsResponse_clear(&response); |
296 | 27 | break; |
297 | 0 | } |
298 | 0 | #endif |
299 | 0 | default: |
300 | 0 | break; |
301 | 3.01k | } |
302 | | |
303 | 3.01k | UA_LOCK(&server->serviceMutex); |
304 | 3.01k | UA_SecureChannel_clear(&channel); |
305 | 3.01k | UA_Session_clear(&session, server); |
306 | 3.01k | UA_UNLOCK(&server->serviceMutex); |
307 | 3.01k | UA_Server_delete(server); |
308 | 3.01k | return 0; |
309 | 3.01k | } |