summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Johnston <matt@ucc.asn.au>2015-12-02 22:37:20 +0800
committerMatt Johnston <matt@ucc.asn.au>2015-12-02 22:37:20 +0800
commit63b250cd79ba1ed60f667904e4ac73eeb1d03abb (patch)
tree8671bc5cf71a6bb29db478da97f133ba2f7e0e2d
parent7237a42a8996d547115b944bc56f501918d08394 (diff)
downloaddropbear-63b250cd79ba1ed60f667904e4ac73eeb1d03abb.tar.gz
ports and addresses must be malloced to avoid segfault on exit
-rw-r--r--runopts.h3
-rw-r--r--svr-runopts.c42
2 files changed, 24 insertions, 21 deletions
diff --git a/runopts.h b/runopts.h
index 62c9bf1..7d6ae06 100644
--- a/runopts.h
+++ b/runopts.h
@@ -72,7 +72,8 @@ typedef struct svr_runopts {
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];
diff --git a/svr-runopts.c b/svr-runopts.c
index 5bb51f2..0e70998 100644
--- a/svr-runopts.c
+++ b/svr-runopts.c
@@ -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 @@ void svr_getopts(int argc, char ** argv) {
}
}
-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);
}
}