From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 65035 invoked by alias); 20 Dec 2018 23:39:37 -0000 Mailing-List: contact libc-stable-help@sourceware.org; run by ezmlm Precedence: bulk List-Post: List-Help: List-Subscribe: List-Archive: Sender: libc-stable-owner@sourceware.org Received: (qmail 65011 invoked by uid 89); 20 Dec 2018 23:39:37 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Checked: by ClamAV 0.100.2 on sourceware.org X-Virus-Found: No 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,KAM_SHORT autolearn=ham version=3.3.2 spammy= X-Spam-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,KAM_SHORT autolearn=ham version=3.3.2 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on sourceware.org X-Spam-Level: X-HELO: hall.aurel32.net Received: from hall.aurel32.net (HELO hall.aurel32.net) (163.172.24.10) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 20 Dec 2018 23:39:34 +0000 Received: from [2a01:e35:2e4c:a861:655e:aef3:f589:b897] (helo=ohm.rr44.fr) by hall.aurel32.net with esmtpsa (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.89) (envelope-from ) id 1ga7ue-0002hK-ME; Fri, 21 Dec 2018 00:39:32 +0100 Received: from aurel32 by ohm.rr44.fr with local (Exim 4.91) (envelope-from ) id 1ga7ue-0005QV-4B; Fri, 21 Dec 2018 00:39:32 +0100 From: Aurelien Jarno To: libc-stable@sourceware.org Cc: Paul Pluzhnikov Subject: [2.24 COMMITTED 2/4] Fix BZ 22786: integer addition overflow may cause stack buffer overflow when realpath() input length is close to SSIZE_MAX. Date: Mon, 01 Jan 2018 00:00:00 -0000 Message-Id: <20181220233902.20796-2-aurelien@aurel32.net> X-Mailer: git-send-email 2.19.2 In-Reply-To: <20181220233902.20796-1-aurelien@aurel32.net> References: <20181220233902.20796-1-aurelien@aurel32.net> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-IsSubscribed: yes X-SW-Source: 2018-12/txt/msg00022.txt.bz2 From: Paul Pluzhnikov 2018-05-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. (cherry picked from commit 5460617d1567657621107d895ee2dd83bc1f88f2) --- ChangeLog | 8 ++++ NEWS | 2 + stdlib/Makefile | 2 +- stdlib/canonicalize.c | 2 +- stdlib/test-bz22786.c | 90 +++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 102 insertions(+), 2 deletions(-) create mode 100644 stdlib/test-bz22786.c diff --git a/ChangeLog b/ChangeLog index 63813de2d5..699e8e510e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2018-05-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. + 2018-03-23 Andrew Senkevich Max Horn diff --git a/NEWS b/NEWS index 77f7f1ad0e..0ff775e578 100644 --- a/NEWS +++ b/NEWS @@ -63,6 +63,8 @@ The following bugs are resolved with this release: [22644] string: memmove-sse2-unaligned on 32bit x86 produces garbage when crossing 2GB threshold (CVE-2017-18269) [22715] x86-64: Properly align La_x86_64_retval to VEC_SIZE + [22786] libc: Stack buffer overflow in realpath() if input size is close + to SSIZE_MAX (CVE-2018-11236) Version 2.24 diff --git a/stdlib/Makefile b/stdlib/Makefile index fc6f23dcaf..23f2d6e326 100644 --- a/stdlib/Makefile +++ b/stdlib/Makefile @@ -77,7 +77,7 @@ tests := tst-strtol tst-strtod testmb testrand testsort testdiv \ tst-tininess tst-strtod-underflow tst-tls-atexit \ tst-setcontext3 tst-tls-atexit-nodelete \ tst-strtol-locale tst-strtod-nan-locale tst-strfmon_l \ - tst-quick_exit tst-thread-quick_exit + tst-quick_exit tst-thread-quick_exit test-bz22786 tests-static := tst-secure-getenv ifeq ($(have-cxx-thread_local),yes) CFLAGS-tst-quick_exit.o = -std=c++11 diff --git a/stdlib/canonicalize.c b/stdlib/canonicalize.c index 58bb8de949..59a7b942e0 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..e445034a8d --- /dev/null +++ b/stdlib/test-bz22786.c @@ -0,0 +1,90 @@ +/* Bug 22786: test for buffer overflow in realpath. + Copyright (C) 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 +#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; + + DIAG_PUSH_NEEDS_COMMENT; +#if __GNUC_PREREQ (7, 0) + /* GCC 7 warns about too-large allocations; here we need such + allocation to succeed for the test to work. */ + DIAG_IGNORE_NEEDS_COMMENT (7, "-Walloc-size-larger-than="); +#endif + char *path = malloc (path_len); + DIAG_POP_NEEDS_COMMENT; + + if (path == NULL) + { + printf ("malloc (%zu): %m\n", path_len); + return EXIT_UNSUPPORTED; + } + + /* 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 -- 2.19.2