/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Copyright 2019 (c) fortiss (Author: Stefan Profanter) */ #include #include #include #include "ua_server_internal.h" #include "custom_memory_manager.h" #include "testing_networklayers.h" #define RECEIVE_BUFFER_SIZE 65535 /* ** Main entry point. The fuzzer invokes this function with each ** fuzzed input. */ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { UA_NodeId_clear(&unsafe_fuzz_authenticationToken); if(size <= 4) return 0; /* Keep setup and teardown outside allocation-failure fuzzing. */ UA_memoryManager_setLimit((unsigned long long)-1); /* less debug output */ UA_ServerConfig initialConfig; memset(&initialConfig, 0, sizeof(UA_ServerConfig)); UA_StatusCode retval = UA_ServerConfig_setDefault(&initialConfig); initialConfig.allowEmptyVariables = UA_RULEHANDLING_ACCEPT; if(retval != UA_STATUSCODE_GOOD) { UA_ServerConfig_clean(&initialConfig); UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "Could not generate the server config"); return 0; } UA_Server *server = UA_Server_newWithConfig(&initialConfig); if(!server) { UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "Could not create server instance using UA_Server_new"); return 0; } // we need to copy the message because it will be freed in the processing function UA_ByteString msg = UA_BYTESTRING_NULL; retval = UA_ByteString_allocBuffer(&msg, size); if(retval != UA_STATUSCODE_GOOD) { UA_Server_delete(server); UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "Could not allocate message buffer"); return 0; } memcpy(msg.data, data, size); UA_Driver *bpm = server->binaryDriver; UA_assert(bpm != NULL); UA_ConnectionManager *cm = TestConnectionManager_new("tcp", NULL); /* Register a listening socket first. New active connections inherit its * context and replace it with their SecureChannel on the first callback. */ void *listenCtx = NULL; serverNetworkCallback(cm, 1, bpm, &listenCtx, UA_CONNECTIONSTATE_ESTABLISHED, &UA_KEYVALUEMAP_NULL, UA_BYTESTRING_NULL); void *connectionCtx = listenCtx; serverNetworkCallback(cm, 2, bpm, &connectionCtx, UA_CONNECTIONSTATE_ESTABLISHED, &UA_KEYVALUEMAP_NULL, msg); /* Remove both connections before freeing the testing ConnectionManager. */ serverNetworkCallback(cm, 2, bpm, &connectionCtx, UA_CONNECTIONSTATE_CLOSING, &UA_KEYVALUEMAP_NULL, UA_BYTESTRING_NULL); serverNetworkCallback(cm, 1, bpm, &listenCtx, UA_CONNECTIONSTATE_CLOSING, &UA_KEYVALUEMAP_NULL, UA_BYTESTRING_NULL); cm->eventSource.free(&cm->eventSource); // if we got an invalid chunk, the message is not deleted, so delete it here UA_ByteString_clear(&msg); UA_Server_delete(server); UA_NodeId_clear(&unsafe_fuzz_authenticationToken); return 0; }