Thanks to visit codestin.com
Credit goes to github.com

Skip to content

curl crash due to hostent has h_name == NULL #1114

@dzatvorniy

Description

@dzatvorniy

I did this

APP with libcurl crash sometimes (It happens in very rare situations, but happens)

#0 0xf74a11c1 in ?? () from /lib32/libc.so.6
#1 0xf74a0e3d in strdup () from /lib32/libc.so.6
#2 0x08b8dd76 in Curl_he2ai ()
#3 0x08b7fae3 in Curl_ipv4_resolve_r ()
#4 0x08b7fa4b in Curl_getaddrinfo ()
#5 0x08b7a818 in Curl_resolv ()
#6 0x08b7a911 in Curl_resolv_timeout ()
#7 0x08b85c44 in resolve_server ()
#8 0x08b86722 in create_conn ()
#9 0x08b86945 in Curl_connect ()
...

I expected the following

In function Curl_he2ai

Curl_addrinfo *
Curl_he2ai(const struct hostent *he, int port)
{
    Curl_addrinfo *ai;
    Curl_addrinfo *prevai = NULL;
    Curl_addrinfo *firstai = NULL;
    struct sockaddr_in *addr;
    #ifdef ENABLE_IPV6
    struct sockaddr_in6 *addr6;
    #endif
    CURLcode result = CURLE_OK;
    int i;
    char *curr;

    if(!he)
    /* no input == no output! */
        return NULL;

    DEBUGASSERT((he->h_name != NULL) && (he->h_addr_list != NULL));

    for(i=0; (curr = he->h_addr_list[i]) != NULL; i++) {

        size_t ss_size;
        #ifdef ENABLE_IPV6
        if(he->h_addrtype == AF_INET6)
            ss_size = sizeof (struct sockaddr_in6);
        else
        #endif
            ss_size = sizeof (struct sockaddr_in);

        if((ai = calloc(1, sizeof(Curl_addrinfo))) == NULL) {
            result = CURLE_OUT_OF_MEMORY;
            break;
        }
    if((ai->ai_canonname = strdup(he->h_name)) == NULL) {
       result = CURLE_OUT_OF_MEMORY;
        free(ai);
        break;
    }
...

Curl has DEBUGASSERT, but does not have any check on a NULL pointer in a release, so we get undefined behavior when passing a NULL pointer to strdup, so we have a crash.

I propose to add a check

/* prevent crash after assert! */
if (he->h_name == NULL || he->h_addr_list == NULL)
  return NULL;

curl/libcurl version

For All versions

operating system

Debian 8 GNU/Linux

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions