From patchwork Tue Sep 5 20:25:18 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 810281 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-84212-incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.b="HSI3nq84"; 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 3xmytL6B4zz9sPs for ; Wed, 6 Sep 2017 06:26:50 +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:from:to:cc:subject:date:message-id:in-reply-to :references; q=dns; s=default; b=Wc77E7R7DthmVTm9VboVQYQtU4UQujG s0Wh0ny+umIMGFgfdwc+4M9KSF5fCAK/IFgiVLeWVxtRpnFtlGIzo+8oPf/UKEf8 P18fuBAwx1BrGTLlldo9VaifrYJJH/bpWCSuS8soKgyYu3dPdAJnKbrS6BUfIthj 8H2O9dsFjoAs= 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:from:to:cc:subject:date:message-id:in-reply-to :references; s=default; bh=ugzsZmLO86wRXxXbmWjH9WRq9EA=; b=HSI3n q84s3bNofahB1zBfLwPhxi1+NI4UgMSThUHpgU3C31xz5vNPGnncc9AqT503vsuO SrK3Kxl7Sf3jiR/z/4vmQ54JZ7oz/MTVfn6fwEU9KTjD2614AN3tmpbwtdDtsLnV /eyF+pY05XMlqgn3Cnu7cKRq8p2zoh4+ZYRZMQ= Received: (qmail 49483 invoked by alias); 5 Sep 2017 20:25:54 -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 48835 invoked by uid 89); 5 Sep 2017 20:25:49 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=lacking X-HELO: mail-qk0-f169.google.com X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=Blvulj+f48B14LwO6vJPYfxom6ZpkU8t9dDAAMQv7GU=; b=fDSqlKXFgrzZ2SQAyBX8sV7T2S5slA83sq9SP4//wLL227xLUasxNH+V0I4885Eclj y+BrgqOhwfgh+gyoqg2/GCKGv7QYgum5lQB+m5QzASknLJBRiiW5C0APTpCJkHcuoau8 gB55X4cK6Nt/mP81eLLog+C5xGvTINhn6lSNTWvbeWr1VkMnRmjK0f+rGzsZUCYQNwPw QRAoe6ScIUcLHdQ3h2E5KuXpMY6CQzktbIcHh3BYPrDN7FavYpPmjvci6ho7GIzEFQgf mehFKUsDsZhCzJu++NBDnDFnKQdmmbMi6DU+qFQLEpRXsamzQ8ES1Fg0jQVmb6KeZX3i rFbg== X-Gm-Message-State: AHPjjUgd7uoCSwYlAu18uYCFUTBZBCOsivHEscQFYFhmuaBU2mgIzzfo cCE//VcL5NTiX400JfBNGA== X-Google-Smtp-Source: ADKCNb7UK1hbNrfLf1Vphvq8IlWY/RDOXlSCq6dfo4PdNDrqBUrYgD9amna9jF77wlte53QJwNuNHQ== X-Received: by 10.55.86.134 with SMTP id k128mr501528qkb.56.1504643140870; Tue, 05 Sep 2017 13:25:40 -0700 (PDT) From: Adhemerval Zanella To: libc-alpha@sourceware.org Cc: Paul Eggert Subject: [PATCH 5/9] posix: Fix getpwnam_r usage (BZ #1062) Date: Tue, 5 Sep 2017 17:25:18 -0300 Message-Id: <1504643122-14874-6-git-send-email-adhemerval.zanella@linaro.org> In-Reply-To: <1504643122-14874-1-git-send-email-adhemerval.zanella@linaro.org> References: <1504643122-14874-1-git-send-email-adhemerval.zanella@linaro.org> This patch fixes longstanding misuse of errno after getpwnam_r, which returns an error number rather than setting errno. This is sync with gnulib commit 5db9301. Checked on x86_64-linux-gnu and on a build using build-many-glibcs.py for all major architectures. [BZ #1062] * posix/glob.c (glob): Port recent patches to platforms lacking getpwnam_r. (glob): Fix longstanding misuse of errno after getpwnam_r, which returns an error number rather than setting errno. --- ChangeLog | 6 +++ posix/glob.c | 164 +++++++++-------------------------------------------------- 2 files changed, 30 insertions(+), 140 deletions(-) diff --git a/posix/glob.c b/posix/glob.c index 15c6295..340cf08 100644 --- a/posix/glob.c +++ b/posix/glob.c @@ -15,10 +15,6 @@ License along with the GNU C Library; if not, see . */ -#ifndef _LIBC -# include -#endif - #include #include @@ -39,10 +35,6 @@ #endif #include -#ifndef __set_errno -# define __set_errno(val) errno = (val) -#endif - #include #include #include @@ -82,12 +74,8 @@ #include #include +#include -#ifdef _SC_GETPW_R_SIZE_MAX -# define GETPW_R_SIZE_MAX() sysconf (_SC_GETPW_R_SIZE_MAX) -#else -# define GETPW_R_SIZE_MAX() (-1) -#endif #ifdef _SC_LOGIN_NAME_MAX # define GET_LOGIN_NAME_MAX() sysconf (_SC_LOGIN_NAME_MAX) #else @@ -649,97 +637,36 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int), if (success) { struct passwd *p; - char *malloc_pwtmpbuf = NULL; - char *pwtmpbuf; + struct scratch_buffer pwtmpbuf; + scratch_buffer_init (&pwtmpbuf); # if defined HAVE_GETPWNAM_R || defined _LIBC - long int pwbuflenmax = GETPW_R_SIZE_MAX (); - size_t pwbuflen = pwbuflenmax; struct passwd pwbuf; - int save = errno; -# ifndef _LIBC - if (! (0 < pwbuflenmax && pwbuflenmax <= SIZE_MAX)) - /* 'sysconf' does not support _SC_GETPW_R_SIZE_MAX. - Try a moderate value. */ - pwbuflen = 1024; -# endif - if (glob_use_alloca (alloca_used, pwbuflen)) - pwtmpbuf = alloca_account (pwbuflen, alloca_used); - else + while (getpwnam_r (name, &pwbuf, + pwtmpbuf.data, pwtmpbuf.length, &p) + == ERANGE) { - pwtmpbuf = malloc (pwbuflen); - if (pwtmpbuf == NULL) + if (!scratch_buffer_grow (&pwtmpbuf)) { - if (__glibc_unlikely (malloc_name)) - free (name); retval = GLOB_NOSPACE; goto out; } - malloc_pwtmpbuf = pwtmpbuf; - } - - while (getpwnam_r (name, &pwbuf, pwtmpbuf, pwbuflen, &p) - != 0) - { - size_t newlen; - bool v; - if (errno != ERANGE) - { - p = NULL; - break; - } - v = size_add_wrapv (pwbuflen, pwbuflen, &newlen); - if (!v && malloc_pwtmpbuf == NULL - && glob_use_alloca (alloca_used, newlen)) - pwtmpbuf = extend_alloca_account (pwtmpbuf, pwbuflen, - newlen, alloca_used); - else - { - char *newp = (v ? NULL - : realloc (malloc_pwtmpbuf, newlen)); - if (newp == NULL) - { - free (malloc_pwtmpbuf); - if (__glibc_unlikely (malloc_name)) - free (name); - retval = GLOB_NOSPACE; - goto out; - } - malloc_pwtmpbuf = pwtmpbuf = newp; - } - pwbuflen = newlen; - __set_errno (save); } # else p = getpwnam (name); # endif - if (__glibc_unlikely (malloc_name)) - free (name); if (p != NULL) { - if (malloc_pwtmpbuf == NULL) - home_dir = p->pw_dir; - else + home_dir = strdup (p->pw_dir); + malloc_home_dir = 1; + if (home_dir == NULL) { - size_t home_dir_len = strlen (p->pw_dir) + 1; - if (glob_use_alloca (alloca_used, home_dir_len)) - home_dir = alloca_account (home_dir_len, - alloca_used); - else - { - home_dir = malloc (home_dir_len); - if (home_dir == NULL) - { - free (pwtmpbuf); - retval = GLOB_NOSPACE; - goto out; - } - malloc_home_dir = 1; - } - memcpy (home_dir, p->pw_dir, home_dir_len); + scratch_buffer_free (&pwtmpbuf); + retval = GLOB_NOSPACE; + goto out; } } - free (malloc_pwtmpbuf); + scratch_buffer_free (&pwtmpbuf); } else { @@ -876,61 +803,21 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int), /* Look up specific user's home directory. */ { struct passwd *p; - char *malloc_pwtmpbuf = NULL; + struct scratch_buffer pwtmpbuf; + scratch_buffer_init (&pwtmpbuf); + # if defined HAVE_GETPWNAM_R || defined _LIBC - long int buflenmax = GETPW_R_SIZE_MAX (); - size_t buflen = buflenmax; - char *pwtmpbuf; struct passwd pwbuf; - int save = errno; - -# ifndef _LIBC - if (! (0 <= buflenmax && buflenmax <= SIZE_MAX)) - /* Perhaps 'sysconf' does not support _SC_GETPW_R_SIZE_MAX. Try a - moderate value. */ - buflen = 1024; -# endif - if (glob_use_alloca (alloca_used, buflen)) - pwtmpbuf = alloca_account (buflen, alloca_used); - else + + while (getpwnam_r (user_name, &pwbuf, + pwtmpbuf.data, pwtmpbuf.length, &p) + == ERANGE) { - pwtmpbuf = malloc (buflen); - if (pwtmpbuf == NULL) + if (!scratch_buffer_grow (&pwtmpbuf)) { - nomem_getpw: - if (__glibc_unlikely (malloc_user_name)) - free (user_name); retval = GLOB_NOSPACE; goto out; } - malloc_pwtmpbuf = pwtmpbuf; - } - - while (getpwnam_r (user_name, &pwbuf, pwtmpbuf, buflen, &p) != 0) - { - size_t newlen; - bool v; - if (errno != ERANGE) - { - p = NULL; - break; - } - v = size_add_wrapv (buflen, buflen, &newlen); - if (!v && malloc_pwtmpbuf == NULL - && glob_use_alloca (alloca_used, newlen)) - pwtmpbuf = extend_alloca_account (pwtmpbuf, buflen, - newlen, alloca_used); - else - { - char *newp = v ? NULL : realloc (malloc_pwtmpbuf, newlen); - if (newp == NULL) - { - free (malloc_pwtmpbuf); - goto nomem_getpw; - } - malloc_pwtmpbuf = pwtmpbuf = newp; - } - __set_errno (save); } # else p = getpwnam (user_name); @@ -957,7 +844,7 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int), dirname = malloc (home_len + rest_len + 1); if (dirname == NULL) { - free (malloc_pwtmpbuf); + scratch_buffer_free (&pwtmpbuf); retval = GLOB_NOSPACE; goto out; } @@ -968,13 +855,9 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int), dirlen = home_len + rest_len; dirname_modified = 1; - - free (malloc_pwtmpbuf); } else { - free (malloc_pwtmpbuf); - if (flags & GLOB_TILDE_CHECK) { /* We have to regard it as an error if we cannot find the @@ -983,6 +866,7 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int), goto out; } } + scratch_buffer_free (&pwtmpbuf); } #endif /* !WINDOWS32 */ }