# HG changeset patch # User Matt Johnston # Date 1449067040 -28800 # Node ID 86a9e0204c03e2bf858eddef0cf745b3d31d12a5 # Parent 8a5e9a97bd7aa1ef7f80c72e030c91bac827be6c ports and addresses must be malloced to avoid segfault on exit diff -r 8a5e9a97bd7a -r 86a9e0204c03 runopts.h --- 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]; diff -r 8a5e9a97bd7a -r 86a9e0204c03 svr-runopts.c --- 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); } }