From patchwork Sun Mar 1 14:14:19 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Weimer X-Patchwork-Id: 444962 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 676C114009B for ; Mon, 2 Mar 2015 19:40:45 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass reason="1024-bit key; unprotected key" header.d=sourceware.org header.i=@sourceware.org header.b=IB2QnOsU; dkim-adsp=none (unprotected policy); 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:message-id:in-reply-to:references:from:date :subject:to; q=dns; s=default; b=qgg4GkWW5JeZCWuwg7jpywH4KizrWcE IyuBa1o+EOUT8tlNv8sIIZCnzoQP4tN9ylKhS02YTmIHOqH1Xv7XDqaKmhh0qh0p 2TbJoCEhXKLPV/HfHAzU98g1ZXWmAVT8BSUmzfPpz+ok3www428eYG/C0T19vLjk MuNv0vGK75rM= 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:message-id:in-reply-to:references:from:date :subject:to; s=default; bh=Dndo5XzVSddHAwdYS3DWzRKcIB0=; b=IB2Qn OsUV59zlnreazabdfduOXhiIG5zASZbjE4iUiFxbzEpdBaUXIFS4EBp5z9mqeugw 5zEqB17bpHE5QSGAAsPuMEe2U7HUJu23p8qchVKomgGe2cwbS4DnPmRPA1Eae2Am K6wRZ5y5EVQJSxGjERinR6RfkT7msVeudgTEFU= Received: (qmail 77608 invoked by alias); 2 Mar 2015 08:40:28 -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 77575 invoked by uid 89); 2 Mar 2015 08:40:27 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.5 required=5.0 tests=AWL, BAYES_00, DATE_IN_PAST_12_24, SPF_HELO_PASS, SPF_PASS, T_RP_MATCHES_RCVD autolearn=no version=3.3.2 X-HELO: mx1.redhat.com Message-Id: In-Reply-To: References: From: Florian Weimer Date: Sun, 1 Mar 2015 15:14:19 +0100 Subject: [PATCH 05/25] getgrent_next_nss (compat-initgroups): Remove alloca fallback To: libc-alpha@sourceware.org If the caller-supplied buffer is not large enough, fall back directly malloc. The previous __libc_use_alloca check was incorrect because it did not take into account that extend_alloca may fail to merge allocations, so it would underestimate the stack space being used by roughly a factor of two. --- nis/nss_compat/compat-initgroups.c | 46 +++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 25 deletions(-) diff --git a/nis/nss_compat/compat-initgroups.c b/nis/nss_compat/compat-initgroups.c index 2f8ba72..5e6f970 100644 --- a/nis/nss_compat/compat-initgroups.c +++ b/nis/nss_compat/compat-initgroups.c @@ -310,7 +310,6 @@ getgrent_next_nss (ent_t *ent, char *buffer, size_t buflen, const char *user, overwrite the pointer with one to a bigger buffer. */ char *tmpbuf = buffer; size_t tmplen = buflen; - bool use_malloc = false; for (int i = 0; i < mystart; i++) { @@ -319,29 +318,26 @@ getgrent_next_nss (ent_t *ent, char *buffer, size_t buflen, const char *user, == NSS_STATUS_TRYAGAIN && *errnop == ERANGE) { - if (__libc_use_alloca (tmplen * 2)) - { - if (tmpbuf == buffer) - { - tmplen *= 2; - tmpbuf = __alloca (tmplen); - } - else - tmpbuf = extend_alloca (tmpbuf, tmplen, tmplen * 2); - } - else - { - tmplen *= 2; - char *newbuf = realloc (use_malloc ? tmpbuf : NULL, tmplen); - - if (newbuf == NULL) - { - status = NSS_STATUS_TRYAGAIN; - goto done; - } - use_malloc = true; - tmpbuf = newbuf; - } + /* Check for overflow. */ + if (__glibc_unlikely (tmplen * 2 < tmplen)) + { + __set_errno (ENOMEM); + status = NSS_STATUS_TRYAGAIN; + goto done; + } + /* Increase the size. Make sure that we retry + with a reasonable size. */ + tmplen *= 2; + if (tmplen < 1024) + tmplen = 1024; + if (tmpbuf != buffer) + free (tmpbuf); + tmpbuf = malloc (tmplen); + if (__glibc_unlikely (tmpbuf == NULL)) + { + status = NSS_STATUS_TRYAGAIN; + goto done; + } } if (__builtin_expect (status != NSS_STATUS_NOTFOUND, 1)) @@ -369,7 +365,7 @@ getgrent_next_nss (ent_t *ent, char *buffer, size_t buflen, const char *user, status = NSS_STATUS_NOTFOUND; done: - if (use_malloc) + if (tmpbuf != buffer) free (tmpbuf); }