From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2206) id E55873858407; Tue, 1 Mar 2022 02:40:41 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org E55873858407 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Siddhesh Poyarekar To: glibc-cvs@sourceware.org Subject: [glibc/siddhesh/gai-cleanup2] gaih_inet: Generic allocation tracking X-Act-Checkin: glibc X-Git-Author: Siddhesh Poyarekar X-Git-Refname: refs/heads/siddhesh/gai-cleanup2 X-Git-Oldrev: 056495f36f77d13e87ec41a2218d55a391fe3ffe X-Git-Newrev: 1ae1143f50f5ed704d314c79b3fffb2edbe4419b Message-Id: <20220301024041.E55873858407@sourceware.org> Date: Tue, 1 Mar 2022 02:40:41 +0000 (GMT) X-BeenThere: glibc-cvs@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Glibc-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 01 Mar 2022 02:40:42 -0000 https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=1ae1143f50f5ed704d314c79b3fffb2edbe4419b commit 1ae1143f50f5ed704d314c79b3fffb2edbe4419b Author: Siddhesh Poyarekar Date: Mon Feb 28 13:43:19 2022 +0530 gaih_inet: Generic allocation tracking Add tracking of allocations in gaih_inet so that all blocks allocated during lookup are freed at the end. Signed-off-by: Siddhesh Poyarekar Diff: --- sysdeps/posix/getaddrinfo.c | 77 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 70 insertions(+), 7 deletions(-) diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c index 28e9f9bd06..d3abc59ba9 100644 --- a/sysdeps/posix/getaddrinfo.c +++ b/sysdeps/posix/getaddrinfo.c @@ -116,6 +116,50 @@ struct gaih_typeproto char name[8]; }; +struct gaih_lookup_result +{ + struct gaih_addrtuple *at; /* The first result tuple. */ + struct scratch_buffer *allocs; /* Pointers to allocated tuples. */ + size_t nallocs; /* Count of such pointers. */ +}; + +/* Initialize RES with BUF, an initialized scratch buffer. */ + +static void +gaih_lookup_result_init (struct gaih_lookup_result *res, + struct scratch_buffer *buf) +{ + res->allocs = buf; +} + +/* Record BUF in RES as an allocated block. */ + +static bool +gaih_lookup_result_push_alloc (struct gaih_lookup_result *res, void *buf) +{ + size_t nallocs = res->nallocs + 1; + if (nallocs * sizeof (void *) > res->allocs->length + && !scratch_buffer_grow_preserve (res->allocs)) + return false; + + ((void **) res->allocs->data)[nallocs - 1] = buf; + res->nallocs = nallocs; + return true; +} + +/* Free up resources held in RES. */ + +static void +gaih_lookup_result_free (struct gaih_lookup_result *res) +{ + res->at = NULL; + size_t nallocs = res->nallocs; + while (nallocs-- > 0) + free (((void **) res->allocs->data)[nallocs]); + + res->nallocs = 0; +} + /* Values for `protoflag'. */ #define GAI_PROTO_NOSERVICE 1 #define GAI_PROTO_PROTOANY 2 @@ -416,9 +460,9 @@ get_servtuples (const struct gaih_service *service, const struct addrinfo *req, static int get_numeric_res (const char *name, const struct addrinfo *req, - struct gaih_addrtuple **pat) + struct gaih_lookup_result *res) { - *pat = NULL; + res->at = NULL; uint32_t addr[4] = {0}; if (__inet_aton_exact (name, (struct in_addr *) addr) != 0) @@ -454,7 +498,13 @@ get_numeric_res (const char *name, const struct addrinfo *req, at->name = canonbuf; } - *pat = at; + if (!gaih_lookup_result_push_alloc (res, at)) + { + free (at); + return -EAI_MEMORY; + } + + res->at = at; return 0; } @@ -505,7 +555,13 @@ get_numeric_res (const char *name, const struct addrinfo *req, at->name = canonbuf; } - *pat = at; + if (!gaih_lookup_result_push_alloc (res, at)) + { + free (at); + return -EAI_MEMORY; + } + + res->at = at; return 0; } @@ -540,6 +596,9 @@ gaih_inet (const char *name, const struct gaih_service *service, struct gaih_addrtuple *addrmem = NULL; char *canonbuf = NULL; int result = 0; + struct gaih_lookup_result res = {0}; + struct scratch_buffer resbuf; + scratch_buffer_init (&resbuf); if (name != NULL) { @@ -553,11 +612,13 @@ gaih_inet (const char *name, const struct gaih_service *service, malloc_name = true; } - if ((result = get_numeric_res (name, req, &at)) != 0) + gaih_lookup_result_init (&res, &resbuf); + + if ((result = get_numeric_res (name, req, &res)) != 0) goto free_and_return; - else if (at != NULL) + else if (res.at != NULL) { - addrmem = at; + at = res.at; canon = canonbuf = at->name; goto process_list; } @@ -1123,6 +1184,8 @@ gaih_inet (const char *name, const struct gaih_service *service, free ((char *) name); free (addrmem); free (canonbuf); + gaih_lookup_result_free (&res); + scratch_buffer_free (&resbuf); return result; }