1 https://sourceware.org/git/gitweb.cgi?p=glibc.git;a=patch;h=5460617d1567657621107d895ee2dd83bc1f88f2
4 From 5460617d1567657621107d895ee2dd83bc1f88f2 Mon Sep 17 00:00:00 2001
5 From: Paul Pluzhnikov <ppluzhnikov@google.com>
6 Date: Tue, 8 May 2018 18:12:41 -0700
7 Subject: [PATCH] Fix BZ 22786: integer addition overflow may cause stack
8 buffer overflow when realpath() input length is close to SSIZE_MAX.
10 2018-05-09 Paul Pluzhnikov <ppluzhnikov@google.com>
13 * stdlib/canonicalize.c (__realpath): Fix overflow in path length
15 * stdlib/Makefile (test-bz22786): New test.
16 * stdlib/test-bz22786.c: New test.
19 stdlib/Makefile | 2 +-
20 stdlib/canonicalize.c | 2 +-
21 stdlib/test-bz22786.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++
22 4 files changed, 100 insertions(+), 2 deletions(-)
23 create mode 100644 stdlib/test-bz22786.c
25 diff --git a/stdlib/Makefile b/stdlib/Makefile
26 index af1643c..1ddb1f9 100644
29 @@ -84,7 +84,7 @@ tests := tst-strtol tst-strtod testmb testrand testsort testdiv \
30 tst-cxa_atexit tst-on_exit test-atexit-race \
31 test-at_quick_exit-race test-cxa_atexit-race \
32 test-on_exit-race test-dlclose-exit-race \
33 - tst-makecontext-align
34 + tst-makecontext-align test-bz22786
36 tests-internal := tst-strtod1i tst-strtod3 tst-strtod4 tst-strtod5i \
37 tst-tls-atexit tst-tls-atexit-nodelete
38 diff --git a/stdlib/canonicalize.c b/stdlib/canonicalize.c
39 index 4135f3f..390fb43 100644
40 --- a/stdlib/canonicalize.c
41 +++ b/stdlib/canonicalize.c
42 @@ -181,7 +181,7 @@ __realpath (const char *name, char *resolved)
43 extra_buf = __alloca (path_max);
46 - if ((long int) (n + len) >= path_max)
47 + if (path_max - n <= len)
49 __set_errno (ENAMETOOLONG);
51 diff --git a/stdlib/test-bz22786.c b/stdlib/test-bz22786.c
53 index 0000000..e7837f9
55 +++ b/stdlib/test-bz22786.c
57 +/* Bug 22786: test for buffer overflow in realpath.
58 + Copyright (C) 2018 Free Software Foundation, Inc.
59 + This file is part of the GNU C Library.
61 + The GNU C Library is free software; you can redistribute it and/or
62 + modify it under the terms of the GNU Lesser General Public
63 + License as published by the Free Software Foundation; either
64 + version 2.1 of the License, or (at your option) any later version.
66 + The GNU C Library is distributed in the hope that it will be useful,
67 + but WITHOUT ANY WARRANTY; without even the implied warranty of
68 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
69 + Lesser General Public License for more details.
71 + You should have received a copy of the GNU Lesser General Public
72 + License along with the GNU C Library; if not, see
73 + <http://www.gnu.org/licenses/>. */
75 +/* This file must be run from within a directory called "stdlib". */
83 +#include <sys/stat.h>
84 +#include <sys/types.h>
85 +#include <support/test-driver.h>
86 +#include <libc-diag.h>
91 + const char dir[] = "bz22786";
92 + const char lnk[] = "bz22786/symlink";
95 + if (mkdir (dir, 0755) != 0 && errno != EEXIST)
97 + printf ("mkdir %s: %m\n", dir);
98 + return EXIT_FAILURE;
100 + if (symlink (".", lnk) != 0 && errno != EEXIST)
102 + printf ("symlink (%s, %s): %m\n", dir, lnk);
103 + return EXIT_FAILURE;
106 + const size_t path_len = (size_t) INT_MAX + 1;
108 + DIAG_PUSH_NEEDS_COMMENT;
109 +#if __GNUC_PREREQ (7, 0)
110 + /* GCC 7 warns about too-large allocations; here we need such
111 + allocation to succeed for the test to work. */
112 + DIAG_IGNORE_NEEDS_COMMENT (7, "-Walloc-size-larger-than=");
114 + char *path = malloc (path_len);
115 + DIAG_POP_NEEDS_COMMENT;
119 + printf ("malloc (%zu): %m\n", path_len);
120 + return EXIT_UNSUPPORTED;
123 + /* Construct very long path = "bz22786/symlink/aaaa....." */
124 + char *p = mempcpy (path, lnk, sizeof (lnk) - 1);
126 + memset (p, 'a', path_len - (path - p) - 2);
127 + p[path_len - (path - p) - 1] = '\0';
129 + /* This call crashes before the fix for bz22786 on 32-bit platforms. */
130 + p = realpath (path, NULL);
132 + if (p != NULL || errno != ENAMETOOLONG)
134 + printf ("realpath: %s (%m)", p);
135 + return EXIT_FAILURE;
145 +#define TEST_FUNCTION do_test
146 +#include <support/test-driver.c>