/src/librabbitmq/fuzz/fuzz_server.c
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright 2007 - 2022, Alan Antonuk and the rabbitmq-c contributors. |
2 | | // SPDX-License-Identifier: mit |
3 | | |
4 | | #include <arpa/inet.h> |
5 | | #include <errno.h> |
6 | | #include <netinet/in.h> |
7 | | #include <pthread.h> |
8 | | #include <stdint.h> |
9 | | #include <stdio.h> |
10 | | #include <stdlib.h> |
11 | | #include <string.h> |
12 | | #include <sys/socket.h> |
13 | | #include <unistd.h> |
14 | | |
15 | | #include <rabbitmq-c/amqp.h> |
16 | | #include <rabbitmq-c/tcp_socket.h> |
17 | | |
18 | | struct Fuzzer { |
19 | | int socket; |
20 | | uint16_t port; |
21 | | pthread_t thread; |
22 | | |
23 | | uint64_t size; |
24 | | uint8_t *buffer; |
25 | | }; |
26 | | typedef struct Fuzzer Fuzzer; |
27 | | |
28 | 0 | #define PORT 5672 |
29 | 88 | #define kMinInputLength 8 |
30 | 40 | #define kMaxInputLength 1024 |
31 | | |
32 | | void client(Fuzzer *fuzzer); |
33 | | |
34 | 0 | void fuzzinit(Fuzzer *fuzzer) { |
35 | 0 | struct sockaddr_in server_addr; |
36 | 0 | int res; |
37 | 0 | fuzzer->socket = socket(AF_INET, SOCK_STREAM, 0); |
38 | 0 | if (fuzzer->socket == -1) { |
39 | 0 | fprintf(stderr, "socket failed %s\n", strerror(errno)); |
40 | 0 | exit(1); |
41 | 0 | } |
42 | 0 | memset(&server_addr, 0, sizeof(server_addr)); |
43 | 0 | server_addr.sin_family = AF_INET; |
44 | 0 | server_addr.sin_port = htons(fuzzer->port); |
45 | 0 | server_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); |
46 | 0 | res = setsockopt(fuzzer->socket, SOL_SOCKET, SO_REUSEADDR, &(int){1}, sizeof(int)); |
47 | 0 | if (res) { |
48 | 0 | fprintf(stderr, "setsockopt failed: %s\n", strerror(errno)); |
49 | 0 | exit(1); |
50 | 0 | } |
51 | | |
52 | 0 | res = bind(fuzzer->socket, (struct sockaddr *)&server_addr, sizeof(server_addr)); |
53 | 0 | if (res) { |
54 | 0 | fprintf(stderr, "bind failed: %s\n", strerror(errno)); |
55 | 0 | exit(1); |
56 | 0 | } |
57 | 0 | res = listen(fuzzer->socket, 1); |
58 | 0 | if (res) { |
59 | 0 | fprintf(stderr, "listen failed: %s\n", strerror(errno)); |
60 | 0 | exit(1); |
61 | 0 | } |
62 | 0 | } |
63 | | |
64 | 0 | void *Server(void *args) { |
65 | 0 | Fuzzer *fuzzer = (Fuzzer *)args; |
66 | |
|
67 | 0 | int client; |
68 | 0 | int res; |
69 | 0 | char clientData[10240]; |
70 | |
|
71 | 0 | client = accept(fuzzer->socket, NULL, NULL); |
72 | 0 | if (client == -1) { |
73 | 0 | fprintf(stderr, "accept failed: %s\n", strerror(errno)); |
74 | 0 | exit(1); |
75 | 0 | } |
76 | | |
77 | 0 | res = recv(client, clientData, sizeof(clientData), 0); |
78 | 0 | if (res == -1) { |
79 | 0 | fprintf(stderr, "recv failed: %s\n", strerror(errno)); |
80 | 0 | exit(1); |
81 | 0 | } |
82 | 0 | res = send(client, fuzzer->buffer, fuzzer->size, 0); |
83 | 0 | if (res == -1) { |
84 | 0 | fprintf(stderr, "send failed: %s\n", strerror(errno)); |
85 | 0 | exit(1); |
86 | 0 | } |
87 | | |
88 | 0 | res = shutdown(client, SHUT_RDWR); |
89 | 0 | close(client); |
90 | 0 | return NULL; |
91 | 0 | } |
92 | | |
93 | 0 | void clean(Fuzzer *fuzzer) { |
94 | 0 | shutdown(fuzzer->socket, SHUT_RDWR); |
95 | 0 | close(fuzzer->socket); |
96 | 0 | free(fuzzer->buffer); |
97 | 0 | free(fuzzer); |
98 | 0 | } |
99 | | |
100 | 44 | extern int LLVMFuzzerTestOneInput(const char *data, size_t size) { |
101 | | |
102 | 44 | if (size < kMinInputLength || size > kMaxInputLength) { |
103 | 44 | return 0; |
104 | 44 | } |
105 | | |
106 | 0 | Fuzzer *fuzzer = (Fuzzer *)malloc(sizeof(Fuzzer)); |
107 | 0 | fuzzer->port = PORT; |
108 | |
|
109 | 0 | fuzzer->size = size; |
110 | 0 | fuzzer->buffer = malloc(fuzzer->size); |
111 | 0 | memcpy(fuzzer->buffer, data, size); |
112 | |
|
113 | 0 | fuzzinit(fuzzer); |
114 | |
|
115 | 0 | pthread_create(&fuzzer->thread, NULL, Server, fuzzer); |
116 | |
|
117 | 0 | client(fuzzer); |
118 | |
|
119 | 0 | pthread_join(fuzzer->thread, NULL); |
120 | |
|
121 | 0 | clean(fuzzer); |
122 | |
|
123 | 0 | return 0; |
124 | 44 | } |
125 | | |
126 | 0 | void client(Fuzzer *fuzzer) { |
127 | 0 | char const *hostname; |
128 | 0 | int status; |
129 | 0 | amqp_socket_t *socket = NULL; |
130 | 0 | amqp_connection_state_t conn; |
131 | |
|
132 | 0 | hostname = "127.0.0.1"; |
133 | |
|
134 | 0 | conn = amqp_new_connection(); |
135 | |
|
136 | 0 | socket = amqp_tcp_socket_new(conn); |
137 | 0 | if (!socket) { |
138 | 0 | exit(1); |
139 | 0 | } |
140 | | |
141 | 0 | status = amqp_socket_open(socket, hostname, fuzzer->port); |
142 | 0 | if (status != AMQP_STATUS_OK) { |
143 | 0 | int sav_errno = errno; |
144 | 0 | fprintf(stderr, "amqp_socket_open failed: %s\n", amqp_error_string2(status)); |
145 | 0 | fprintf(stderr, "amqp_socket_open errno: %d: %s\n", sav_errno, strerror(sav_errno)); |
146 | 0 | exit(1); |
147 | 0 | } |
148 | | |
149 | 0 | amqp_login(conn, "/", 0, 131072, 0, AMQP_SASL_METHOD_PLAIN, "guest", "guest"); |
150 | |
|
151 | 0 | amqp_destroy_connection(conn); |
152 | 0 | } |