From 76c7d269bf6b81b118c861bc0e7c34ea4983b16a Mon Sep 17 00:00:00 2001 From: Tom Carroll <34632752+tomc797@users.noreply.github.com> Date: Tue, 13 Jun 2023 21:51:20 -0700 Subject: [PATCH] Handle case of host == NULL The fix addresses two defects. The getaddrinfo interface contract allowed for host == NULL, but Ziti_resolve assumed host != NULL. Additionally, Ziti_resolve would leak res and addr if the function wasn't successful. Signed-off-by: Tom Carroll <4632752+tomc797@users.noreply.github.com> --- library/zitilib.c | 73 +++++++++++++++++++++++++++++++---------------- 1 file changed, 48 insertions(+), 25 deletions(-) diff --git a/library/zitilib.c b/library/zitilib.c index c0c1982b..7504324d 100644 --- a/library/zitilib.c +++ b/library/zitilib.c @@ -1226,6 +1226,15 @@ int Ziti_resolve(const char *host, const char *port, const struct addrinfo *hint 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)); + union { + struct sockaddr_in s4; + struct sockaddr_in6 s6; + } *addr = calloc(1, sizeof *addr); + int af = AF_UNSPEC; + + if (!res || !addr) + goto error; + if (hints) { res->ai_socktype = hints->ai_socktype; switch (hints->ai_socktype) { @@ -1239,27 +1248,34 @@ 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: + af = 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 ((af == AF_UNSPEC || af == AF_INET) && uv_ip4_addr(host ? host : "127.0.0.1", portnum, &addr->s4) == 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 = (struct sockaddr*)&addr->s4; + res->ai_addrlen = sizeof addr->s4; *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 ((af == AF_UNSPEC || af == AF_INET6) && uv_ip6_addr(host ? host : "::1", portnum, &addr->s6) == 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 = (struct sockaddr*)&addr->s6; + res->ai_addrlen = sizeof addr->s6; *addrlist = res; return 0; } @@ -1273,14 +1289,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; } } } @@ -1300,21 +1316,28 @@ 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->s4.sin_family = AF_INET; + addr->s4.sin_port = htons(portnum); + addr->s4.sin_addr.s_addr = (in_addr_t)(uintptr_t)f->result; + + res->ai_family = AF_INET; + res->ai_addr = (struct sockaddr*)&addr->s4; + res->ai_socktype = hints->ai_socktype; + + res->ai_addrlen = sizeof addr->s4; + *addrlist = res; - res->ai_addrlen = sizeof(*addr4); - *addrlist = res; - } destroy_future(f); - return err == 0 ? 0 : -1; + return 0; + +error: + free(res); + free(addr); + return -1; } int Ziti_check_socket(ziti_socket_t fd) {