From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 5366 invoked by alias); 2 Jun 2010 11:45:32 -0000 Received: (qmail 5281 invoked by uid 22791); 2 Jun 2010 11:45:28 -0000 X-SWARE-Spam-Status: No, hits=-5.5 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_HI,SPF_HELO_PASS,TW_CP,TW_PW,TW_TP,TW_WU,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 02 Jun 2010 11:42:47 +0000 Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o52Bgji6031799 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Wed, 2 Jun 2010 07:42:45 -0400 Received: from hase.home (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o52Bgh0u027909 for ; Wed, 2 Jun 2010 07:42:44 -0400 From: Andreas Schwab To: libc-hacker@sourceware.org Subject: [PATCH] Fix error handling in getlogin_r X-Yow: Let's climb to the TOP of that MOUNTAIN and think about STRIP MINING!! Date: Wed, 02 Jun 2010 11:45:00 -0000 Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.1 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Mailing-List: contact libc-hacker-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-hacker-owner@sourceware.org X-SW-Source: 2010-06/txt/msg00000.txt.bz2 2010-06-02 Andreas Schwab * sysdeps/unix/sysv/linux/getlogin_r.c (__getlogin_r_loginuid): Fix error handling. Properly resize buffer. Don't set errno. (getlogin_r): Only use fallback if __getlogin_r_loginuid returns -1. --- sysdeps/unix/sysv/linux/getlogin_r.c | 63 ++++++++++++++++++++-------------- 1 files changed, 37 insertions(+), 26 deletions(-) diff --git a/sysdeps/unix/sysv/linux/getlogin_r.c b/sysdeps/unix/sysv/linux/getlogin_r.c index dad2671..404c84d 100644 --- a/sysdeps/unix/sysv/linux/getlogin_r.c +++ b/sysdeps/unix/sysv/linux/getlogin_r.c @@ -27,6 +27,10 @@ static int getlogin_r_fd0 (char *name, size_t namesize); #undef getlogin_r +/* Try to determine login name from /proc/self/loginuid and return 0 + if successful. If /proc/self/loginuid cannot be read return -1. + Otherwise return the error number. */ + int attribute_hidden __getlogin_r_loginuid (name, namesize) @@ -35,7 +39,7 @@ __getlogin_r_loginuid (name, namesize) { int fd = open_not_cancel_2 ("/proc/self/loginuid", O_RDONLY); if (fd == -1) - return 1; + return -1; /* We are reading a 32-bit number. 12 bytes are enough for the text representation. If not, something is wrong. */ @@ -51,46 +55,50 @@ __getlogin_r_loginuid (name, namesize) || (uidbuf[n] = '\0', uid = strtoul (uidbuf, &endp, 10), endp == uidbuf || *endp != '\0')) - return 1; + return -1; size_t buflen = 1024; char *buf = alloca (buflen); bool use_malloc = false; struct passwd pwd; struct passwd *tpwd; - int res; - - while ((res = __getpwuid_r (uid, &pwd, buf, buflen, &tpwd)) != 0) - if (__libc_use_alloca (2 * buflen)) - extend_alloca (buf, buflen, 2 * buflen); - else - { - buflen *= 2; - char *newp = realloc (use_malloc ? buf : NULL, buflen); - if (newp == NULL) - { - fail: - if (use_malloc) - free (buf); - return 1; - } - buf = newp; - use_malloc = true; - } + int result; + + while ((result = __getpwuid_r (uid, &pwd, buf, buflen, &tpwd)) != 0) + { + if (result != ERANGE) + goto out; + if (__libc_use_alloca (2 * buflen)) + buf = extend_alloca (buf, buflen, 2 * buflen); + else + { + buflen *= 2; + char *newp = realloc (use_malloc ? buf : NULL, buflen); + if (newp == NULL) + { + result = ENOMEM; + goto out; + } + buf = newp; + use_malloc = true; + } + } if (tpwd == NULL) - goto fail; + { + result = ENOENT; + goto out; + } - int result = 0; size_t needed = strlen (pwd.pw_name) + 1; if (needed > namesize) { - __set_errno (ERANGE); result = ERANGE; goto out; } memcpy (name, pwd.pw_name, needed); + result = 0; out: if (use_malloc) @@ -109,8 +117,11 @@ getlogin_r (name, namesize) char *name; size_t namesize; { - if (__getlogin_r_loginuid (name, namesize) == 0) - return 0; + int result; + + result = __getlogin_r_loginuid (name, namesize); + if (result >= 0) + return result; return getlogin_r_fd0 (name, namesize); } -- 1.7.1 -- Andreas Schwab, schwab@redhat.com GPG Key fingerprint = D4E8 DBE3 3813 BB5D FA84 5EC7 45C6 250E 6F00 984E "And now for something completely different."