From patchwork Tue Aug 18 23:54:44 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Pluzhnikov X-Patchwork-Id: 8281 Received: (qmail 101238 invoked by alias); 18 Aug 2015 23:54:48 -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 101228 invoked by uid 89); 18 Aug 2015 23:54:48 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.5 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-qg0-f54.google.com MIME-Version: 1.0 X-Received: by 10.140.194.17 with SMTP id p17mr18866319qha.62.1439942084823; Tue, 18 Aug 2015 16:54:44 -0700 (PDT) In-Reply-To: References: Date: Tue, 18 Aug 2015 16:54:44 -0700 Message-ID: Subject: Re: [patch] Fix BZ #18660 -- overflow in getusershell From: Paul Pluzhnikov To: Joseph Myers Cc: GLIBC Devel , Tobias Stoeckmann On Mon, Aug 17, 2015 at 3:59 AM, Joseph Myers wrote: > Since you're increasing an allocation size, don't you also need to adjust > the check a few lines earlier for whether the allocation size calculation > would overflow? Thanks. Revised patch attached. 2015-08-15 Paul Pluzhnikov Tobias Stoeckmann [BZ #18660] * misc/getusershell.c (initshells): Fix possible overflow. diff --git a/misc/getusershell.c b/misc/getusershell.c index fc2c43b..a5d861e 100644 --- a/misc/getusershell.c +++ b/misc/getusershell.c @@ -31,6 +31,7 @@ static char sccsid[] = "@(#)getusershell.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ +#include #include #include #include @@ -99,6 +100,7 @@ initshells (void) FILE *fp; struct stat64 statb; size_t flen; + off64_t max_shells; free(shells); shells = NULL; @@ -114,12 +116,13 @@ initshells (void) okshells[1] = _PATH_CSHELL; return (char **) okshells; } - if (statb.st_size > ~(size_t)0 / sizeof (char *) * 3) + max_shells = (statb.st_size / 3) + 2; + if (max_shells > ~(size_t)0 / sizeof (char *)) goto init_okshells; flen = statb.st_size + 3; if ((strings = malloc(flen)) == NULL) goto init_okshells; - shells = malloc(statb.st_size / 3 * sizeof (char *)); + shells = malloc(max_shells * sizeof (char *)); if (shells == NULL) { free(strings); strings = NULL; @@ -130,13 +133,16 @@ initshells (void) while (fgets_unlocked(cp, flen - (cp - strings), fp) != NULL) { while (*cp != '#' && *cp != '/' && *cp != '\0') cp++; - if (*cp == '#' || *cp == '\0' || cp[1] == '\0') + /* Reject non-absolute paths, or anything too short. */ + if (cp[0] != '/' || cp[1] == '\0' || isspace(cp[1])) continue; *sp++ = cp; while (!isspace(*cp) && *cp != '#' && *cp != '\0') cp++; + assert (cp < strings + flen); *cp++ = '\0'; } + assert (sp < shells + max_shells); *sp = NULL; (void)fclose(fp); return (shells);