From patchwork Mon Jun 25 17:49:23 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Weimer X-Patchwork-Id: 934499 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=sourceware.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=libc-alpha-return-93594-incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.b="YBNP2Smn"; dkim-atps=neutral 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 41DxXc4DQXz9rvt for ; Tue, 26 Jun 2018 03:50:24 +1000 (AEST) 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= qFLIBFRUKWm/Z6xrz9gR1E47v600LD3mzz0Z9azkhN2Xqqtsl6Rr2fQZVNfW5lUM wRv0/SOMghZfwy2eubcBTWF0cKWPdFjEa9NLp3UijrmDLMZVshEpdd8x5dV3e6a7 aB1iADJ/4PEiiCEQk/c0IjrI/wY+RwqW9GAEZdImXV0= 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=6mwVQ9 fycejqjJdCIdKWSLCupPI=; b=YBNP2SmnAXzMKpwh1RMHlSgq7tbKn+n7rBJJb/ zdL030IT8ylVHaDHI4ZFOEo1YAm34d865t73dKbB7//vcJ46DySmaEKDwXhjuvw0 2FJKip0rpGwFS7vSeq8KgbrIO2rlXDkBd60DTrudSZAUmv4hO9rJWkIj7PBXn3OB fJ414= Received: (qmail 93364 invoked by alias); 25 Jun 2018 17:49:39 -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 93146 invoked by uid 89); 25 Jun 2018 17:49:27 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-25.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_LAZY_DOMAIN_SECURITY, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=Increase, retry X-HELO: mx1.redhat.com Date: Mon, 25 Jun 2018 19:49:23 +0200 To: libc-alpha@sourceware.org Subject: [PATCH] getgrent_next_nss (compat-initgroups): Remove alloca fallback [BZ #18023] User-Agent: Heirloom mailx 12.5 7/5/10 MIME-Version: 1.0 Message-Id: <20180625174923.5E6A643994575@oldenburg.str.redhat.com> From: fweimer@redhat.com (Florian Weimer) 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. 2018-06-25 Florian Weimer [BZ #18023] * nss/nss_compat/compat-initgroups.c (getgrent_next_nss): Fall back to malloc directly, without stack allocations. diff --git a/nss/nss_compat/compat-initgroups.c b/nss/nss_compat/compat-initgroups.c index 74414f4622..540eee863c 100644 --- a/nss/nss_compat/compat-initgroups.c +++ b/nss/nss_compat/compat-initgroups.c @@ -261,7 +261,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++) { @@ -270,29 +269,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)) @@ -320,7 +316,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); }