changeset 1785:9026f976eee8

fuzz: work around fuzz_connect_remote() limitations
author Matt Johnston <matt@ucc.asn.au>
date Sun, 06 Dec 2020 21:27:25 +0800 (2020-12-06)
parents 94323a20e572
children a3b39df57c8b
files cli-tcpfwd.c fuzz/fuzz-common.c svr-tcpfwd.c
diffstat 3 files changed, 10 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/cli-tcpfwd.c	Sat Dec 05 14:56:53 2020 +0800
+++ b/cli-tcpfwd.c	Sun Dec 06 21:27:25 2020 +0800
@@ -273,11 +273,11 @@
                 origaddr, origport);
 		goto out;
 	}
+
+	channel->prio = DROPBEAR_CHANNEL_PRIO_UNKNOWABLE;
 	
 	snprintf(portstring, sizeof(portstring), "%u", fwd->connectport);
 	channel->conn_pending = connect_remote(fwd->connectaddr, portstring, channel_connect_done, channel, NULL, NULL);
-
-	channel->prio = DROPBEAR_CHANNEL_PRIO_UNKNOWABLE;
 	
 	err = SSH_OPEN_IN_PROGRESS;
 
--- a/fuzz/fuzz-common.c	Sat Dec 05 14:56:53 2020 +0800
+++ b/fuzz/fuzz-common.c	Sun Dec 06 21:27:25 2020 +0800
@@ -238,6 +238,12 @@
 struct dropbear_progress_connection *fuzz_connect_remote(const char* UNUSED(remotehost), const char* UNUSED(remoteport),
     connect_callback cb, void* cb_data, 
     const char* UNUSED(bind_address), const char* UNUSED(bind_port)) {
+    /* This replacement for connect_remote() has slightly different semantics
+    to the real thing. It should probably be replaced with something more sophisticated.
+    It calls the callback cb() immediately rather than
+    in a future session loop iteration with set_connect_fds()/handle_connect_fds().
+    This could cause problems depending on how connect_remote() is used. In particular
+    the callback can close a channel - that can cause use-after-free. */
     char r;
     genrandom((void*)&r, 1);
     if (r & 1) {
--- a/svr-tcpfwd.c	Sat Dec 05 14:56:53 2020 +0800
+++ b/svr-tcpfwd.c	Sun Dec 06 21:27:25 2020 +0800
@@ -284,10 +284,10 @@
 		goto out;
 	}
 
+	channel->prio = DROPBEAR_CHANNEL_PRIO_UNKNOWABLE;
+
 	snprintf(portstring, sizeof(portstring), "%u", destport);
 	channel->conn_pending = connect_remote(desthost, portstring, channel_connect_done, channel, NULL, NULL);
-
-	channel->prio = DROPBEAR_CHANNEL_PRIO_UNKNOWABLE;
 	
 	err = SSH_OPEN_IN_PROGRESS;