Coverage Report

Created: 2026-09-28 07:11

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/open62541_15/tests/fuzz/fuzz_binary_message.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
 *    Copyright 2019 (c) fortiss (Author: Stefan Profanter)
6
 */
7
8
#include <open62541/plugin/log_stdout.h>
9
#include <open62541/server_config_default.h>
10
#include <open62541/types.h>
11
12
#include "ua_server_internal.h"
13
#include "custom_memory_manager.h"
14
#include "testing_networklayers.h"
15
16
#define RECEIVE_BUFFER_SIZE 65535
17
18
static void *
19
2.49k
_removeServerComponent(void *application, UA_ServerComponent *sc) {
20
2.49k
    UA_assert(sc->state == UA_LIFECYCLESTATE_STOPPED);
21
2.49k
    sc->clear(sc);
22
2.49k
    UA_free(sc);
23
2.49k
    return NULL;
24
2.49k
}
25
26
/*
27
** Main entry point.  The fuzzer invokes this function with each
28
** fuzzed input.
29
*/
30
extern "C" int
31
834
LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
32
834
    UA_NodeId_clear(&unsafe_fuzz_authenticationToken);
33
834
    if(size <= 4)
34
4
        return 0;
35
36
    /* Keep setup and teardown outside allocation-failure fuzzing. */
37
830
    UA_memoryManager_setLimit((unsigned long long)-1);
38
39
    /* less debug output */
40
830
    UA_ServerConfig initialConfig;
41
830
    memset(&initialConfig, 0, sizeof(UA_ServerConfig));
42
830
    UA_StatusCode retval = UA_ServerConfig_setDefault(&initialConfig);
43
830
    initialConfig.allowEmptyVariables = UA_RULEHANDLING_ACCEPT;
44
830
    if(retval != UA_STATUSCODE_GOOD) {
45
0
        UA_ServerConfig_clean(&initialConfig);
46
0
        UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER,
47
0
                     "Could not generate the server config");
48
0
        return 0;
49
0
    }
50
51
830
    UA_Server *server = UA_Server_newWithConfig(&initialConfig);
52
830
    if(!server) {
53
0
        UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER,
54
0
                     "Could not create server instance using UA_Server_new");
55
0
        return 0;
56
0
    }
57
58
    // we need to copy the message because it will be freed in the processing function
59
830
    UA_ByteString msg = UA_BYTESTRING_NULL;
60
830
    retval = UA_ByteString_allocBuffer(&msg, size);
61
830
    if(retval != UA_STATUSCODE_GOOD) {
62
0
        UA_Server_delete(server);
63
0
        UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER,
64
0
                     "Could not allocate message buffer");
65
0
        return 0;
66
0
    }
67
830
    memcpy(msg.data, data, size);
68
69
    /* Remove all remaining server components (must be all stopped) */
70
830
    lockServer(server);
71
830
    ZIP_ITER(UA_ServerComponentTree, &server->serverComponents,
72
830
             _removeServerComponent, server);
73
830
    ZIP_INIT(&server->serverComponents);
74
830
    unlockServer(server);
75
76
830
    UA_ServerComponent *bpm = UA_BinaryProtocolManager_new(server);
77
830
    addServerComponent(server, bpm, NULL);
78
79
830
    UA_ConnectionManager *cm = TestConnectionManager_new("tcp", NULL);
80
81
    /* Register a listening socket first. New active connections inherit its
82
     * context and replace it with their SecureChannel on the first callback. */
83
830
    void *listenCtx = NULL;
84
830
    serverNetworkCallback(cm, 1, bpm,
85
830
                          &listenCtx, UA_CONNECTIONSTATE_ESTABLISHED,
86
830
                          &UA_KEYVALUEMAP_NULL, UA_BYTESTRING_NULL);
87
88
830
    void *connectionCtx = listenCtx;
89
830
    serverNetworkCallback(cm, 2, bpm,
90
830
                          &connectionCtx, UA_CONNECTIONSTATE_ESTABLISHED,
91
830
                          &UA_KEYVALUEMAP_NULL, msg);
92
93
    /* Remove both connections before freeing the testing ConnectionManager. */
94
830
    serverNetworkCallback(cm, 2, bpm,
95
830
                          &connectionCtx, UA_CONNECTIONSTATE_CLOSING,
96
830
                          &UA_KEYVALUEMAP_NULL, UA_BYTESTRING_NULL);
97
830
    serverNetworkCallback(cm, 1, bpm,
98
830
                          &listenCtx, UA_CONNECTIONSTATE_CLOSING,
99
830
                          &UA_KEYVALUEMAP_NULL, UA_BYTESTRING_NULL);
100
830
    cm->eventSource.free(&cm->eventSource);
101
102
    // if we got an invalid chunk, the message is not deleted, so delete it here
103
830
    UA_ByteString_clear(&msg);
104
830
    UA_Server_delete(server);
105
830
    UA_NodeId_clear(&unsafe_fuzz_authenticationToken);
106
830
    return 0;
107
830
}