From patchwork Thu May 12 12:09:00 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Weimer X-Patchwork-Id: 621450 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3r5BcP0RjRz9sBX for ; Thu, 12 May 2016 22:09:24 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.b=Eyp37f8l; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:date:to:subject:mime-version:content-type :content-transfer-encoding:message-id:from; q=dns; s=default; b= jmzPkVEW0R0imW4CLqotDdaZ2gvGcCHPUDNTCrGvOLooGe2cvD/MKWSYoPy+We7Z IwY0vwET8OCTPo+rLpxeTESywO8fsrUtZOPRWJWceC5fQ2sxCZlZFMjIzQ+qOl5J dGdB4amDuZY2N4fe3Lz9PRKKDgRupcQD0CoGUotJ1ec= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:date:to:subject:mime-version:content-type :content-transfer-encoding:message-id:from; s=default; bh=u6CXp9 BMajHBFvJMWO/MgCSWWag=; b=Eyp37f8lVL0JMxMdaHV4CzGVXgXO7yoiY+zZBJ zRW0b9aRVyVhU7uz0wpYMAl2tQsb3t7E8j3nQg/nN/7FgopNBI8QI+si5QapNVNR lqLONhCVbkMkXkh2mQBNU0brh5doi1rI2atZQB9I8fAVyTNk1vFWOZ0+4UO83cIY byCcs= Received: (qmail 128098 invoked by alias); 12 May 2016 12:09:14 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 128069 invoked by uid 89); 12 May 2016 12:09:13 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-3.3 required=5.0 tests=BAYES_00, RP_MATCHES_RCVD, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=Net, 8459, advised X-HELO: mx1.redhat.com Date: Thu, 12 May 2016 14:09:00 +0200 To: libc-alpha@sourceware.org Subject: [PATCH COMMITTED] getaddrinfo: Convert from extend_alloca to struct scratch_buffer User-Agent: Heirloom mailx 12.5 7/5/10 MIME-Version: 1.0 Message-Id: <20160512120900.95BF640191DCA@oldenburg.str.redhat.com> From: fweimer@redhat.com (Florian Weimer) 2016-05-12 Florian Weimer * sysdeps/posix/getaddrinfo.c (gaih_inet_serv): Add tmpbuf argument. Use scratch buffer instead of extend_alloca. (gethosts): Use scratch buffer instead of extend_alloca. (gaih_inet): Add tmpbuf argument. Use scratch buffer instead of extend_alloca. (getaddrinfo): Allocate scratch buffer and pass it to gaih_inet. diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c index c670a98..574ce08 100644 --- a/sysdeps/posix/getaddrinfo.c +++ b/sysdeps/posix/getaddrinfo.c @@ -1,3 +1,21 @@ +/* Host and service name lookups using Name Service Switch modules. + Copyright (C) 1996-2016 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + /* The Inner Net License, Version 2.00 The author(s) grant permission for redistribution and use in source and @@ -63,6 +81,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include #include +#include #ifdef HAVE_LIBIDN extern int __idna_to_ascii_lz (const char *input, char **output, int flags); @@ -135,24 +154,24 @@ static const struct addrinfo default_hints = static int gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp, - const struct addrinfo *req, struct gaih_servtuple *st) + const struct addrinfo *req, struct gaih_servtuple *st, + struct scratch_buffer *tmpbuf) { struct servent *s; - size_t tmpbuflen = 1024; struct servent ts; - char *tmpbuf; int r; do { - tmpbuf = __alloca (tmpbuflen); - - r = __getservbyname_r (servicename, tp->name, &ts, tmpbuf, tmpbuflen, - &s); + r = __getservbyname_r (servicename, tp->name, &ts, + tmpbuf->data, tmpbuf->length, &s); if (r != 0 || s == NULL) { if (r == ERANGE) - tmpbuflen *= 2; + { + if (!scratch_buffer_grow (tmpbuf)) + return -EAI_MEMORY; + } else return -EAI_SERVICE; } @@ -227,26 +246,15 @@ convert_hostent_to_gaih_addrtuple (const struct addrinfo *req, no_data = 0; \ while (1) { \ rc = 0; \ - status = DL_CALL_FCT (fct, (name, _family, &th, tmpbuf, tmpbuflen, \ + status = DL_CALL_FCT (fct, (name, _family, &th, \ + tmpbuf->data, tmpbuf->length, \ &rc, &herrno, NULL, &localcanon)); \ if (rc != ERANGE || herrno != NETDB_INTERNAL) \ break; \ - if (!malloc_tmpbuf && __libc_use_alloca (alloca_used + 2 * tmpbuflen)) \ - tmpbuf = extend_alloca_account (tmpbuf, tmpbuflen, 2 * tmpbuflen, \ - alloca_used); \ - else \ + if (!scratch_buffer_grow (tmpbuf)) \ { \ - char *newp = realloc (malloc_tmpbuf ? tmpbuf : NULL, \ - 2 * tmpbuflen); \ - if (newp == NULL) \ - { \ - _res.options |= old_res_options & RES_USE_INET6; \ - result = -EAI_MEMORY; \ - goto free_and_return; \ - } \ - tmpbuf = newp; \ - malloc_tmpbuf = true; \ - tmpbuflen = 2 * tmpbuflen; \ + result = -EAI_MEMORY; \ + goto free_and_return; \ } \ } \ if (status == NSS_STATUS_SUCCESS && rc == 0) \ @@ -308,7 +316,7 @@ extern service_user *__nss_hosts_database attribute_hidden; static int gaih_inet (const char *name, const struct gaih_service *service, const struct addrinfo *req, struct addrinfo **pai, - unsigned int *naddrs) + unsigned int *naddrs, struct scratch_buffer *tmpbuf) { const struct gaih_typeproto *tp = gaih_inet_typeproto; struct gaih_servtuple *st = (struct gaih_servtuple *) &nullserv; @@ -317,7 +325,10 @@ gaih_inet (const char *name, const struct gaih_service *service, bool got_ipv6 = false; const char *canon = NULL; const char *orig_name = name; - size_t alloca_used = 0; + + /* Reserve stack memory for the scratch buffer in the getaddrinfo + function. */ + size_t alloca_used = sizeof (struct scratch_buffer); if (req->ai_protocol || req->ai_socktype) { @@ -352,7 +363,7 @@ gaih_inet (const char *name, const struct gaih_service *service, st = (struct gaih_servtuple *) alloca_account (sizeof (struct gaih_servtuple), alloca_used); - if ((rc = gaih_inet_serv (service->name, tp, req, st))) + if ((rc = gaih_inet_serv (service->name, tp, req, st, tmpbuf))) return rc; } else @@ -377,7 +388,8 @@ gaih_inet (const char *name, const struct gaih_service *service, alloca_account (sizeof (struct gaih_servtuple), alloca_used); - if ((rc = gaih_inet_serv (service->name, tp, req, newp))) + if ((rc = gaih_inet_serv (service->name, + tp, req, newp, tmpbuf))) { if (rc) continue; @@ -438,9 +450,8 @@ gaih_inet (const char *name, const struct gaih_service *service, struct gaih_addrtuple *addrmem = NULL; bool malloc_canonbuf = false; char *canonbuf = NULL; - bool malloc_tmpbuf = false; - char *tmpbuf = NULL; int result = 0; + if (name != NULL) { at = alloca_account (sizeof (struct gaih_addrtuple), alloca_used); @@ -608,11 +619,6 @@ gaih_inet (const char *name, const struct gaih_service *service, if (req->ai_family == AF_INET && (req->ai_flags & AI_CANONNAME) == 0) { - /* Allocate additional room for struct host_data. */ - size_t tmpbuflen = (512 + MAX_NR_ALIASES * sizeof(char*) - + 16 * sizeof(char)); - assert (tmpbuf == NULL); - tmpbuf = alloca_account (tmpbuflen, alloca_used); int rc; struct hostent th; struct hostent *h; @@ -620,28 +626,15 @@ gaih_inet (const char *name, const struct gaih_service *service, while (1) { - rc = __gethostbyname2_r (name, AF_INET, &th, tmpbuf, - tmpbuflen, &h, &herrno); + rc = __gethostbyname2_r (name, AF_INET, &th, + tmpbuf->data, tmpbuf->length, + &h, &herrno); if (rc != ERANGE || herrno != NETDB_INTERNAL) break; - - if (!malloc_tmpbuf - && __libc_use_alloca (alloca_used + 2 * tmpbuflen)) - tmpbuf = extend_alloca_account (tmpbuf, tmpbuflen, - 2 * tmpbuflen, - alloca_used); - else + if (!scratch_buffer_grow (tmpbuf)) { - char *newp = realloc (malloc_tmpbuf ? tmpbuf : NULL, - 2 * tmpbuflen); - if (newp == NULL) - { - result = -EAI_MEMORY; - goto free_and_return; - } - tmpbuf = newp; - malloc_tmpbuf = true; - tmpbuflen = 2 * tmpbuflen; + result = -EAI_MEMORY; + goto free_and_return; } } @@ -835,22 +828,6 @@ gaih_inet (const char *name, const struct gaih_service *service, old_res_options = _res.options; _res.options &= ~RES_USE_INET6; - size_t tmpbuflen = 1024 + sizeof(struct gaih_addrtuple); - malloc_tmpbuf = !__libc_use_alloca (alloca_used + tmpbuflen); - assert (tmpbuf == NULL); - if (!malloc_tmpbuf) - tmpbuf = alloca_account (tmpbuflen, alloca_used); - else - { - tmpbuf = malloc (tmpbuflen); - if (tmpbuf == NULL) - { - _res.options |= old_res_options & RES_USE_INET6; - result = -EAI_MEMORY; - goto free_and_return; - } - } - while (!no_more) { no_data = 0; @@ -868,8 +845,9 @@ gaih_inet (const char *name, const struct gaih_service *service, while (1) { rc = 0; - status = DL_CALL_FCT (fct4, (name, pat, tmpbuf, - tmpbuflen, &rc, &herrno, + status = DL_CALL_FCT (fct4, (name, pat, + tmpbuf->data, tmpbuf->length, + &rc, &herrno, NULL)); if (status == NSS_STATUS_SUCCESS) break; @@ -883,24 +861,11 @@ gaih_inet (const char *name, const struct gaih_service *service, break; } - if (!malloc_tmpbuf - && __libc_use_alloca (alloca_used + 2 * tmpbuflen)) - tmpbuf = extend_alloca_account (tmpbuf, tmpbuflen, - 2 * tmpbuflen, - alloca_used); - else + if (!scratch_buffer_grow (tmpbuf)) { - char *newp = realloc (malloc_tmpbuf ? tmpbuf : NULL, - 2 * tmpbuflen); - if (newp == NULL) - { - _res.options |= old_res_options & RES_USE_INET6; - result = -EAI_MEMORY; - goto free_and_return; - } - tmpbuf = newp; - malloc_tmpbuf = true; - tmpbuflen = 2 * tmpbuflen; + _res.options |= old_res_options & RES_USE_INET6; + result = -EAI_MEMORY; + goto free_and_return; } } @@ -1287,8 +1252,6 @@ gaih_inet (const char *name, const struct gaih_service *service, free (addrmem); if (malloc_canonbuf) free (canonbuf); - if (malloc_tmpbuf) - free (tmpbuf); return result; } @@ -2423,7 +2386,11 @@ getaddrinfo (const char *name, const char *service, if (hints->ai_family == AF_UNSPEC || hints->ai_family == AF_INET || hints->ai_family == AF_INET6) { - last_i = gaih_inet (name, pservice, hints, end, &naddrs); + struct scratch_buffer tmpbuf; + scratch_buffer_init (&tmpbuf); + last_i = gaih_inet (name, pservice, hints, end, &naddrs, &tmpbuf); + scratch_buffer_free (&tmpbuf); + if (last_i != 0) { freeaddrinfo (p);