/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 | 2.39k | extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { |
36 | 2.39k | if(size < 2) |
37 | 2 | return 0; |
38 | | |
39 | 2.39k | UA_ServerConfig config; |
40 | 2.39k | memset(&config, 0, sizeof(UA_ServerConfig)); |
41 | 2.39k | UA_StatusCode retval = UA_ServerConfig_setDefault(&config); |
42 | 2.39k | if(retval != UA_STATUSCODE_GOOD) { |
43 | 0 | UA_ServerConfig_clean(&config); |
44 | 0 | return 0; |
45 | 0 | } |
46 | | |
47 | 2.39k | UA_Server *server = UA_Server_newWithConfig(&config); |
48 | 2.39k | if(!server) { |
49 | 0 | UA_ServerConfig_clean(&config); |
50 | 0 | return 0; |
51 | 0 | } |
52 | | |
53 | 2.39k | UA_SecureChannel channel; |
54 | 2.39k | UA_SecureChannel_init(&channel); |
55 | 2.39k | channel.state = UA_SECURECHANNELSTATE_OPEN; |
56 | | |
57 | 2.39k | UA_Session session; |
58 | 2.39k | UA_Session_init(&session); |
59 | 2.39k | session.activated = true; |
60 | 2.39k | UA_NodeId_init(&session.sessionId); |
61 | 2.39k | session.sessionId.identifierType = UA_NODEIDTYPE_NUMERIC; |
62 | 2.39k | session.sessionId.identifier.numeric = 1; |
63 | | |
64 | | // Use the first byte to decide which service to call |
65 | 2.39k | uint8_t serviceChoice = data[0] % SERVICE_COUNT; |
66 | 2.39k | data++; |
67 | 2.39k | size--; |
68 | | |
69 | 2.39k | UA_ByteString msg = {size, (UA_Byte *) (void *) data}; |
70 | | |
71 | 2.39k | switch((ServiceType)serviceChoice) { |
72 | 182 | case SERVICE_FINDSERVERS: { |
73 | 182 | UA_FindServersRequest request; |
74 | 182 | UA_FindServersResponse response; |
75 | 182 | UA_FindServersResponse_init(&response); |
76 | 182 | if(UA_decodeBinary(&msg, &request, &UA_TYPES[UA_TYPES_FINDSERVERSREQUEST], NULL) == UA_STATUSCODE_GOOD) { |
77 | 46 | UA_LOCK(&server->serviceMutex); |
78 | 46 | Service_FindServers(server, &session, &request, &response); |
79 | 46 | UA_UNLOCK(&server->serviceMutex); |
80 | 46 | UA_FindServersRequest_clear(&request); |
81 | 46 | } |
82 | 182 | UA_FindServersResponse_clear(&response); |
83 | 182 | break; |
84 | 0 | } |
85 | 59 | case SERVICE_GETENDPOINTS: { |
86 | 59 | UA_GetEndpointsRequest request; |
87 | 59 | UA_GetEndpointsResponse response; |
88 | 59 | UA_GetEndpointsResponse_init(&response); |
89 | 59 | if(UA_decodeBinary(&msg, &request, &UA_TYPES[UA_TYPES_GETENDPOINTSREQUEST], NULL) == UA_STATUSCODE_GOOD) { |
90 | 20 | UA_LOCK(&server->serviceMutex); |
91 | 20 | Service_GetEndpoints(server, &session, &request, &response); |
92 | 20 | UA_UNLOCK(&server->serviceMutex); |
93 | 20 | UA_GetEndpointsRequest_clear(&request); |
94 | 20 | } |
95 | 59 | UA_GetEndpointsResponse_clear(&response); |
96 | 59 | break; |
97 | 0 | } |
98 | 0 | #ifdef UA_ENABLE_DISCOVERY |
99 | 100 | case SERVICE_REGISTERSERVER: { |
100 | 100 | UA_RegisterServerRequest request; |
101 | 100 | UA_RegisterServerResponse response; |
102 | 100 | UA_RegisterServerResponse_init(&response); |
103 | 100 | if(UA_decodeBinary(&msg, &request, &UA_TYPES[UA_TYPES_REGISTERSERVERREQUEST], NULL) == UA_STATUSCODE_GOOD) { |
104 | 9 | UA_LOCK(&server->serviceMutex); |
105 | 9 | Service_RegisterServer(server, &session, &request, &response); |
106 | 9 | UA_UNLOCK(&server->serviceMutex); |
107 | 9 | UA_RegisterServerRequest_clear(&request); |
108 | 9 | } |
109 | 100 | UA_RegisterServerResponse_clear(&response); |
110 | 100 | break; |
111 | 0 | } |
112 | 113 | case SERVICE_REGISTERSERVER2: { |
113 | 113 | UA_RegisterServer2Request request; |
114 | 113 | UA_RegisterServer2Response response; |
115 | 113 | UA_RegisterServer2Response_init(&response); |
116 | 113 | 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 | 113 | UA_RegisterServer2Response_clear(&response); |
123 | 113 | break; |
124 | 0 | } |
125 | 0 | # ifdef UA_ENABLE_DISCOVERY_MULTICAST |
126 | 42 | case SERVICE_FINDSERVERSONNETWORK: { |
127 | 42 | UA_FindServersOnNetworkRequest request; |
128 | 42 | UA_FindServersOnNetworkResponse response; |
129 | 42 | UA_FindServersOnNetworkResponse_init(&response); |
130 | 42 | if(UA_decodeBinary(&msg, &request, &UA_TYPES[UA_TYPES_FINDSERVERSONNETWORKREQUEST], NULL) == UA_STATUSCODE_GOOD) { |
131 | 2 | UA_LOCK(&server->serviceMutex); |
132 | 2 | Service_FindServersOnNetwork(server, &session, &request, &response); |
133 | 2 | UA_UNLOCK(&server->serviceMutex); |
134 | 2 | UA_FindServersOnNetworkRequest_clear(&request); |
135 | 2 | } |
136 | 42 | UA_FindServersOnNetworkResponse_clear(&response); |
137 | 42 | break; |
138 | 0 | } |
139 | 0 | # endif |
140 | 0 | #endif |
141 | 31 | case SERVICE_CREATESESSION: { |
142 | 31 | UA_CreateSessionRequest request; |
143 | 31 | UA_CreateSessionResponse response; |
144 | 31 | UA_CreateSessionResponse_init(&response); |
145 | 31 | 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 | 31 | UA_CreateSessionResponse_clear(&response); |
152 | 31 | break; |
153 | 0 | } |
154 | 81 | case SERVICE_ACTIVATESESSION: { |
155 | 81 | UA_ActivateSessionRequest request; |
156 | 81 | UA_ActivateSessionResponse response; |
157 | 81 | UA_ActivateSessionResponse_init(&response); |
158 | 81 | 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 | 81 | UA_ActivateSessionResponse_clear(&response); |
165 | 81 | break; |
166 | 0 | } |
167 | 45 | case SERVICE_CLOSESESSION: { |
168 | 45 | UA_CloseSessionRequest request; |
169 | 45 | UA_CloseSessionResponse response; |
170 | 45 | UA_CloseSessionResponse_init(&response); |
171 | 45 | if(UA_decodeBinary(&msg, &request, &UA_TYPES[UA_TYPES_CLOSESESSIONREQUEST], NULL) == UA_STATUSCODE_GOOD) { |
172 | 3 | UA_LOCK(&server->serviceMutex); |
173 | 3 | Service_CloseSession(server, &channel, &request, &response); |
174 | 3 | UA_UNLOCK(&server->serviceMutex); |
175 | 3 | UA_CloseSessionRequest_clear(&request); |
176 | 3 | } |
177 | 45 | UA_CloseSessionResponse_clear(&response); |
178 | 45 | break; |
179 | 0 | } |
180 | 28 | case SERVICE_CANCEL: { |
181 | 28 | UA_CancelRequest request; |
182 | 28 | UA_CancelResponse response; |
183 | 28 | UA_CancelResponse_init(&response); |
184 | 28 | 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 | 28 | UA_CancelResponse_clear(&response); |
191 | 28 | break; |
192 | 0 | } |
193 | 0 | #ifdef UA_ENABLE_SUBSCRIPTIONS |
194 | 1.10k | case SERVICE_CREATESUBSCRIPTION: { |
195 | 1.10k | UA_CreateSubscriptionRequest request; |
196 | 1.10k | UA_CreateSubscriptionResponse response; |
197 | 1.10k | UA_CreateSubscriptionResponse_init(&response); |
198 | 1.10k | if(UA_decodeBinary(&msg, &request, &UA_TYPES[UA_TYPES_CREATESUBSCRIPTIONREQUEST], NULL) == UA_STATUSCODE_GOOD) { |
199 | 435 | UA_LOCK(&server->serviceMutex); |
200 | 435 | Service_CreateSubscription(server, &session, &request, &response); |
201 | 435 | UA_UNLOCK(&server->serviceMutex); |
202 | 435 | UA_CreateSubscriptionRequest_clear(&request); |
203 | 435 | } |
204 | 1.10k | UA_CreateSubscriptionResponse_clear(&response); |
205 | 1.10k | break; |
206 | 0 | } |
207 | 65 | case SERVICE_MODIFYSUBSCRIPTION: { |
208 | 65 | UA_ModifySubscriptionRequest request; |
209 | 65 | UA_ModifySubscriptionResponse response; |
210 | 65 | UA_ModifySubscriptionResponse_init(&response); |
211 | 65 | if(UA_decodeBinary(&msg, &request, &UA_TYPES[UA_TYPES_MODIFYSUBSCRIPTIONREQUEST], NULL) == UA_STATUSCODE_GOOD) { |
212 | 6 | UA_LOCK(&server->serviceMutex); |
213 | 6 | Service_ModifySubscription(server, &session, &request, &response); |
214 | 6 | UA_UNLOCK(&server->serviceMutex); |
215 | 6 | UA_ModifySubscriptionRequest_clear(&request); |
216 | 6 | } |
217 | 65 | UA_ModifySubscriptionResponse_clear(&response); |
218 | 65 | break; |
219 | 0 | } |
220 | 53 | case SERVICE_SETPUBLISHINGMODE: { |
221 | 53 | UA_SetPublishingModeRequest request; |
222 | 53 | UA_SetPublishingModeResponse response; |
223 | 53 | UA_SetPublishingModeResponse_init(&response); |
224 | 53 | if(UA_decodeBinary(&msg, &request, &UA_TYPES[UA_TYPES_SETPUBLISHINGMODEREQUEST], NULL) == UA_STATUSCODE_GOOD) { |
225 | 24 | UA_LOCK(&server->serviceMutex); |
226 | 24 | Service_SetPublishingMode(server, &session, &request, &response); |
227 | 24 | UA_UNLOCK(&server->serviceMutex); |
228 | 24 | UA_SetPublishingModeRequest_clear(&request); |
229 | 24 | } |
230 | 53 | UA_SetPublishingModeResponse_clear(&response); |
231 | 53 | break; |
232 | 0 | } |
233 | 39 | case SERVICE_DELETESUBSCRIPTIONS: { |
234 | 39 | UA_DeleteSubscriptionsRequest request; |
235 | 39 | UA_DeleteSubscriptionsResponse response; |
236 | 39 | UA_DeleteSubscriptionsResponse_init(&response); |
237 | 39 | if(UA_decodeBinary(&msg, &request, &UA_TYPES[UA_TYPES_DELETESUBSCRIPTIONSREQUEST], NULL) == UA_STATUSCODE_GOOD) { |
238 | 16 | UA_LOCK(&server->serviceMutex); |
239 | 16 | Service_DeleteSubscriptions(server, &session, &request, &response); |
240 | 16 | UA_UNLOCK(&server->serviceMutex); |
241 | 16 | UA_DeleteSubscriptionsRequest_clear(&request); |
242 | 16 | } |
243 | 39 | UA_DeleteSubscriptionsResponse_clear(&response); |
244 | 39 | break; |
245 | 0 | } |
246 | 168 | case SERVICE_CREATEMONITOREDITEMS: { |
247 | 168 | UA_CreateMonitoredItemsRequest request; |
248 | 168 | UA_CreateMonitoredItemsResponse response; |
249 | 168 | UA_CreateMonitoredItemsResponse_init(&response); |
250 | 168 | if(UA_decodeBinary(&msg, &request, &UA_TYPES[UA_TYPES_CREATEMONITOREDITEMSREQUEST], NULL) == UA_STATUSCODE_GOOD) { |
251 | 94 | UA_LOCK(&server->serviceMutex); |
252 | 94 | Service_CreateMonitoredItems(server, &session, &request, &response); |
253 | 94 | UA_UNLOCK(&server->serviceMutex); |
254 | 94 | UA_CreateMonitoredItemsRequest_clear(&request); |
255 | 94 | } |
256 | 168 | UA_CreateMonitoredItemsResponse_clear(&response); |
257 | 168 | break; |
258 | 0 | } |
259 | 211 | case SERVICE_MODIFYMONITOREDITEMS: { |
260 | 211 | UA_ModifyMonitoredItemsRequest request; |
261 | 211 | UA_ModifyMonitoredItemsResponse response; |
262 | 211 | UA_ModifyMonitoredItemsResponse_init(&response); |
263 | 211 | if(UA_decodeBinary(&msg, &request, &UA_TYPES[UA_TYPES_MODIFYMONITOREDITEMSREQUEST], NULL) == UA_STATUSCODE_GOOD) { |
264 | 87 | UA_LOCK(&server->serviceMutex); |
265 | 87 | Service_ModifyMonitoredItems(server, &session, &request, &response); |
266 | 87 | UA_UNLOCK(&server->serviceMutex); |
267 | 87 | UA_ModifyMonitoredItemsRequest_clear(&request); |
268 | 87 | } |
269 | 211 | UA_ModifyMonitoredItemsResponse_clear(&response); |
270 | 211 | break; |
271 | 0 | } |
272 | 48 | case SERVICE_SETMONITORINGMODE: { |
273 | 48 | UA_SetMonitoringModeRequest request; |
274 | 48 | UA_SetMonitoringModeResponse response; |
275 | 48 | UA_SetMonitoringModeResponse_init(&response); |
276 | 48 | if(UA_decodeBinary(&msg, &request, &UA_TYPES[UA_TYPES_SETMONITORINGMODEREQUEST], NULL) == UA_STATUSCODE_GOOD) { |
277 | 3 | UA_LOCK(&server->serviceMutex); |
278 | 3 | Service_SetMonitoringMode(server, &session, &request, &response); |
279 | 3 | UA_UNLOCK(&server->serviceMutex); |
280 | 3 | UA_SetMonitoringModeRequest_clear(&request); |
281 | 3 | } |
282 | 48 | UA_SetMonitoringModeResponse_clear(&response); |
283 | 48 | break; |
284 | 0 | } |
285 | 28 | case SERVICE_DELETEMONITOREDITEMS: { |
286 | 28 | UA_DeleteMonitoredItemsRequest request; |
287 | 28 | UA_DeleteMonitoredItemsResponse response; |
288 | 28 | UA_DeleteMonitoredItemsResponse_init(&response); |
289 | 28 | 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 | 28 | UA_DeleteMonitoredItemsResponse_clear(&response); |
296 | 28 | break; |
297 | 0 | } |
298 | 0 | #endif |
299 | 0 | default: |
300 | 0 | break; |
301 | 2.39k | } |
302 | | |
303 | 2.39k | UA_LOCK(&server->serviceMutex); |
304 | 2.39k | UA_SecureChannel_clear(&channel); |
305 | 2.39k | UA_Session_clear(&session, server); |
306 | 2.39k | UA_UNLOCK(&server->serviceMutex); |
307 | 2.39k | UA_Server_delete(server); |
308 | 2.39k | return 0; |
309 | 2.39k | } |