fuzz_tcp_message.cc 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  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. #include "custom_memory_manager.h"
  8. #include <pthread.h>
  9. #include <open62541/plugin/log_stdout.h>
  10. #include <open62541/server_config_default.h>
  11. #include <open62541/types.h>
  12. #include "ua_server_internal.h"
  13. #include "testing_networklayers.h"
  14. #define RECEIVE_BUFFER_SIZE 65535
  15. #define SERVER_PORT 4840
  16. volatile bool running = true;
  17. static void *serverLoop(void *server_ptr) {
  18. UA_Server *server = (UA_Server*) server_ptr;
  19. while (running) {
  20. UA_Server_run_iterate(server, false);
  21. }
  22. return NULL;
  23. }
  24. /*
  25. ** Main entry point. The fuzzer invokes this function with each
  26. ** fuzzed input.
  27. */
  28. extern "C" int
  29. LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
  30. UA_Server *server = UA_Server_new();
  31. if(!server) {
  32. UA_LOG_FATAL(UA_Log_Stdout, UA_LOGCATEGORY_SERVER,
  33. "Could not create server instance using UA_Server_new");
  34. return EXIT_FAILURE;
  35. }
  36. UA_ServerConfig *config = UA_Server_getConfig(server);
  37. UA_StatusCode retval = UA_ServerConfig_setMinimal(config, SERVER_PORT, NULL);
  38. if (retval != UA_STATUSCODE_GOOD) {
  39. UA_LOG_FATAL(UA_Log_Stdout, UA_LOGCATEGORY_SERVER,
  40. "Could not create server instance using UA_Server_new. %s", UA_StatusCode_name(retval));
  41. UA_Server_delete(server);
  42. return EXIT_FAILURE;
  43. }
  44. // Enable the mDNS announce and response functionality
  45. config->discovery.mdnsEnable = true;
  46. config->discovery.mdns.mdnsServerName = UA_String_fromChars("Sample Multicast Server");
  47. retval = UA_Server_run_startup(server);
  48. if(retval != UA_STATUSCODE_GOOD) {
  49. UA_LOG_FATAL(UA_Log_Stdout, UA_LOGCATEGORY_SERVER,
  50. "Could not run UA_Server_run_startup. %s", UA_StatusCode_name(retval));
  51. UA_Server_delete(server);
  52. return EXIT_FAILURE;
  53. }
  54. if (!UA_memoryManager_setLimitFromLast4Bytes(data, size)) {
  55. UA_Server_run_shutdown(server);
  56. UA_Server_delete(server);
  57. return EXIT_SUCCESS;
  58. }
  59. size -= 4;
  60. // Iterate once to initialize the TCP connection. Otherwise the connect below may come before the server is up.
  61. UA_Server_run_iterate(server, true);
  62. pthread_t serverThread;
  63. int rc = pthread_create(&serverThread, NULL, serverLoop, (void *)server);
  64. if (rc){
  65. UA_LOG_FATAL(UA_Log_Stdout, UA_LOGCATEGORY_SERVER,
  66. "return code from pthread_create() is %d", rc);
  67. UA_Server_run_shutdown(server);
  68. UA_Server_delete(server);
  69. return -1;
  70. }
  71. int retCode = EXIT_SUCCESS;
  72. int sockfd = 0;
  73. {
  74. // create a client and write to localhost TCP server
  75. if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
  76. {
  77. UA_LOG_FATAL(UA_Log_Stdout, UA_LOGCATEGORY_CLIENT,
  78. "Could not create socket");
  79. retCode = EXIT_FAILURE;
  80. } else {
  81. struct sockaddr_in serv_addr;
  82. serv_addr.sin_family = AF_INET;
  83. serv_addr.sin_port = htons(SERVER_PORT);
  84. serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
  85. int status = connect(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr));
  86. if (status >= 0) {
  87. if (write(sockfd, data, size) != size) {
  88. UA_LOG_FATAL(UA_Log_Stdout, UA_LOGCATEGORY_CLIENT,
  89. "Did not write %d bytes", size);
  90. retCode = EXIT_FAILURE;
  91. }
  92. } else {
  93. UA_LOG_FATAL(UA_Log_Stdout, UA_LOGCATEGORY_CLIENT,
  94. "Could not connect to server: %s", strerror(errno));
  95. retCode = EXIT_FAILURE;
  96. }
  97. }
  98. }
  99. running = false;
  100. void *status;
  101. pthread_join(serverThread, &status);
  102. // Process any remaining data. Just repeat a few times to empty all the buffered bytes
  103. for (size_t i=0; i<5; i++) {
  104. UA_Server_run_iterate(server, false);
  105. }
  106. close(sockfd);
  107. UA_Server_run_shutdown(server);
  108. UA_Server_delete(server);
  109. return retCode;
  110. }