From patchwork Tue Apr 10 00:25:21 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Pluzhnikov X-Patchwork-Id: 26663 Received: (qmail 3054 invoked by alias); 10 Apr 2018 00:25:55 -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 3023 invoked by uid 89); 10 Apr 2018 00:25:54 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-24.4 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy= X-HELO: mail-wr0-f177.google.com X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to; bh=KoXHeYf4MZsvqs5YBcMS8oW4eNPxA/g5ByhXucxVhOk=; b=XbdJ7AW0dqIlg8Dh89yktAuXW/vVx6H5O0mfrBtOdftAgp3NbBh9r6nDOunIjI0giJ Pir7tR9aiPvOuT7Kvl4CLgUFVM/MP64Re3fg/QbbSGcMSD1RTjBj+tuPzsgmvBaYjJjC ey/fb1bay34H1D0Ywc80KuqpPA2iCHBmzW1lE3GGmnhwhviWkHVsK4vhPThXrsWLgmG5 1m141aZJdnoYboYy6yo7/bAGdAhXKmGwZCOQV7Xbr2HSsvVJSCgpaS5hVP5oLspwiqzH yJ9kBzDKRprgsp29z0i1UIq41BQUaXs8S/pQxyHEzh1DixYLKn5Lwq4q+HQnD/qYG23v cYKA== X-Gm-Message-State: ALQs6tDsAByuuk4yzZEbdHO8jx0N0EOa7eLoC/0fnrdYs1FbLC81JTkn J3+S46A2J8bulEj0f0+DRpRmj6mHROl3DkbzWVWFGevh X-Google-Smtp-Source: AIpwx4+mTPTJ8qMOl8Uc1imvvjvN+ijStis4AC3TfWKDKZ3R4rvFo+OpzwrRsZZKYgpRie0Yqcpme2mOqWofUYYgpjs= X-Received: by 10.223.210.73 with SMTP id o9mr8986878wri.248.1523319950002; Mon, 09 Apr 2018 17:25:50 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: From: Paul Pluzhnikov Date: Tue, 10 Apr 2018 00:25:21 +0000 Message-ID: Subject: Re: [patch] Fix path length overflow in realpath (BZ#22786) To: GLIBC Devel + const size_t path_len = (size_t) INT_MAX + 1; + char *path = malloc(path_len); Sorry, missed space before parenth here. Updated patch attached. On Mon, Apr 9, 2018 at 4:01 PM Paul Pluzhnikov wrote: > Greetings, > Attached is a trivial fix, and a test case. > Thanks, > 2018-04-09 Paul Pluzhnikov > [BZ #22786] > * stdlib/canonicalize.c (__realpath): Fix overflow in path length > computation. > * stdlib/Makefile (test-bz22786): New test. > * stdlib/test-bz22786.c: New test. > -- > Paul Pluzhnikov --- Paul Pluzhnikov diff --git a/stdlib/Makefile b/stdlib/Makefile index af1643c0c4..d04afd62c8 100644 --- a/stdlib/Makefile +++ b/stdlib/Makefile @@ -84,7 +84,7 @@ tests := tst-strtol tst-strtod testmb testrand testsort testdiv \ tst-cxa_atexit tst-on_exit test-atexit-race \ test-at_quick_exit-race test-cxa_atexit-race \ test-on_exit-race test-dlclose-exit-race \ - tst-makecontext-align + tst-makecontext-align test-bz22786 tests-internal := tst-strtod1i tst-strtod3 tst-strtod4 tst-strtod5i \ tst-tls-atexit tst-tls-atexit-nodelete @@ -156,6 +156,9 @@ CFLAGS-tst-qsort.c += $(stack-align-test-flags) CFLAGS-tst-makecontext.c += -funwind-tables CFLAGS-tst-makecontext2.c += $(stack-align-test-flags) +# suppress warnings about allocation size. +CFLAGS-test-bz22786.c += $(+gcc-nowarn) + # Run a test on the header files we use. tests-special += $(objpfx)isomac.out diff --git a/stdlib/canonicalize.c b/stdlib/canonicalize.c index 4135f3f33c..390fb437a8 100644 --- a/stdlib/canonicalize.c +++ b/stdlib/canonicalize.c @@ -181,7 +181,7 @@ __realpath (const char *name, char *resolved) extra_buf = __alloca (path_max); len = strlen (end); - if ((long int) (n + len) >= path_max) + if (path_max - n <= len) { __set_errno (ENAMETOOLONG); goto error; diff --git a/stdlib/test-bz22786.c b/stdlib/test-bz22786.c new file mode 100644 index 0000000000..504535bbbd --- /dev/null +++ b/stdlib/test-bz22786.c @@ -0,0 +1,80 @@ +/* Bug 22786: test for stack overflow in realpath. + Copyright (C) 2017-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +/* This file must be run from within a directory called "stdlib". */ + +#include +#include +#include +#include +#include +#include +#include +#include + +static int +do_test (void) +{ + const char dir[] = "bz22786"; + const char lnk[] = "bz22786/symlink"; + + rmdir (dir); + if (mkdir (dir, 0755) != 0 && errno != EEXIST) + { + printf ("mkdir %s: %m\n", dir); + return EXIT_FAILURE; + } + if (symlink (".", lnk) != 0 && errno != EEXIST) + { + printf ("symlink (%s, %s): %m\n", dir, lnk); + return EXIT_FAILURE; + } + + const size_t path_len = (size_t) INT_MAX + 1; + char *path = malloc (path_len); + + if (path == NULL) + { + printf ("malloc (%zu): %m\n", path_len); + return EXIT_FAILURE; + } + + /* Construct very long path = "bz22786/symlink/aaaa....." */ + char *p = mempcpy (path, lnk, sizeof (lnk) - 1); + *(p++) = '/'; + memset (p, 'a', path_len - (path - p) - 2); + p[path_len - (path - p) - 1] = '\0'; + + /* This call crashes before the fix for bz22786 on 32-bit platforms. */ + p = realpath (path, NULL); + + if (p != NULL || errno != ENAMETOOLONG) + { + printf ("realpath: %s (%m)", p); + return EXIT_FAILURE; + } + + /* Cleanup. */ + unlink (lnk); + rmdir (dir); + + return 0; +} + +#define TEST_FUNCTION do_test +#include