changeset 1197:86a9e0204c03

ports and addresses must be malloced to avoid segfault on exit
author Matt Johnston <matt@ucc.asn.au>
date Wed, 02 Dec 2015 22:37:20 +0800
parents 8a5e9a97bd7a
children 388e5c3e380e
files runopts.h svr-runopts.c
diffstat 2 files changed, 24 insertions(+), 21 deletions(-) [+]
line wrap: on
line diff
--- a/runopts.h	Mon Nov 30 21:13:03 2015 +0800
+++ b/runopts.h	Wed Dec 02 22:37:20 2015 +0800
@@ -72,7 +72,8 @@
 	int forkbg;
 	int usingsyslog;
 
-	/* ports is an array of the portcount listening ports */
+	/* ports and addresses are arrays of the portcount 
+	listening ports. strings are malloced. */
 	char *ports[DROPBEAR_MAX_PORTS];
 	unsigned int portcount;
 	char *addresses[DROPBEAR_MAX_PORTS];
--- a/svr-runopts.c	Mon Nov 30 21:13:03 2015 +0800
+++ b/svr-runopts.c	Wed Dec 02 22:37:20 2015 +0800
@@ -33,7 +33,7 @@
 svr_runopts svr_opts; /* GLOBAL */
 
 static void printhelp(const char * progname);
-static void addportandaddress(char* spec);
+static void addportandaddress(const char* spec);
 static void loadhostkey(const char *keyfile, int fatal_duplicate);
 static void addhostkey(const char *keyfile);
 
@@ -348,54 +348,56 @@
 	}
 }
 
-static void addportandaddress(char* spec) {
-
-	char *myspec = NULL;
+static void addportandaddress(const char* spec) {
+	char *spec_copy = NULL, *myspec = NULL, *port = NULL, *address = NULL;
 
 	if (svr_opts.portcount < DROPBEAR_MAX_PORTS) {
 
 		/* We don't free it, it becomes part of the runopt state */
-		myspec = m_strdup(spec);
+		spec_copy = m_strdup(spec);
+		myspec = spec_copy;
 
 		if (myspec[0] == '[') {
 			myspec++;
-			svr_opts.ports[svr_opts.portcount] = strchr(myspec, ']');
-			if (svr_opts.ports[svr_opts.portcount] == NULL) {
+			port = strchr(myspec, ']');
+			if (!port) {
 				/* Unmatched [ -> exit */
 				dropbear_exit("Bad listen address");
 			}
-			svr_opts.ports[svr_opts.portcount][0] = '\0';
-			svr_opts.ports[svr_opts.portcount]++;
-			if (svr_opts.ports[svr_opts.portcount][0] != ':') {
+			port[0] = '\0';
+			port++;
+			if (port[0] != ':') {
 				/* Missing port -> exit */
 				dropbear_exit("Missing port");
 			}
 		} else {
 			/* search for ':', that separates address and port */
-			svr_opts.ports[svr_opts.portcount] = strrchr(myspec, ':');
+			port = strrchr(myspec, ':');
 		}
 
-		if (svr_opts.ports[svr_opts.portcount] == NULL) {
+		if (!port) {
 			/* no ':' -> the whole string specifies just a port */
-			svr_opts.ports[svr_opts.portcount] = myspec;
+			port = myspec;
 		} else {
 			/* Split the address/port */
-			svr_opts.ports[svr_opts.portcount][0] = '\0'; 
-			svr_opts.ports[svr_opts.portcount]++;
-			svr_opts.addresses[svr_opts.portcount] = myspec;
+			port[0] = '\0'; 
+			port++;
+			address = myspec;
 		}
 
-		if (svr_opts.addresses[svr_opts.portcount] == NULL) {
+		if (!address) {
 			/* no address given -> fill in the default address */
-			svr_opts.addresses[svr_opts.portcount] = m_strdup(DROPBEAR_DEFADDRESS);
+			address = DROPBEAR_DEFADDRESS;
 		}
 
-		if (svr_opts.ports[svr_opts.portcount][0] == '\0') {
+		if (port[0] == '\0') {
 			/* empty port -> exit */
 			dropbear_exit("Bad port");
 		}
-
+		svr_opts.ports[svr_opts.portcount] = m_strdup(port);
+		svr_opts.addresses[svr_opts.portcount] = m_strdup(address);
 		svr_opts.portcount++;
+		m_free(spec_copy);
 	}
 }