Skip to content

Commit

Permalink
Handle case of host == NULL
Browse files Browse the repository at this point in the history
The fix addresses two defects. The getaddrinfo interface contract
allowed for host == NULL, but Ziti_resolve assumed host != NULL. zitify
nc -l 9999 would trigger a fault.  Additionally, hints was accessed
without checking to ensure it was NULL. Lastly, Ziti_resolve would leak
res and addr if the function wasn't successful.

Signed-off-by: Tom Carroll <4632752+tomc797@users.noreply.github.com>
  • Loading branch information
tomc797 committed Jun 16, 2023
1 parent d3a58bd commit 078b689
Showing 1 changed file with 66 additions and 26 deletions.
92 changes: 66 additions & 26 deletions library/zitilib.c
Original file line number Diff line number Diff line change
Expand Up @@ -1225,7 +1225,34 @@ ZITI_FUNC
int Ziti_resolve(const char *host, const char *port, const struct addrinfo *hints, struct addrinfo **addrlist) {
in_port_t portnum = port ? (in_port_t) strtol(port, NULL, 10) : 0;
ZITI_LOG(DEBUG, "host[%s] port[%s]", host, port);
struct addrinfo *res = calloc(1, sizeof(struct addrinfo));

/**
* Linux and FreeBSD freeaddrinfo(ai) frees ai->canonname and ai, but not ai->ai_addr.
* ai is allocated large enough to carry the sockaddr
*/
union sockaddr_union {
struct sockaddr sa;
struct sockaddr_in in4;
struct sockaddr_in6 in6;
};

struct result_storage {
struct addrinfo addrinfo;
union sockaddr_union sockaddr;
} *store = calloc(1, sizeof *store);

if (!store)
goto error;

struct addrinfo *res = &store->addrinfo;
union sockaddr_union *addr = &store->sockaddr;

res->ai_family = AF_UNSPEC;
res->ai_socktype = 0;
res->ai_protocol = 0;

addr->sa.sa_family = AF_UNSPEC;

if (hints) {
res->ai_socktype = hints->ai_socktype;
switch (hints->ai_socktype) {
Expand All @@ -1239,27 +1266,36 @@ int Ziti_resolve(const char *host, const char *port, const struct addrinfo *hint
res->ai_protocol = 0;
break;
default: // no other protocols are supported
return -1;
goto error;
}

switch (hints->ai_family) {
case AF_INET:
case AF_INET6:
case AF_UNSPEC:
res->ai_family = hints->ai_family;
break;
default: // unsupported address family
goto error;
}
}

struct sockaddr_in *addr4 = calloc(1, sizeof(struct sockaddr_in6));
int rc = 0;
if ((rc = uv_ip4_addr(host, portnum, addr4)) == 0) {
ZITI_LOG(DEBUG, "host[%s] port[%s] rc = %d", host, port, rc);
if ((res->ai_family == AF_UNSPEC || res->ai_family == AF_INET)
&& uv_ip4_addr(host ? host : "127.0.0.1", portnum, &addr->in4) == 0) {
ZITI_LOG(DEBUG, "host[%s] port[%s]", host, port);

res->ai_family = AF_INET;
res->ai_addr = (struct sockaddr *) addr4;
res->ai_addrlen = sizeof(struct sockaddr_in);

res->ai_addr = &addr->sa;
res->ai_addrlen = sizeof addr->in4;
*addrlist = res;
return 0;
} else if (uv_ip6_addr(host, portnum, (struct sockaddr_in6 *) addr4) == 0) {
ZITI_LOG(INFO, "host[%s] port[%s] rc = %d", host, port, rc);
} else if ((res->ai_family == AF_UNSPEC || res->ai_family == AF_INET6)
&& uv_ip6_addr(host ? host : "::1", portnum, &addr->in6) == 0) {
ZITI_LOG(INFO, "host[%s] port[%s]", host, port);

res->ai_family = AF_INET6;
res->ai_addr = (struct sockaddr *) addr4;
res->ai_addrlen = sizeof(struct sockaddr_in6);
res->ai_addr = &addr->sa;
res->ai_addrlen = sizeof addr->in6;
*addrlist = res;
return 0;
}
Expand All @@ -1273,14 +1309,14 @@ int Ziti_resolve(const char *host, const char *port, const struct addrinfo *hint
tlsuv_parse_url(&url, ctrl);

if (strncmp(host, url.hostname, url.hostname_len) == 0) {
return -1;
goto error;
}

if (wrap->ztx) {
MODEL_MAP_FOR(chit, wrap->ztx->channels) {
ziti_channel_t *ch = model_map_it_value(chit);
if (strcmp(ch->host, host) == 0) {
return -1;
goto error;
}
}
}
Expand All @@ -1300,21 +1336,25 @@ int Ziti_resolve(const char *host, const char *port, const struct addrinfo *hint
int err = await_future(f);
set_error(err);

if (err == 0) {
addr4->sin_family = AF_INET;
addr4->sin_port = htons(portnum);
addr4->sin_addr.s_addr = (in_addr_t)(uintptr_t)f->result;
if (err != 0)
goto error;

res->ai_family = AF_INET;
res->ai_addr = (struct sockaddr *) addr4;
res->ai_socktype = hints->ai_socktype;
addr->in4.sin_family = AF_INET;
addr->in4.sin_port = htons(portnum);
addr->in4.sin_addr.s_addr = (in_addr_t)(uintptr_t)f->result;

res->ai_family = AF_INET;
res->ai_addr = &addr->sa;
res->ai_addrlen = sizeof addr->in4;
*addrlist = res;

res->ai_addrlen = sizeof(*addr4);
*addrlist = res;
}
destroy_future(f);

return err == 0 ? 0 : -1;
return 0;

error:
free(store);
return -1;
}

int Ziti_check_socket(ziti_socket_t fd) {
Expand Down

0 comments on commit 078b689

Please sign in to comment.