Browse Source

Fuzz test: Fix all build warnings

bel2125 4 năm trước cách đây
mục cha
commit
cfe2afa545
4 tập tin đã thay đổi với 242 bổ sung166 xóa
  1. 3 3
      fuzztest/build.sh
  2. 3 3
      fuzztest/build_and_run.sh
  3. 24 0
      fuzztest/build_with_all.sh
  4. 212 160
      fuzztest/fuzzmain.c

+ 3 - 3
fuzztest/build.sh

@@ -3,11 +3,11 @@
 make clean
 rm civetweb_fuzz?
 
-make WITH_ALL=1 TEST_FUZZ=1
+make TEST_FUZZ=1
 mv civetweb civetweb_fuzz1
-make WITH_ALL=1 TEST_FUZZ=2
+make TEST_FUZZ=2
 mv civetweb civetweb_fuzz2
-make WITH_ALL=1 TEST_FUZZ=3
+make TEST_FUZZ=3
 mv civetweb civetweb_fuzz3
 
 echo ""

+ 3 - 3
fuzztest/build_and_run.sh

@@ -11,7 +11,7 @@ echo "== run fuzz test 1 =="
 echo "====================="
 echo ""
 
-./civetweb_fuzz1 -max_total_time=600 -max_len=2048 fuzztest/url/
+./civetweb_fuzz1 -max_total_time=60 -max_len=2048 fuzztest/url/
 
 echo ""
 echo "====================="
@@ -19,7 +19,7 @@ echo "== run fuzz test 2 =="
 echo "====================="
 echo ""
 
-./civetweb_fuzz2 -max_total_time=600 -max_len=2048 -dict=fuzztest/http1.dict fuzztest/http1/
+./civetweb_fuzz2 -max_total_time=60 -max_len=2048 -dict=fuzztest/http1.dict fuzztest/http1/
 
 echo ""
 echo "====================="
@@ -27,7 +27,7 @@ echo "== run fuzz test 3 =="
 echo "====================="
 echo ""
 
-./civetweb_fuzz3 -max_total_time=600 -max_len=2048 -dict=fuzztest/http1.dict fuzztest/http1c/
+./civetweb_fuzz3 -max_total_time=60 -max_len=2048 -dict=fuzztest/http1.dict fuzztest/http1c/
 
 echo ""
 echo "====================="

+ 24 - 0
fuzztest/build_with_all.sh

@@ -0,0 +1,24 @@
+#!/bin/sh
+
+make clean
+rm civetweb_fuzz?
+
+make WITH_ALL=1 TEST_FUZZ=1
+mv civetweb civetweb_fuzz1
+make WITH_ALL=1 TEST_FUZZ=2
+mv civetweb civetweb_fuzz2
+make WITH_ALL=1 TEST_FUZZ=3
+mv civetweb civetweb_fuzz3
+
+echo ""
+echo "====================="
+echo "== Build completed =="
+echo "====================="
+echo ""
+
+ls -halt civetweb*
+md5sum civetweb_fuzz*
+
+echo ""
+echo "====================="
+echo ""

+ 212 - 160
fuzztest/fuzzmain.c

@@ -19,7 +19,7 @@
 typedef int SOCKET;
 #define closesocket(a) (close(a))
 
-#endif
+#endif // not _WIN32
 
 
 /* Port configuration */
@@ -28,6 +28,7 @@ unsigned short PORT_NUM_HTTP = 0; /* set dynamically */
 
 #define TESTabort()                                                            \
 	{                                                                          \
+		fprintf(stderr, "!!! Precondition in test environment not met !!!\n"); \
 		fprintf(stderr, "!!! aborting fuzz test in line %u !!!", __LINE__);    \
 		abort();                                                               \
 	}
@@ -35,7 +36,13 @@ unsigned short PORT_NUM_HTTP = 0; /* set dynamically */
 
 static uint64_t call_count = 0;
 
-static struct mg_context *ctx;
+
+/********************************************************/
+/* Init CivetWeb server ... test with mock client       */
+/********************************************************/
+#if defined(TEST_FUZZ1) || defined(TEST_FUZZ2)
+
+static struct mg_context *ctx = 0;
 static const char *OPTIONS[] = {"listening_ports",
                                 "0", /* port: auto */
                                 "document_root",
@@ -43,16 +50,24 @@ static const char *OPTIONS[] = {"listening_ports",
                                 NULL,
                                 NULL};
 
+static void
+civetweb_exit(void)
+{
+	printf("CivetWeb server exit\n");
+	mg_stop(ctx);
+	ctx = 0;
+	test_sleep(5);
+}
+
 
 static void
-init_civetweb(void)
+civetweb_init(void)
 {
 	struct mg_callbacks callbacks;
 	struct mg_server_port ports[8];
 	memset(&callbacks, 0, sizeof(callbacks));
 	memset(&ports, 0, sizeof(ports));
 
-
 	ctx = mg_start(&callbacks, 0, OPTIONS);
 
 	if (!ctx) {
@@ -81,160 +96,16 @@ init_civetweb(void)
 	 * when testing starting/stopping the server multiple times in test
 	 * container environments. */
 	test_sleep(5);
+	atexit(civetweb_exit);
 }
 
 
-struct tcp_func_prm {
-	SOCKET sock;
-};
-
-
-struct tRESPONSE {
-	char data[4096];
-	size_t size;
-} RESPONSE;
-
-
-static void *
-tcp_func(void *arg)
-{
-	char req[1024 * 16];
-	SOCKET svr = (SOCKET)(-1);
-
-	/* Get thread parameters and free arg */
-	{
-		struct tcp_func_prm *ptcp_func_prm = (struct tcp_func_prm *)arg;
-		svr = ptcp_func_prm->sock;
-		free(arg);
-	}
-
-	printf("MOCK server ready, sock %i\n", svr);
-
-next_request : {
-	struct sockaddr_in cliadr;
-	socklen_t adrlen = sizeof(cliadr);
-	int buf_filled = 0;
-	int req_ready = 0;
-
-	memset(&cliadr, 0, sizeof(cliadr));
-
-	SOCKET cli = accept(svr, (struct sockaddr *)&cliadr, &adrlen);
-
-	if (cli == -1) {
-		int er = errno;
-		fprintf(stderr, "Error: Accept failed [%s]\n", strerror(er));
-		test_sleep(1);
-		goto next_request;
-	}
-
-	/* Read request */
-	do {
-		int r = recv(cli, req + buf_filled, sizeof(req) - buf_filled - 1, 0);
-		if (r > 0) {
-			buf_filled += r;
-			req[buf_filled] = 0;
-			if (strstr(req, "\r\n\r\n") != NULL) {
-				req_ready = 1;
-			}
-		} else {
-			/* some error */
-			int er = errno;
-			fprintf(stderr, "Error: Recv failed [%s]\n", strerror(er));
-			test_sleep(1);
-			goto next_request;
-		}
-	} while (!req_ready);
-
-	/* Request is complete here.
-	 * Now send response */
-	send(cli, RESPONSE.data, RESPONSE.size, MSG_NOSIGNAL);
-
-	/* Close connection. */
-	shutdown(cli, SHUT_RDWR);
-	closesocket(cli);
-
-	/* done */
-	goto next_request;
-}
-}
-
-
-static void
-init_tcp(void)
-{
-	int r;
-	int bind_success = 0;
-	SOCKET sock = socket(AF_INET, SOCK_STREAM, 6);
-	if (sock == -1) {
-		r = errno;
-		fprintf(stderr, "Error: Cannot create socket [%s]\n", strerror(r));
-		TESTabort();
-	}
-
-	for (PORT_NUM_HTTP = 1024; PORT_NUM_HTTP != 0; PORT_NUM_HTTP++) {
-		struct sockaddr_in sin;
-		memset(&sin, 0, sizeof(sin));
-		sin.sin_family = AF_INET;
-		sin.sin_addr.s_addr = inet_addr("127.0.0.1");
-		sin.sin_port = htons(PORT_NUM_HTTP);
-		r = bind(sock, (struct sockaddr *)&sin, sizeof(sin));
-		if (r == 0) {
-			bind_success = 1;
-			break;
-		}
-		r = errno;
-		fprintf(stderr, "Warning: Cannot bind [%s]\n", strerror(r));
-	}
-
-	if (!bind_success) {
-		fprintf(stderr, "Error: Cannot bind to any port\n");
-		closesocket(sock);
-		TESTabort();
-	}
-
-	printf("MOCK server running on port %i\n", (int)PORT_NUM_HTTP);
-
-	r = listen(sock, 128);
-	if (r != 0) {
-		r = errno;
-		fprintf(stderr, "Error: Cannot listen [%s]\n", strerror(r));
-		closesocket(sock);
-		TESTabort();
-	}
-
-	pthread_t thread_id;
-	pthread_attr_t attr;
-	int result;
-	struct tcp_func_prm *thread_prm;
-
-	thread_prm = (struct tcp_func_prm *)malloc(sizeof(struct tcp_func_prm));
-	if (!thread_prm) {
-		fprintf(stderr, "Error: Out of memory\n");
-		closesocket(sock);
-		TESTabort();
-	}
-	thread_prm->sock = sock;
-
-	(void)pthread_attr_init(&attr);
-	(void)pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
-	result = pthread_create(&thread_id, &attr, tcp_func, (void *)thread_prm);
-	(void)pthread_attr_destroy(&attr);
-	if (result != 0) {
-		r = errno;
-		fprintf(stderr, "Error: Cannot create thread [%s]\n", strerror(r));
-		closesocket(sock);
-		TESTabort();
-	}
-
-	test_sleep(5);
-}
-
-
+#if defined(TEST_FUZZ1)
 static int
-test_http_request(const char *server,
-                  uint16_t port,
-                  int use_ssl,
-                  const char *uri)
+test_civetweb_client(const char *server,
+                     uint16_t port,
+                     int use_ssl,
+                     const char *uri)
 {
 	/* Client var */
 	struct mg_connection *client;
@@ -328,7 +199,7 @@ LLVMFuzzerTestOneInput_URI(const uint8_t *data, size_t size)
 
 	if (call_count == 0) {
 		memset(URI, 0, sizeof(URI));
-		init_civetweb();
+		civetweb_init();
 	}
 	call_count++;
 
@@ -339,15 +210,17 @@ LLVMFuzzerTestOneInput_URI(const uint8_t *data, size_t size)
 		return 1;
 	}
 
-	return test_http_request("127.0.0.1", PORT_NUM_HTTP, 0, URI);
+	return test_civetweb_client("127.0.0.1", PORT_NUM_HTTP, 0, URI);
 }
+#endif
 
 
+#if defined(TEST_FUZZ2)
 static int
 LLVMFuzzerTestOneInput_REQUEST(const uint8_t *data, size_t size)
 {
 	if (call_count == 0) {
-		init_civetweb();
+		civetweb_init();
 	}
 	call_count++;
 
@@ -373,7 +246,7 @@ LLVMFuzzerTestOneInput_REQUEST(const uint8_t *data, size_t size)
 
 	char trash[1024];
 	r = send(sock, data, size, 0);
-	if (r != size) {
+	if (r != (int)size) {
 		fprintf(stderr, "Warning: %i bytes sent (TODO: Repeat)\n", r);
 	}
 
@@ -390,6 +263,176 @@ LLVMFuzzerTestOneInput_REQUEST(const uint8_t *data, size_t size)
 		max_data_read = data_read;
 		printf("GOT data: %i\n", data_read);
 	}
+	return 0;
+}
+#endif
+
+#endif // defined(TEST_FUZZ1) || defined(TEST_FUZZ2)
+
+
+/********************************************************/
+/* Init mock server ... test with CivetWeb client       */
+/********************************************************/
+#if defined(TEST_FUZZ3)
+
+struct tcp_func_prm {
+	SOCKET sock;
+};
+
+struct tRESPONSE {
+	char data[4096];
+	size_t size;
+} RESPONSE;
+
+
+volatile int mock_server_stop_flag = 0;
+
+static void
+mock_server_exit(void)
+{
+	printf("MOCK server exit\n");
+	mock_server_stop_flag = 1;
+	test_sleep(5);
+}
+
+
+static void *
+mock_server_thread(void *arg)
+{
+	char req[1024 * 16];
+	SOCKET svr = (SOCKET)(-1);
+
+	/* Get thread parameters and free arg */
+	{
+		struct tcp_func_prm *ptcp_func_prm = (struct tcp_func_prm *)arg;
+		svr = ptcp_func_prm->sock;
+		free(arg);
+	}
+
+	mock_server_stop_flag = 0;
+	printf("MOCK server ready, sock %i\n", svr);
+
+next_request:
+	while (!mock_server_stop_flag) {
+		struct sockaddr_in cliadr;
+		socklen_t adrlen = sizeof(cliadr);
+		int buf_filled = 0;
+		int req_ready = 0;
+
+		memset(&cliadr, 0, sizeof(cliadr));
+
+		SOCKET cli = accept(svr, (struct sockaddr *)&cliadr, &adrlen);
+
+		if (cli == -1) {
+			int er = errno;
+			fprintf(stderr, "Error: Accept failed [%s]\n", strerror(er));
+			test_sleep(1);
+			goto next_request;
+		}
+
+		/* Read request */
+		do {
+			int r =
+			    recv(cli, req + buf_filled, sizeof(req) - buf_filled - 1, 0);
+			if (r > 0) {
+				buf_filled += r;
+				req[buf_filled] = 0;
+				if (strstr(req, "\r\n\r\n") != NULL) {
+					req_ready = 1;
+				}
+			} else {
+				/* some error */
+				int er = errno;
+				fprintf(stderr, "Error: Recv failed [%s]\n", strerror(er));
+				test_sleep(1);
+				goto next_request;
+			}
+		} while (!req_ready);
+
+		/* Request is complete here.
+		 * Now send response */
+		send(cli, RESPONSE.data, RESPONSE.size, MSG_NOSIGNAL);
+
+		/* Close connection. */
+		shutdown(cli, SHUT_RDWR);
+		closesocket(cli);
+	}
+	return 0;
+}
+
+
+static void
+mock_server_init(void)
+{
+	int r;
+	int bind_success = 0;
+	SOCKET sock = socket(AF_INET, SOCK_STREAM, 6);
+	if (sock == -1) {
+		r = errno;
+		fprintf(stderr, "Error: Cannot create socket [%s]\n", strerror(r));
+		TESTabort();
+	}
+
+	for (PORT_NUM_HTTP = 1024; PORT_NUM_HTTP != 0; PORT_NUM_HTTP++) {
+		struct sockaddr_in sin;
+		memset(&sin, 0, sizeof(sin));
+		sin.sin_family = AF_INET;
+		sin.sin_addr.s_addr = inet_addr("127.0.0.1");
+		sin.sin_port = htons(PORT_NUM_HTTP);
+		r = bind(sock, (struct sockaddr *)&sin, sizeof(sin));
+		if (r == 0) {
+			bind_success = 1;
+			break;
+		}
+		r = errno;
+		fprintf(stderr, "Warning: Cannot bind [%s]\n", strerror(r));
+	}
+
+	if (!bind_success) {
+		fprintf(stderr, "Error: Cannot bind to any port\n");
+		closesocket(sock);
+		TESTabort();
+	}
+
+	printf("MOCK server running on port %i\n", (int)PORT_NUM_HTTP);
+
+	r = listen(sock, 128);
+	if (r != 0) {
+		r = errno;
+		fprintf(stderr, "Error: Cannot listen [%s]\n", strerror(r));
+		closesocket(sock);
+		TESTabort();
+	}
+
+	pthread_t thread_id;
+	pthread_attr_t attr;
+	int result;
+	struct tcp_func_prm *thread_prm;
+
+	thread_prm = (struct tcp_func_prm *)malloc(sizeof(struct tcp_func_prm));
+	if (!thread_prm) {
+		fprintf(stderr, "Error: Out of memory\n");
+		closesocket(sock);
+		TESTabort();
+	}
+	thread_prm->sock = sock;
+
+	(void)pthread_attr_init(&attr);
+	(void)pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+	result = pthread_create(&thread_id,
+	                        &attr,
+	                        mock_server_thread,
+	                        (void *)thread_prm);
+	(void)pthread_attr_destroy(&attr);
+	if (result != 0) {
+		r = errno;
+		fprintf(stderr, "Error: Cannot create thread [%s]\n", strerror(r));
+		closesocket(sock);
+		TESTabort();
+	}
+
+	test_sleep(3);
+	atexit(mock_server_exit);
 }
 
 
@@ -397,7 +440,7 @@ static int
 LLVMFuzzerTestOneInput_RESPONSE(const uint8_t *data, size_t size)
 {
 	if (call_count == 0) {
-		init_tcp();
+		mock_server_init();
 	}
 	call_count++;
 
@@ -422,13 +465,22 @@ LLVMFuzzerTestOneInput_RESPONSE(const uint8_t *data, size_t size)
 	int r = mg_get_response(conn, errbuf, sizeof(errbuf), 1000);
 	const struct mg_response_info *ri = mg_get_response_info(conn);
 
+	(void)r;
+	(void)ri;
+
 	mg_close_connection(conn);
 
 	return 0;
 }
 
+#endif // defined(TEST_FUZZ3)
+
+/********************************************************/
+/* MAIN for fuzztest                                    */
+/********************************************************/
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
+// warning: no previous prototype for function 'LLVMFuzzerTestOneInput'
 
-/* MAIN for fuzztest */
 int
 LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
 {