[PATCH v2 03/12] getaddrinfo: Fix leak with AI_ALL [BZ #28852]
DJ Delorie
dj@redhat.com
Wed Mar 16 23:42:39 GMT 2022
Siddhesh Poyarekar via Libc-alpha <libc-alpha@sourceware.org> writes:
> Use realloc in convert_hostent_to_gaih_addrtuple and fix up pointers in
> the result list so that a single block is maintained for
> hostbyname3_r/hostbyname2_r and freed in gaih_inet. This result is
> never merged with any other results, since the hosts database does not
> permit merging.
It took me a while to realize that you're basically converting the data
structure from a linked list to an array, and ensuring that it's always
handled as an array. That means the comment preceeding
convert_hostent_to_gaih_addrtuple() is no longer accurate and needs
updating. Ideally, the users could be optimized to treat it as an array
instead of a list, but it may need to remain a list-like type for
compatibility.
LGTM with that comment change.
Reviewed-by: DJ Delorie <dj@redhat.com>
> - while (*result)
> - result = &(*result)->next;
> -
Don't skip to end of "list". Ok.
> @@ -212,10 +209,30 @@ convert_hostent_to_gaih_addrtuple (const struct addrinfo *req,
> if (count == 0 || h->h_length > sizeof (((struct gaih_addrtuple) {}).addr))
> return true;
>
> - struct gaih_addrtuple *array = calloc (count, sizeof (*array));
> + struct gaih_addrtuple *array = *result;
> + size_t old = 0;
> +
> + while (array != NULL)
> + {
> + old++;
> + array = array->next;
> + }
> +
> + array = realloc (*result, (old + count) * sizeof (*array));
> +
Count existing members of *array* and resize base array. Ok. The rest
are initialized later, in the unchanged part of the code.
> if (array == NULL)
> return false;
>
> + *result = array;
> +
> + /* Update the next pointers on reallocation. */
> + for (size_t i = 0; i < old; i++)
> + array[i].next = array + i + 1;
> +
> + array += old;
> +
> + memset (array, 0, count * sizeof (*array));
> +
Ok.
> for (size_t i = 0; i < count; ++i)
> {
> if (family == AF_INET && req->ai_family == AF_INET6)
> @@ -235,7 +252,6 @@ convert_hostent_to_gaih_addrtuple (const struct addrinfo *req,
> array[0].name = h->h_name;
> array[count - 1].next = NULL;
>
> - *result = array;
> return true;
> }
Ok.
More information about the Libc-alpha
mailing list