Coverage Report

Created: 2026-09-27 07:10

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.48k
_removeServerComponent(void *application, UA_ServerComponent *sc) {
20
2.48k
    UA_assert(sc->state == UA_LIFECYCLESTATE_STOPPED);
21
2.48k
    sc->clear(sc);
22
2.48k
    UA_free(sc);
23
2.48k
    return NULL;
24
2.48k
}
25
26
/*
27
** Main entry point.  The fuzzer invokes this function with each
28
** fuzzed input.
29
*/
30
extern "C" int
31
833
LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
32
833
    UA_NodeId_clear(&unsafe_fuzz_authenticationToken);
33
833
    if(size <= 4)
34
4
        return 0;
35
36
    /* Keep setup and teardown outside allocation-failure fuzzing. */
37
829
    UA_memoryManager_setLimit((unsigned long long)-1);
38
39
    /* less debug output */
40
829
    UA_ServerConfig initialConfig;
41
829
    memset(&initialConfig, 0, sizeof(UA_ServerConfig));
42
829
    UA_StatusCode retval = UA_ServerConfig_setDefault(&initialConfig);
43
829
    initialConfig.allowEmptyVariables = UA_RULEHANDLING_ACCEPT;
44
829
    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
829
    UA_Server *server = UA_Server_newWithConfig(&initialConfig);
52
829
    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
829
    UA_ByteString msg = UA_BYTESTRING_NULL;
60
829
    retval = UA_ByteString_allocBuffer(&msg, size);
61
829
    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
829
    memcpy(msg.data, data, size);
68
69
    /* Remove all remaining server components (must be all stopped) */
70
829
    lockServer(server);
71
829
    ZIP_ITER(UA_ServerComponentTree, &server->serverComponents,
72
829
             _removeServerComponent, server);
73
829
    ZIP_INIT(&server->serverComponents);
74
829
    unlockServer(server);
75
76
829
    UA_ServerComponent *bpm = UA_BinaryProtocolManager_new(server);
77
829
    addServerComponent(server, bpm, NULL);
78
79
829
    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
829
    void *listenCtx = NULL;
84
829
    serverNetworkCallback(cm, 1, bpm,
85
829
                          &listenCtx, UA_CONNECTIONSTATE_ESTABLISHED,
86
829
                          &UA_KEYVALUEMAP_NULL, UA_BYTESTRING_NULL);
87
88
829
    void *connectionCtx = listenCtx;
89
829
    serverNetworkCallback(cm, 2, bpm,
90
829
                          &connectionCtx, UA_CONNECTIONSTATE_ESTABLISHED,
91
829
                          &UA_KEYVALUEMAP_NULL, msg);
92
93
    /* Remove both connections before freeing the testing ConnectionManager. */
94
829
    serverNetworkCallback(cm, 2, bpm,
95
829
                          &connectionCtx, UA_CONNECTIONSTATE_CLOSING,
96
829
                          &UA_KEYVALUEMAP_NULL, UA_BYTESTRING_NULL);
97
829
    serverNetworkCallback(cm, 1, bpm,
98
829
                          &listenCtx, UA_CONNECTIONSTATE_CLOSING,
99
829
                          &UA_KEYVALUEMAP_NULL, UA_BYTESTRING_NULL);
100
829
    cm->eventSource.free(&cm->eventSource);
101
102
    // if we got an invalid chunk, the message is not deleted, so delete it here
103
829
    UA_ByteString_clear(&msg);
104
829
    UA_Server_delete(server);
105
829
    UA_NodeId_clear(&unsafe_fuzz_authenticationToken);
106
829
    return 0;
107
829
}