https://sourceware.org/git/gitweb.cgi?p=glibc.git;a=patch;h=5460617d1567657621107d895ee2dd83bc1f88f2 with ChangeLog removed From 5460617d1567657621107d895ee2dd83bc1f88f2 Mon Sep 17 00:00:00 2001 From: Paul Pluzhnikov Date: Tue, 8 May 2018 18:12:41 -0700 Subject: [PATCH] Fix BZ 22786: integer addition overflow may cause stack buffer overflow when realpath() input length is close to SSIZE_MAX. 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. --- ChangeLog | 8 +++++ stdlib/Makefile | 2 +- stdlib/canonicalize.c | 2 +- stdlib/test-bz22786.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 100 insertions(+), 2 deletions(-) create mode 100644 stdlib/test-bz22786.c diff --git a/stdlib/Makefile b/stdlib/Makefile index af1643c..1ddb1f9 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 diff --git a/stdlib/canonicalize.c b/stdlib/canonicalize.c index 4135f3f..390fb43 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 0000000..e7837f9 --- /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.9.3 ccount-details) (parse-contacts): Delete procedures. (%send-dbus-binary, %send-dbus-bus, %send-dbus-user, %send-dbus-group) (%send-dbus-debug): Delete parameters. (jami-service-running?): New procedure. (send-dbus/configuration-manager): Rename to... (call-configuration-manager-method): ... this. Turn METHOD into a positional argument. Turn ARGUMENTS into an optional argument. Invoke `call-dbus-method' instead of `send-dbus', adjusting callers accordingly. (get-account-ids, id->account-details, id->account-details) (id->volatile-account-details, username->id, add-account remove-account) (username->contacts, remove-contact, add-contact, set-account-details) (set-all-moderators, username->all-moderators?, username->moderators) (set-moderator): Adjust accordingly. (with-retries, send-dbus, dbus-available-services) (dbus-service-available?): Move to ... * gnu/build/dbus-service.scm: ... this new module. (send-dbus): Rewrite to use the Guile AC/D-Bus library. (%dbus-query-timeout, sleep*): New variables. (%current-dbus-connection): New parameter. (initialize-dbus-connection!, argument->signature-type) (call-dbus-method): New procedures. (dbus-available-services): Adjust accordingly. * gnu/local.mk (GNU_SYSTEM_MODULES): Register new module. * gnu/packages/glib.scm (dbus-for-jami): New variable. * gnu/services/telephony.scm: (jami-configuration)[dbus]: Default to dbus-for-jami. (jami-dbus-session-activation): Write a D-Bus daemon configuration file at '/var/run/jami/session-local.conf'. (jami-shepherd-services): Add the closure of guile-ac-d-bus and guile-fibers as extensions. Adjust imported modules. Remove no longer used parameters. <jami-dbus-session>: Use a PID file, avoiding the need for the manual synchronization. <jami>: Set DBUS_SESSION_BUS_ADDRESS environment variable. Poll using 'jami-service-available?' instead of 'dbus-service-available?'. * gnu/tests/telephony.scm (run-jami-test): Add needed Guile extensions. Set DBUS_SESSION_BUS_ADDRESS environment variable. Adjust all tests to use 'jami-service-available?' to determine if the service is started rather than the now problematic Shepherd's 'start-service'.