diff options
author | Arjun <36335769+0x34d@users.noreply.github.com> | 2022-07-25 22:16:01 +0530 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-07-25 12:46:01 -0400 |
commit | 6f831426e00ec8c42d2cc45ec03b652d491b320f (patch) | |
tree | 38a009eebd84197a1f3175858c1216e5618bd046 | |
parent | cc7e1578856b1bc6bbb10e67242bfefa473a8ed7 (diff) | |
download | rabbitmq-c-6f831426e00ec8c42d2cc45ec03b652d491b320f.tar.gz |
fuzzer deployment (#734)
* fuzzer deployment
Signed-off-by: 0x34d <ajsinghyadav00@gmail.com>
-rw-r--r-- | CMakeLists.txt | 27 | ||||
-rw-r--r-- | fuzz/CMakeLists.txt | 20 | ||||
-rw-r--r-- | fuzz/README.md | 15 | ||||
-rw-r--r-- | fuzz/fuzz_server.c | 133 | ||||
-rw-r--r-- | fuzz/fuzz_table.c | 31 | ||||
-rw-r--r-- | fuzz/fuzz_url.c | 17 | ||||
-rw-r--r-- | fuzz/input/input.raw | bin | 0 -> 8 bytes |
7 files changed, 243 insertions, 0 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index cd33223..1170675 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -135,6 +135,8 @@ option(BUILD_TOOLS "Build Tools (requires POPT Library)" OFF) cmake_dependent_option(BUILD_TOOLS_DOCS "Build man pages for tools (requires xmlto)" OFF "BUILD_TOOLS" OFF) option(BUILD_API_DOCS "Build Doxygen API docs" OFF) option(RUN_SYSTEM_TESTS "Run system tests (i.e. tests requiring an accessible RabbitMQ server instance on localhost)" OFF) +option(BUILD_LIBFUZZ "Build LibFuzzer" OFF) +option(BUILD_AFLFUZZ "Build AFLFuzzer" OFF) if (NOT BUILD_SHARED_LIBS AND NOT BUILD_STATIC_LIBS) message(FATAL_ERROR "One or both of BUILD_SHARED_LIBS or BUILD_STATIC_LIBS must be set to ON to build") @@ -142,6 +144,27 @@ endif() set(targets_export_name rabbitmq-targets) +if(BUILD_LIBFUZZ) + if (NOT CMAKE_C_COMPILER_ID STREQUAL "Clang") + message(FATAL_ERROR "Need clang for libFuzzer support") + endif() + if (NOT BUILD_STATIC_LIBS) + message(FATAL_ERROR "LibFuzzer can only be built against static libraries " "(set BUILD_STATIC_LIBS=ON)") + endif () + + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=fuzzer-no-link,address,undefined") + SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address,undefined") +endif () + +if(BUILD_AFLFUZZ) + if (NOT BUILD_STATIC_LIBS) + message(FATAL_ERROR "AFL-Fuzzer can only be built against static libraries " "(set BUILD_STATIC_LIBS=ON)") + endif () + + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address,undefined") + SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address,undefined") +endif () + add_subdirectory(librabbitmq) if(BUILD_EXAMPLES) @@ -168,6 +191,10 @@ if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME AND BUILD_TESTING) add_subdirectory(tests) endif () +if(BUILD_LIBFUZZ OR BUILD_AFLFUZZ) + add_subdirectory(fuzz) +endif () + if (BUILD_API_DOCS) find_package(Doxygen REQUIRED) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/docs/Doxyfile.in ${CMAKE_CURRENT_BINARY_DIR}/docs/Doxyfile @ONLY) diff --git a/fuzz/CMakeLists.txt b/fuzz/CMakeLists.txt new file mode 100644 index 0000000..7212758 --- /dev/null +++ b/fuzz/CMakeLists.txt @@ -0,0 +1,20 @@ +include_directories( + ${LIBRABBITMQ_INCLUDE_DIRS} + ${CMAKE_CURRENT_BINARY_DIR}/../librabbitmq/ + ${CMAKE_CURRENT_SOURCE_DIR}/../librabbitmq/) + +add_definitions(-DHAVE_CONFIG_H) +add_definitions(-DAMQP_STATIC) + +if(BUILD_LIBFUZZ) + add_executable(fuzz_url fuzz_url.c) + target_link_libraries(fuzz_url rabbitmq-static -fsanitize=fuzzer) + + add_executable(fuzz_table fuzz_table.c) + target_link_libraries(fuzz_table rabbitmq-static -fsanitize=fuzzer) +endif () + +if(BUILD_AFLFUZZ) + add_executable(fuzz_server fuzz_server.c) + target_link_libraries(fuzz_server rabbitmq-static) +endif () diff --git a/fuzz/README.md b/fuzz/README.md new file mode 100644 index 0000000..f11e13d --- /dev/null +++ b/fuzz/README.md @@ -0,0 +1,15 @@ +#### Libfuzzer +``` +cmake -DCMAKE_C_COMPILER=clang -DCMAKE_BUILD_TYPE=Debug -DBUILD_LIBFUZZ=ON ../ + +./fuzz/fuzz_url +./fuzz/fuzz_table +``` + +#### AFL Fuzzer +``` +cmake -DCMAKE_C_COMPILER=afl-clang-fast -DCMAKE_BUILD_TYPE=Debug -DBUILD_AFLFUZZ=ON ../ + +afl-fuzz -i afl_in -o afl_out -- ./fuzz_server 8080 @@ + +``` diff --git a/fuzz/fuzz_server.c b/fuzz/fuzz_server.c new file mode 100644 index 0000000..b5e4b6a --- /dev/null +++ b/fuzz/fuzz_server.c @@ -0,0 +1,133 @@ +// Copyright 2007 - 2022, Alan Antonuk and the rabbitmq-c contributors. +// SPDX-License-Identifier: mit + +#include <arpa/inet.h> +#include <netinet/in.h> +#include <pthread.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/socket.h> +#include <unistd.h> + +#include <rabbitmq-c/amqp.h> +#include <rabbitmq-c/tcp_socket.h> + +struct Fuzzer { + uint16_t port; + char *file; + + FILE *inFile; + uint64_t size; + uint8_t *buffer; + + pthread_t thread; + int socket; +}; +typedef struct Fuzzer Fuzzer; + +static uint8_t pre_encoded_table[] = {0x00, 0x00, 0x00, 0xff, 0x07, + 0x6c, 0x6f, 0x6e, 0x67, 0x73}; + +void fuzzinit(Fuzzer *fuzzer) { + // File + fuzzer->inFile = fopen(fuzzer->file, "rb"); + fseek(fuzzer->inFile, 0L, SEEK_END); + fuzzer->size = ftell(fuzzer->inFile); + fseek(fuzzer->inFile, 0L, SEEK_SET); + fuzzer->buffer = (uint8_t *)calloc(fuzzer->size, sizeof(char)); + fread(fuzzer->buffer, sizeof(char), fuzzer->size, fuzzer->inFile); + // Server + struct sockaddr_in server_addr; + fuzzer->socket = socket(AF_INET, SOCK_STREAM, 0); + server_addr.sin_family = AF_INET; + server_addr.sin_port = htons(fuzzer->port); + server_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); + setsockopt(fuzzer->socket, SOL_SOCKET, SO_REUSEADDR, &(int){1}, sizeof(int)); + bind(fuzzer->socket, (struct sockaddr *)&server_addr, sizeof(server_addr)); + listen(fuzzer->socket, 1); +} + +void *Server(void *args) { + + Fuzzer *fuzzer = (Fuzzer *)args; + + int client; + char clientData[10240]; + struct sockaddr_in clientAddr; + uint32_t clientSZ = sizeof(clientAddr); + + client = accept(fuzzer->socket, (struct sockaddr *)&clientAddr, &clientSZ); + + recv(client, clientData, sizeof(clientData), 0); + + if (fuzzer->size < 9) { + send(client, pre_encoded_table, sizeof(pre_encoded_table), 0); + } else { + send(client, fuzzer->buffer, fuzzer->size, 0); + } + + close(client); + + pthread_exit(NULL); +} + +void client(Fuzzer *fuzzer) { + char const *hostname; + int status; + amqp_socket_t *socket = NULL; + amqp_connection_state_t conn; + + hostname = "localhost"; + + conn = amqp_new_connection(); + + socket = amqp_tcp_socket_new(conn); + if (!socket) { + exit(1); + } + + status = amqp_socket_open(socket, hostname, fuzzer->port); + if (status) { + exit(1); + } + + amqp_login(conn, "/", 0, 131072, 0, AMQP_SASL_METHOD_PLAIN, "guest", "guest"); + + amqp_destroy_connection(conn); +} + +void clean(Fuzzer *fuzzer) { + + free(fuzzer->buffer); + fclose(fuzzer->inFile); + + close(fuzzer->socket); + + free(fuzzer); +} + +int main(int argc, char *argv[]) { + + if (argc < 3) { + printf("Server-port,Input-file \n"); + return 0; + } + + Fuzzer *fuzzer = (Fuzzer *)malloc(sizeof(Fuzzer)); + fuzzer->port = atoi(argv[1]); + fuzzer->file = argv[2]; + + fuzzinit(fuzzer); + + pthread_create(&fuzzer->thread, NULL, Server, fuzzer); + + client(fuzzer); + + pthread_join(fuzzer->thread, NULL); + + clean(fuzzer); + + return 0; +} diff --git a/fuzz/fuzz_table.c b/fuzz/fuzz_table.c new file mode 100644 index 0000000..fbac460 --- /dev/null +++ b/fuzz/fuzz_table.c @@ -0,0 +1,31 @@ +// Copyright 2007 - 2022, Alan Antonuk and the rabbitmq-c contributors. +// SPDX-License-Identifier: mit + +#include <errno.h> +#include <inttypes.h> +#include <math.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <rabbitmq-c/amqp.h> + +extern int LLVMFuzzerTestOneInput(const char *data, size_t size) { + + int result; + amqp_pool_t pool; + + init_amqp_pool(&pool, 4096); + { + amqp_table_t decoded; + size_t decoding_offset = 0; + amqp_bytes_t decoding_bytes; + decoding_bytes.len = size; + decoding_bytes.bytes = (uint8_t *)data; + + result = + amqp_decode_table(decoding_bytes, &pool, &decoded, &decoding_offset); + } + return result; +} diff --git a/fuzz/fuzz_url.c b/fuzz/fuzz_url.c new file mode 100644 index 0000000..5b3658a --- /dev/null +++ b/fuzz/fuzz_url.c @@ -0,0 +1,17 @@ +// Copyright 2007 - 2022, Alan Antonuk and the rabbitmq-c contributors. +// SPDX-License-Identifier: mit + +#include <inttypes.h> +#include <stddef.h> +#include <stdint.h> +#include <string.h> + +#include <rabbitmq-c/amqp.h> + +extern int LLVMFuzzerTestOneInput(const char *data, size_t size) { + + struct amqp_connection_info ci; + int res; + res = amqp_parse_url((char *)data, &ci); + return res; +} diff --git a/fuzz/input/input.raw b/fuzz/input/input.raw Binary files differnew file mode 100644 index 0000000..4f2ca96 --- /dev/null +++ b/fuzz/input/input.raw |