mirror of
https://github.com/moparisthebest/curl
synced 2024-12-22 08:08:50 -05:00
Curl_getaddrinfo_ex: sanitize function results.
Ensure that spurious results from system's getaddrinfo() ares not propagated by Curl_getaddrinfo_ex() into the library. Also ensure that the ai_addrlen member of Curl_getaddrinfo_ex()'s output linked list of Curl_addrinfo structures has appropriate family-specific address size.
This commit is contained in:
parent
d212fe43af
commit
6fe18add71
@ -118,12 +118,12 @@ Curl_getaddrinfo_ex(const char *nodename,
|
|||||||
const struct addrinfo *hints,
|
const struct addrinfo *hints,
|
||||||
Curl_addrinfo **result)
|
Curl_addrinfo **result)
|
||||||
{
|
{
|
||||||
const struct addrinfo *ainext;
|
|
||||||
const struct addrinfo *ai;
|
const struct addrinfo *ai;
|
||||||
struct addrinfo *aihead;
|
struct addrinfo *aihead;
|
||||||
Curl_addrinfo *cafirst = NULL;
|
Curl_addrinfo *cafirst = NULL;
|
||||||
Curl_addrinfo *calast = NULL;
|
Curl_addrinfo *calast = NULL;
|
||||||
Curl_addrinfo *ca;
|
Curl_addrinfo *ca;
|
||||||
|
size_t ss_size;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
*result = NULL; /* assume failure */
|
*result = NULL; /* assume failure */
|
||||||
@ -132,7 +132,28 @@ Curl_getaddrinfo_ex(const char *nodename,
|
|||||||
if(error)
|
if(error)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
for(ai = aihead; ai != NULL; ai = ainext) {
|
/* traverse the addrinfo list */
|
||||||
|
|
||||||
|
for(ai = aihead; ai != NULL; ai = ai->ai_next) {
|
||||||
|
|
||||||
|
/* ignore elements with unsupported address family, */
|
||||||
|
/* settle family-specific sockaddr structure size. */
|
||||||
|
if(ai->ai_family == AF_INET)
|
||||||
|
ss_size = sizeof(struct sockaddr_in);
|
||||||
|
#ifdef ENABLE_IPV6
|
||||||
|
else if(ai->ai_family == AF_INET6)
|
||||||
|
ss_size = sizeof(struct sockaddr_in6);
|
||||||
|
#endif
|
||||||
|
else
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* ignore elements without required address info */
|
||||||
|
if((ai->ai_addr == NULL) || !(ai->ai_addrlen > 0))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* ignore elements with bogus address size */
|
||||||
|
if((size_t)ai->ai_addrlen < ss_size)
|
||||||
|
continue;
|
||||||
|
|
||||||
if((ca = malloc(sizeof(Curl_addrinfo))) == NULL) {
|
if((ca = malloc(sizeof(Curl_addrinfo))) == NULL) {
|
||||||
error = EAI_MEMORY;
|
error = EAI_MEMORY;
|
||||||
@ -140,35 +161,28 @@ Curl_getaddrinfo_ex(const char *nodename,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* copy each structure member individually, member ordering, */
|
/* copy each structure member individually, member ordering, */
|
||||||
/* size, or padding might be different for each structure. */
|
/* size, or padding might be different for each platform. */
|
||||||
|
|
||||||
ca->ai_flags = ai->ai_flags;
|
ca->ai_flags = ai->ai_flags;
|
||||||
ca->ai_family = ai->ai_family;
|
ca->ai_family = ai->ai_family;
|
||||||
ca->ai_socktype = ai->ai_socktype;
|
ca->ai_socktype = ai->ai_socktype;
|
||||||
ca->ai_protocol = ai->ai_protocol;
|
ca->ai_protocol = ai->ai_protocol;
|
||||||
ca->ai_addrlen = 0;
|
ca->ai_addrlen = (curl_socklen_t)ss_size;
|
||||||
ca->ai_addr = NULL;
|
ca->ai_addr = NULL;
|
||||||
ca->ai_canonname = NULL;
|
ca->ai_canonname = NULL;
|
||||||
ca->ai_next = NULL;
|
ca->ai_next = NULL;
|
||||||
|
|
||||||
if((ai->ai_addrlen > 0) && (ai->ai_addr != NULL)) {
|
if((ca->ai_addr = malloc(ss_size)) == NULL) {
|
||||||
/* typecast below avoid warning on at least win64:
|
error = EAI_MEMORY;
|
||||||
conversion from 'size_t' to 'curl_socklen_t', possible loss of data
|
free(ca);
|
||||||
*/
|
break;
|
||||||
ca->ai_addrlen = (curl_socklen_t)ai->ai_addrlen;
|
|
||||||
if((ca->ai_addr = malloc(ca->ai_addrlen)) == NULL) {
|
|
||||||
error = EAI_MEMORY;
|
|
||||||
free(ca);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
memcpy(ca->ai_addr, ai->ai_addr, ca->ai_addrlen);
|
|
||||||
}
|
}
|
||||||
|
memcpy(ca->ai_addr, ai->ai_addr, ss_size);
|
||||||
|
|
||||||
if(ai->ai_canonname != NULL) {
|
if(ai->ai_canonname != NULL) {
|
||||||
if((ca->ai_canonname = strdup(ai->ai_canonname)) == NULL) {
|
if((ca->ai_canonname = strdup(ai->ai_canonname)) == NULL) {
|
||||||
error = EAI_MEMORY;
|
error = EAI_MEMORY;
|
||||||
if(ca->ai_addr)
|
free(ca->ai_addr);
|
||||||
free(ca->ai_addr);
|
|
||||||
free(ca);
|
free(ca);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -183,8 +197,6 @@ Curl_getaddrinfo_ex(const char *nodename,
|
|||||||
calast->ai_next = ca;
|
calast->ai_next = ca;
|
||||||
calast = ca;
|
calast = ca;
|
||||||
|
|
||||||
/* fetch next element fom the addrinfo list */
|
|
||||||
ainext = ai->ai_next;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* destroy the addrinfo list */
|
/* destroy the addrinfo list */
|
||||||
|
Loading…
Reference in New Issue
Block a user