[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Trinity is a syscall fuzz tool for local host testing. But it would also be
very useful to fuzz during established sessions over the network. This patch
add simple connection ability for IPv4/IPv6 so user can use it as a
client/server and simulate as a real environment.

Signed-off-by: Hangbin Liu <liuhangbin@xxxxxxxxx>
---
 include/net.h    |  2 ++
 include/params.h |  3 +++
 net/proto-ipv4.c | 13 +++++++++++++
 net/proto-ipv6.c | 14 ++++++++++++++
 params.c         | 25 +++++++++++++++++++++----
 5 files changed, 53 insertions(+), 4 deletions(-)

diff --git a/include/net.h b/include/net.h
index 15c51a6..d7a0f0f 100644
--- a/include/net.h
+++ b/include/net.h
@@ -13,6 +13,8 @@ extern unsigned int nr_sockets;
 /* protocol decoding */
 extern unsigned int specific_proto;
 
+extern int server_port;
+extern char server_addr[INET6_ADDRSTRLEN];
 
 /* glibc headers might be older than the kernel, so chances are we know
  * about more protocols than glibc does. So we define our own PF_MAX */
diff --git a/include/params.h b/include/params.h
index 2ee0f7b..40d213e 100644
--- a/include/params.h
+++ b/include/params.h
@@ -52,3 +52,6 @@ extern unsigned int kernel_taint_mask;
 extern bool kernel_taint_param_occured;
 
 extern unsigned int user_specified_children;
+
+extern int server_port;
+extern char server_addr[INET6_ADDRSTRLEN];
diff --git a/net/proto-ipv4.c b/net/proto-ipv4.c
index 8babe6d..976197f 100644
--- a/net/proto-ipv4.c
+++ b/net/proto-ipv4.c
@@ -85,12 +85,25 @@ in_addr_t random_ipv4_address(void)
 void ipv4_gen_sockaddr(struct sockaddr **addr, socklen_t *addrlen)
 {
 	struct sockaddr_in *ipv4;
+	struct in_addr serv_addr;
 
 	ipv4 = zmalloc(sizeof(struct sockaddr_in));
 
 	ipv4->sin_family = PF_INET;
 	ipv4->sin_addr.s_addr = random_ipv4_address();
 	ipv4->sin_port = htons(rand() % 65535);
+
+	/* Client side if we supplied server_addr */
+	if (inet_pton(PF_INET, server_addr, &serv_addr) == 1)
+		ipv4->sin_addr = serv_addr;
+	/* Server side if we supplied port without addr, so listen on INADDR_ANY */
+	else if (server_port != 0)
+		ipv4->sin_addr.s_addr = htonl(INADDR_ANY);
+
+	/* Fuzz from port to (port + 100) if supplied */
+	if (server_port != 0)
+		ipv4->sin_port = htons(server_port + rand() % 100);
+
 	*addr = (struct sockaddr *) ipv4;
 	*addrlen = sizeof(struct sockaddr_in);
 }
diff --git a/net/proto-ipv6.c b/net/proto-ipv6.c
index 16bceb3..bf62897 100644
--- a/net/proto-ipv6.c
+++ b/net/proto-ipv6.c
@@ -5,6 +5,7 @@
 #include <linux/if.h>
 #include <linux/if_arp.h>
 #include <linux/if_packet.h>
+#include <arpa/inet.h>
 #include <stdlib.h>
 #include "net.h"
 #include "random.h"
@@ -14,6 +15,7 @@
 void ipv6_gen_sockaddr(struct sockaddr **addr, socklen_t *addrlen)
 {
 	struct sockaddr_in6 *ipv6;
+	struct in6_addr serv_addr;
 
 	ipv6 = zmalloc(sizeof(struct sockaddr_in6));
 
@@ -23,6 +25,18 @@ void ipv6_gen_sockaddr(struct sockaddr **addr, socklen_t *addrlen)
 	ipv6->sin6_addr.s6_addr32[2] = 0;
 	ipv6->sin6_addr.s6_addr32[3] = htonl(1);
 	ipv6->sin6_port = htons(rand() % 65535);
+
+	/* Client side if we supplied server_addr */
+	if (inet_pton(PF_INET6, server_addr, &serv_addr) == 1)
+		ipv6->sin6_addr = serv_addr;
+	/* Server side if we supplied port without addr, so listen on in6addr_any */
+	else if (server_port != 0)
+		ipv6->sin6_addr = in6addr_any;
+
+	/* Fuzz from port to (port + 100) if supplied */
+	if (server_port != 0)
+		ipv6->sin6_port = htons(server_port + rand() % 100);
+
 	*addr = (struct sockaddr *) ipv6;
 	*addrlen = sizeof(struct sockaddr_in6);
 }
diff --git a/params.c b/params.c
index df702e3..c8eef3a 100644
--- a/params.c
+++ b/params.c
@@ -57,6 +57,9 @@ char *victim_path = NULL;
 unsigned int kernel_taint_mask = 0xFFFFFFFF;
 bool kernel_taint_param_occured = FALSE;
 
+int server_port = 0;
+char server_addr[INET6_ADDRSTRLEN] = "\0";
+
 static void usage(void)
 {
 	outputerr("%s\n", progname);
@@ -77,6 +80,8 @@ static void usage(void)
 	outputerr(" --no_proto,-E: specify network protocols to be excluded from testing.\n");
 	outputerr(" --quiet,-q: less output.\n");
 	outputerr(" --random,-r#: pick N syscalls at random and just fuzz those\n");
+	outputerr(" --server_addr: supply an IPv4 or IPv6 address to connect, no need for server side.\n");
+	outputerr(" --server_port: supply an server port to listen or connect, will fuzz between port to (port + 100)\n");
 	outputerr(" --syslog,-S: log important info to syslog. (useful if syslog is remote)\n");
 	outputerr(" --verbose,-v: increase output verbosity.\n");
 	outputerr(" --victims,-V: path to victim files.\n");
@@ -110,6 +115,8 @@ static const struct option longopts[] = {
 	{ "proto", required_argument, NULL, 'P' },
 	{ "quiet", no_argument, NULL, 'q' },
 	{ "random", required_argument, NULL, 'r' },
+	{ "server_addr", required_argument, NULL, 0 },
+	{ "server_port", required_argument, NULL, 0 },
 	{ "syslog", no_argument, NULL, 'S' },
 	{ "verbose", no_argument, NULL, 'v' },
 	{ "victims", required_argument, NULL, 'V' },
@@ -118,8 +125,9 @@ static const struct option longopts[] = {
 void parse_args(int argc, char *argv[])
 {
 	int opt;
+	int opt_index = 0;
 
-	while ((opt = getopt_long(argc, argv, paramstr, longopts, NULL)) != -1) {
+	while ((opt = getopt_long(argc, argv, paramstr, longopts, &opt_index)) != -1) {
 		switch (opt) {
 		default:
 			if (opt == '?')
@@ -128,9 +136,6 @@ void parse_args(int argc, char *argv[])
 				outputstd("opt:%c\n", opt);
 			return;
 
-		case '\0':
-			return;
-
 		case 'b':
 			init_bdev_list();
 			process_bdev_param(optarg);
@@ -294,6 +299,18 @@ void parse_args(int argc, char *argv[])
 		case 'X':
 			dropprivs = TRUE;
 			break;
+
+		case 0:
+			/*
+			 * FIXME: It's really hard to find two reasonable short
+			 * names since S s P p all have been used. Use long
+			 * options before we fix this issue.
+			*/
+			if (strcmp("server_addr", longopts[opt_index].name) == 0)
+				strcpy(server_addr, optarg);
+			if (strcmp("server_port", longopts[opt_index].name) == 0)
+				server_port = atoi(optarg);
+			break;
 		}
 	}
 	if (quiet_level > MAX_LOGLEVEL)
-- 
1.9.3

--
To unsubscribe from this list: send the line "unsubscribe trinity" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux SCSI]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux