diff options
author | Ulrich Drepper <drepper@redhat.com> | 2005-02-21 23:14:10 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2005-02-21 23:14:10 +0000 |
commit | 553cc5f9ad5408fc7fb49a33417acc1446f0c548 (patch) | |
tree | d4feec607359c614b579876e8035ce539dfac3b8 | |
parent | 53360aa17295db38e5d5e0ed16548f5f002f0fa2 (diff) | |
download | glibc-553cc5f9ad5408fc7fb49a33417acc1446f0c548.tar.gz glibc-553cc5f9ad5408fc7fb49a33417acc1446f0c548.tar.xz glibc-553cc5f9ad5408fc7fb49a33417acc1446f0c548.zip |
* sysdeps/unix/sysv/linux/libc_fatal.c: Print backtrace and memory
map if requested. * debug/chk_fail.c: Request backtrace and memory map dump. * Versions.def: Add GLIBC_2.4 for libc. * debug/fgets_chk.c: New file. * debug/fgets_u_chk.c: New file. * debug/getcwd_chk.c: New file. * debug/getwd_chk.c: New file. * debug/readlink_chk.c: New file. * debug/read_chk.c: New file. * debug/pread_chk.c: New file. * debug/pread64_chk.c: New file. * debug/recv_chk.c: New file. * debug/recvfrom_chk.c: New file. * debug/Versions: Add all new functions with version GLIBC_2.4. * debug/Makefile (routines): Add fgets_chk, fgets_u_chk, read_chk, pread_chk, pread64_chk, recv_chk, recvfrom_chk, readlink_chk, getwd_chk, and getcwd_chk. Plus appropriate CFLAGS definitions. * debug/tst-chk1.c: Add more tests. * libio/bits/stdio2.h: Add macros for fgets and fgets_unlocked. * include/stdio.h: Declare __fgets_chk and __fgets_unlocked_chk. * posix/unistd.h: Include <bits/unistd.h> for fortification. * posix/bits/unistd.h: New file. * posix/Makefile (headers): Add bits/unistd.h. * socket/sys/socket.h: Include <bits/socket2.h> for fortification. * socket/bits/socket2.h: New file. * socket/Makefile (headers): Add bits/socket2.h. * string/bits/string3.h: Extend memset macro to check for zero 3rd parameter and use __memset_zero_constant_len_parameter in that case. * sysdeps/generic/memset_chk.c: Add __memset_zero_constant_len_parameter alias and linker warning. * debug/Versions: Add __memset_zero_constant_len_parameter to libc with version GLIBC_2.4. * sysdeps/generic/bits/types.h: Don't unnecessarily use __extension__ in __STD_TYPE definition. 2005-02-21 Jakub Jelinek <jakub@redhat.com> * malloc/malloc.c (malloc_printerr): If MALLOC_CHECK_={5,7}, print the error message rather than program name. 2005-02-21 Ulrich Drepper <drepper@redhat.com>
34 files changed, 789 insertions, 38 deletions
diff --git a/ChangeLog b/ChangeLog index 587fa4995d..c828841de5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,51 @@ 2005-02-21 Ulrich Drepper <drepper@redhat.com> + * sysdeps/unix/sysv/linux/libc_fatal.c: Print backtrace and memory + map if requested. + * debug/chk_fail.c: Request backtrace and memory map dump. + + * Versions.def: Add GLIBC_2.4 for libc. + * debug/fgets_chk.c: New file. + * debug/fgets_u_chk.c: New file. + * debug/getcwd_chk.c: New file. + * debug/getwd_chk.c: New file. + * debug/readlink_chk.c: New file. + * debug/read_chk.c: New file. + * debug/pread_chk.c: New file. + * debug/pread64_chk.c: New file. + * debug/recv_chk.c: New file. + * debug/recvfrom_chk.c: New file. + * debug/Versions: Add all new functions with version GLIBC_2.4. + * debug/Makefile (routines): Add fgets_chk, fgets_u_chk, read_chk, + pread_chk, pread64_chk, recv_chk, recvfrom_chk, readlink_chk, + getwd_chk, and getcwd_chk. Plus appropriate CFLAGS definitions. + * debug/tst-chk1.c: Add more tests. + * libio/bits/stdio2.h: Add macros for fgets and fgets_unlocked. + * include/stdio.h: Declare __fgets_chk and __fgets_unlocked_chk. + * posix/unistd.h: Include <bits/unistd.h> for fortification. + * posix/bits/unistd.h: New file. + * posix/Makefile (headers): Add bits/unistd.h. + * socket/sys/socket.h: Include <bits/socket2.h> for fortification. + * socket/bits/socket2.h: New file. + * socket/Makefile (headers): Add bits/socket2.h. + + * string/bits/string3.h: Extend memset macro to check for zero 3rd + parameter and use __memset_zero_constant_len_parameter in that case. + * sysdeps/generic/memset_chk.c: Add + __memset_zero_constant_len_parameter alias and linker warning. + * debug/Versions: Add __memset_zero_constant_len_parameter to libc + with version GLIBC_2.4. + + * sysdeps/generic/bits/types.h: Don't unnecessarily use __extension__ + in __STD_TYPE definition. + +2005-02-21 Jakub Jelinek <jakub@redhat.com> + + * malloc/malloc.c (malloc_printerr): If MALLOC_CHECK_={5,7}, print + the error message rather than program name. + +2005-02-21 Ulrich Drepper <drepper@redhat.com> + * posix/unistd.h: symlink and readlink are unconditionally available in the 2001 spec. diff --git a/Versions.def b/Versions.def index 33409f1143..45b2127914 100644 --- a/Versions.def +++ b/Versions.def @@ -20,6 +20,7 @@ libc { GLIBC_2.3.2 GLIBC_2.3.3 GLIBC_2.3.4 + GLIBC_2.4 %ifdef USE_IN_LIBIO HURD_CTHREADS_0.3 %endif diff --git a/bits/types.h b/bits/types.h index ce48964f14..65c8a9fe90 100644 --- a/bits/types.h +++ b/bits/types.h @@ -1,5 +1,5 @@ /* bits/types.h -- definitions of __*_t types underlying *_t types. - Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc. + Copyright (C) 2002, 2003, 2004, 2005 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 @@ -114,6 +114,9 @@ typedef struct # define __ULONG32_TYPE unsigned long int # define __S64_TYPE __quad_t # define __U64_TYPE __u_quad_t +/* We want __extension__ before typedef's that use nonstandard base types + such as `long long' in C89 mode. */ +# define __STD_TYPE __extension__ typedef #elif __WORDSIZE == 64 # define __SQUAD_TYPE long int # define __UQUAD_TYPE unsigned long int @@ -123,15 +126,13 @@ typedef struct # define __ULONG32_TYPE unsigned int # define __S64_TYPE long int # define __U64_TYPE unsigned long int +/* No need to mark the typedef with __extension__. */ +# define __STD_TYPE typedef #else # error #endif #include <bits/typesizes.h> /* Defines __*_T_TYPE macros. */ -/* We want __extension__ before typedef's that use nonstandard base types - such as `long long' in C89 mode. */ -#define __STD_TYPE __extension__ typedef - __STD_TYPE __DEV_T_TYPE __dev_t; /* Type of device numbers. */ __STD_TYPE __UID_T_TYPE __uid_t; /* Type of user identifications. */ diff --git a/debug/Makefile b/debug/Makefile index 6df06116b7..a3f20fd9a7 100644 --- a/debug/Makefile +++ b/debug/Makefile @@ -1,4 +1,4 @@ -# Copyright (C) 1998, 1999, 2000, 2001, 2004 Free Software Foundation, Inc. +# Copyright (C) 1998,1999,2000,2001,2004,2005 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 @@ -29,7 +29,9 @@ routines := backtrace backtracesyms backtracesymsfd noophooks \ strcat_chk strcpy_chk strncat_chk strncpy_chk \ sprintf_chk vsprintf_chk snprintf_chk vsnprintf_chk \ printf_chk fprintf_chk vprintf_chk vfprintf_chk \ - gets_chk chk_fail readonly-area + gets_chk chk_fail readonly-area fgets_chk fgets_u_chk \ + read_chk pread_chk pread64_chk recv_chk recvfrom_chk \ + readlink_chk getwd_chk getcwd_chk CFLAGS-backtrace.c = -fno-omit-frame-pointer CFLAGS-sprintf_chk.c = -D_IO_MTSAFE_IO @@ -41,6 +43,13 @@ CFLAGS-fprintf_chk.c = -D_IO_MTSAFE_IO $(exceptions) CFLAGS-vprintf_chk.c = -D_IO_MTSAFE_IO $(exceptions) CFLAGS-vfprintf_chk.c = -D_IO_MTSAFE_IO $(exceptions) CFLAGS-gets_chk.c = -D_IO_MTSAFE_IO $(exceptions) +CFLAGS-fgets_chk.c = -D_IO_MTSAFE_IO $(exceptions) +CFLAGS-fgets_u_chk.c = -D_IO_MTSAFE_IO $(exceptions) +CFLAGS-read_chk.c = -fexceptions -fasynchronous-unwind-tables +CFLAGS-pread_chk.c = -fexceptions -fasynchronous-unwind-tables +CFLAGS-pread64_chk.c = -fexceptions -fasynchronous-unwind-tables +CFLAGS-recv_chk.c = -fexceptions -fasynchronous-unwind-tables +CFLAGS-recvfrom_chk.c = -fexceptions -fasynchronous-unwind-tables tests = backtrace-tst tst-chk1 tst-chk2 tst-chk3 \ test-strcpy_chk test-stpcpy_chk diff --git a/debug/Versions b/debug/Versions index 07d6fbb830..a4229d7852 100644 --- a/debug/Versions +++ b/debug/Versions @@ -18,4 +18,11 @@ libc { __printf_chk; __fprintf_chk; __vprintf_chk; __vfprintf_chk; __gets_chk; } + GLIBC_2.4 { + __fgets_chk; __fgets_unlocked_chk; + __read_chk; __pread_chk; __pread64_chk; + __readlink_chk; __getcwd_chk; __getwd_chk; + __memset_zero_constant_len_parameter; + __recv_chk; __recvfrom_chk; + } } diff --git a/debug/chk_fail.c b/debug/chk_fail.c index 6921ca4686..0cfca295a9 100644 --- a/debug/chk_fail.c +++ b/debug/chk_fail.c @@ -28,7 +28,7 @@ __chk_fail (void) { /* The loop is added only to keep gcc happy. */ while (1) - __libc_message (1, "*** buffer overflow detected ***: %s terminated\n", + __libc_message (2, "*** buffer overflow detected ***: %s terminated\n", __libc_argv[0] ?: "<unknown>"); } libc_hidden_def (__chk_fail) diff --git a/debug/fgets_chk.c b/debug/fgets_chk.c new file mode 100644 index 0000000000..27fbede7f0 --- /dev/null +++ b/debug/fgets_chk.c @@ -0,0 +1,67 @@ +/* Copyright (C) 1993, 1995, 1996, 1997, 1998, 1999, 2002, 2003, 2005 + 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include <stdio.h> +#include <sys/param.h> + +char * +__fgets_chk (buf, size, n, fp) + char *buf; + size_t size; + int n; + _IO_FILE *fp; +{ + _IO_size_t count; + char *result; + CHECK_FILE (fp, NULL); + if (n <= 0) + return NULL; + _IO_acquire_lock (fp); + /* This is very tricky since a file descriptor may be in the + non-blocking mode. The error flag doesn't mean much in this + case. We return an error only when there is a new error. */ + int old_error = fp->_IO_file_flags & _IO_ERR_SEEN; + fp->_IO_file_flags &= ~_IO_ERR_SEEN; + count = INTUSE(_IO_getline) (fp, buf, MIN ((size_t) n - 1, size), '\n', 1); + /* If we read in some bytes and errno is EAGAIN, that error will + be reported for next read. */ + if (count == 0 || ((fp->_IO_file_flags & _IO_ERR_SEEN) + && errno != EAGAIN)) + result = NULL; + else if (count >= size) + __chk_fail (); + else + { + buf[count] = '\0'; + result = buf; + } + fp->_IO_file_flags |= old_error; + _IO_release_lock (fp); + return result; +} diff --git a/debug/fgets_u_chk.c b/debug/fgets_u_chk.c new file mode 100644 index 0000000000..324d7e371b --- /dev/null +++ b/debug/fgets_u_chk.c @@ -0,0 +1,65 @@ +/* Copyright (C) 1993, 1995, 1996, 1997, 1998, 1999, 2002, 2003, 2005 + 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include <stdio.h> +#include <sys/param.h> + +char * +__fgets_unlocked_chk (buf, size, n, fp) + char *buf; + size_t size; + int n; + _IO_FILE *fp; +{ + _IO_size_t count; + char *result; + CHECK_FILE (fp, NULL); + if (n <= 0) + return NULL; + /* This is very tricky since a file descriptor may be in the + non-blocking mode. The error flag doesn't mean much in this + case. We return an error only when there is a new error. */ + int old_error = fp->_IO_file_flags & _IO_ERR_SEEN; + fp->_IO_file_flags &= ~_IO_ERR_SEEN; + count = INTUSE(_IO_getline) (fp, buf, MIN ((size_t) n - 1, size), '\n', 1); + /* If we read in some bytes and errno is EAGAIN, that error will + be reported for next read. */ + if (count == 0 || ((fp->_IO_file_flags & _IO_ERR_SEEN) + && errno != EAGAIN)) + result = NULL; + else if (count >= size) + __chk_fail (); + else + { + buf[count] = '\0'; + result = buf; + } + fp->_IO_file_flags |= old_error; + return result; +} diff --git a/debug/getcwd_chk.c b/debug/getcwd_chk.c new file mode 100644 index 0000000000..9e14a0102e --- /dev/null +++ b/debug/getcwd_chk.c @@ -0,0 +1,31 @@ +/* Copyright (C) 2005 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <errno.h> +#include <unistd.h> +#include <sys/param.h> + + +char * +__getcwd_chk (char *buf, size_t size, size_t buflen) +{ + char *res = __getcwd (buf, MIN (size, buflen)); + if (res == NULL && errno == ERANGE && size > buflen) + __chk_fail (); + return res; +} diff --git a/debug/getwd_chk.c b/debug/getwd_chk.c new file mode 100644 index 0000000000..898af28d3f --- /dev/null +++ b/debug/getwd_chk.c @@ -0,0 +1,34 @@ +/* Copyright (C) 2005 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <errno.h> +#include <unistd.h> +#include <sys/param.h> + + +char * +__getwd_chk (char *buf, size_t buflen) +{ + char *res = __getcwd (buf, buflen); + if (res == NULL && errno == ERANGE) + __chk_fail (); + return res; +} + +link_warning (getwd, + "the `getwd' function is dangerous and should not be used.") diff --git a/debug/pread64_chk.c b/debug/pread64_chk.c new file mode 100644 index 0000000000..5402e05b86 --- /dev/null +++ b/debug/pread64_chk.c @@ -0,0 +1,33 @@ +/* Copyright (C) 2005 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <unistd.h> +#include <sys/param.h> + + +ssize_t +__pread64_chk (int fd, void *buf, size_t nbytes, off64_t offset, size_t buflen) +{ + /* In case NBYTES is greater than BUFLEN, we read BUFLEN+1 bytes. + This might overflow the buffer but the damage is reduced to just + one byte. And the program will terminate right away. */ + ssize_t n = __pread64 (fd, buf, offset, MIN (nbytes, buflen + 1)); + if (n > 0 && (size_t) n > buflen) + __chk_fail (); + return n; +} diff --git a/debug/pread_chk.c b/debug/pread_chk.c new file mode 100644 index 0000000000..6dfa2ab499 --- /dev/null +++ b/debug/pread_chk.c @@ -0,0 +1,33 @@ +/* Copyright (C) 2005 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <unistd.h> +#include <sys/param.h> + + +ssize_t +__pread_chk (int fd, void *buf, size_t nbytes, off_t offset, size_t buflen) +{ + /* In case NBYTES is greater than BUFLEN, we read BUFLEN+1 bytes. + This might overflow the buffer but the damage is reduced to just + one byte. And the program will terminate right away. */ + ssize_t n = __pread (fd, buf, offset, MIN (nbytes, buflen + 1)); + if (n > 0 && (size_t) n > buflen) + __chk_fail (); + return n; +} diff --git a/debug/read_chk.c b/debug/read_chk.c new file mode 100644 index 0000000000..88404ed205 --- /dev/null +++ b/debug/read_chk.c @@ -0,0 +1,41 @@ +/* Copyright (C) 2005 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <unistd.h> +#include <sys/param.h> +#ifdef HAVE_INLINED_SYSCALLS +# include <errno.h> +# include <sysdep.h> +#endif + + +ssize_t +__read_chk (int fd, void *buf, size_t nbytes, size_t buflen) +{ + /* In case NBYTES is greater than BUFLEN, we read BUFLEN+1 bytes. + This might overflow the buffer but the damage is reduced to just + one byte. And the program will terminate right away. */ +#ifdef HAVE_INLINED_SYSCALLS + ssize_t n = INLINE_SYSCALL (read, 3, fd, buf, MIN (nbytes, buflen + 1)); +#else + ssize_t n = __read (fd, buf, MIN (nbytes, buflen + 1)); +#endif + if (n > 0 && (size_t) n > buflen) + __chk_fail (); + return n; +} diff --git a/debug/readlink_chk.c b/debug/readlink_chk.c new file mode 100644 index 0000000000..662041957a --- /dev/null +++ b/debug/readlink_chk.c @@ -0,0 +1,41 @@ +/* Copyright (C) 2005 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <unistd.h> +#include <sys/param.h> +#ifdef HAVE_INLINED_SYSCALLS +# include <errno.h> +# include <sysdep.h> +#endif + + +ssize_t +__readlink_chk (const char *path, void *buf, size_t len, size_t buflen) +{ + /* In case LEN is greater than BUFLEN, we read BUFLEN+1 bytes. + This might overflow the buffer but the damage is reduced to just + one byte. And the program will terminate right away. */ +#ifdef HAVE_INLINED_SYSCALLS + int n = INLINE_SYSCALL (readlink, 3, path, buf, MIN (len, buflen + 1)); +#else + int n = __readlink (path, buf, MIN (len, buflen + 1)); +#endif + if (n > 0 && (size_t) n > buflen) + __chk_fail (); + return n; +} diff --git a/debug/recv_chk.c b/debug/recv_chk.c new file mode 100644 index 0000000000..7a49d17234 --- /dev/null +++ b/debug/recv_chk.c @@ -0,0 +1,33 @@ +/* Copyright (C) 2005 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <sys/param.h> +#include <sys/socket.h> + + +ssize_t +__recv_chk (int fd, void *buf, size_t n, size_t buflen, int flags) +{ + /* In case N is greater than BUFLEN, we read BUFLEN+1 bytes. + This might overflow the buffer but the damage is reduced to just + one byte. And the program will terminate right away. */ + ssize_t nrecv = __recv (fd, buf, MIN (n, buflen + 1), flags); + if (nrecv > 0 && (size_t) nrecv > buflen) + __chk_fail (); + return nrecv; +} diff --git a/debug/recvfrom_chk.c b/debug/recvfrom_chk.c new file mode 100644 index 0000000000..e1b1da7f6b --- /dev/null +++ b/debug/recvfrom_chk.c @@ -0,0 +1,35 @@ +/* Copyright (C) 2005 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <sys/param.h> +#include <sys/socket.h> + + +ssize_t +__recvfrom_chk (int fd, void *buf, size_t n, size_t buflen, int flags, + __SOCKADDR_ARG addr, socklen_t *addr_len) +{ + /* In case N is greater than BUFLEN, we read BUFLEN+1 bytes. + This might overflow the buffer but the damage is reduced to just + one byte. And the program will terminate right away. */ + ssize_t nrecv = __recvfrom (fd, buf, MIN (n, buflen + 1), flags, + addr, addr_len); + if (nrecv > 0 && (size_t) nrecv > buflen) + __chk_fail (); + return nrecv; +} diff --git a/debug/tst-chk1.c b/debug/tst-chk1.c index 0df660d57f..3ed1cd9825 100644 --- a/debug/tst-chk1.c +++ b/debug/tst-chk1.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2004 Free Software Foundation, Inc. +/* Copyright (C) 2004, 2005 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Jakub Jelinek <jakub@redhat.com>, 2004. @@ -455,6 +455,85 @@ do_test (void) CHK_FAIL_END #endif + rewind (stdin); + + if (fgets (buf, sizeof (buf), stdin) != buf + || memcmp (buf, "abcdefgh\n", 10)) + FAIL (); + if (fgets (buf, sizeof (buf), stdin) != buf || memcmp (buf, "ABCDEFGHI", 10)) + FAIL (); + +#if __USE_FORTIFY_LEVEL >= 1 + CHK_FAIL_START + if (fgets (buf, sizeof (buf) + 1, stdin) != buf) + FAIL (); + CHK_FAIL_END +#endif + + rewind (stdin); + + if (fgets_unlocked (buf, sizeof (buf), stdin) != buf + || memcmp (buf, "abcdefgh\n", 10)) + FAIL (); + if (fgets_unlocked (buf, sizeof (buf), stdin) != buf + || memcmp (buf, "ABCDEFGHI", 10)) + FAIL (); + +#if __USE_FORTIFY_LEVEL >= 1 + CHK_FAIL_START + if (fgets_unlocked (buf, sizeof (buf) + 1, stdin) != buf) + FAIL (); + CHK_FAIL_END +#endif + + lseek (fileno (stdin), 0, SEEK_SET); + + if (read (fileno (stdin), buf, sizeof (buf) - 1) != sizeof (buf) - 1 + || memcmp (buf, "abcdefgh\n", 9)) + FAIL (); + if (read (fileno (stdin), buf, sizeof (buf) - 1) != sizeof (buf) - 1 + || memcmp (buf, "ABCDEFGHI", 9)) + FAIL (); + +#if __USE_FORTIFY_LEVEL >= 1 + CHK_FAIL_START + if (read (fileno (stdin), buf, sizeof (buf) + 1) != sizeof (buf) + 1) + FAIL (); + CHK_FAIL_END +#endif + + if (pread (fileno (stdin), buf, sizeof (buf) - 1, 0) != sizeof (buf) - 1 + || memcmp (buf, "abcdefgh\n", 9)) + FAIL (); + if (pread (fileno (stdin), buf, sizeof (buf) - 1, sizeof (buf) - 1) + != sizeof (buf) - 1 + || memcmp (buf, "ABCDEFGHI", 9)) + FAIL (); + +#if __USE_FORTIFY_LEVEL >= 1 + CHK_FAIL_START + if (pread (fileno (stdin), buf, sizeof (buf) + 1, 2 * sizeof (buf)) + != sizeof (buf) + 1) + FAIL (); + CHK_FAIL_END +#endif + + if (pread64 (fileno (stdin), buf, sizeof (buf) - 1, 0) != sizeof (buf) - 1 + || memcmp (buf, "abcdefgh\n", 9)) + FAIL (); + if (pread64 (fileno (stdin), buf, sizeof (buf) - 1, sizeof (buf) - 1) + != sizeof (buf) - 1 + || memcmp (buf, "ABCDEFGHI", 9)) + FAIL (); + +#if __USE_FORTIFY_LEVEL >= 1 + CHK_FAIL_START + if (pread64 (fileno (stdin), buf, sizeof (buf) + 1, 2 * (sizeof (buf) - 1)) + != sizeof (buf) + 1) + FAIL (); + CHK_FAIL_END +#endif + if (freopen (temp_filename, "r", stdin) == NULL) { puts ("could not open temporary file"); diff --git a/include/stdio.h b/include/stdio.h index 0c1e8fca10..c8c89ad878 100644 --- a/include/stdio.h +++ b/include/stdio.h @@ -38,6 +38,8 @@ extern int __printf_chk (int, const char *, ...); extern int __fprintf_chk (FILE *, int, const char *, ...); extern int __vprintf_chk (int, const char *, _G_va_list); extern int __vfprintf_chk (FILE *, int, const char *, _G_va_list); +extern char *__fgets_unlocked_chk (char *buf, size_t size, int n, FILE *fp); +extern char *__fgets_chk (char *buf, size_t size, int n, FILE *fp); /* Prototypes for compatibility functions. */ extern FILE *__new_tmpfile (void); diff --git a/libio/bits/stdio2.h b/libio/bits/stdio2.h index acf07ea91b..4181f8a9a9 100644 --- a/libio/bits/stdio2.h +++ b/libio/bits/stdio2.h @@ -1,5 +1,5 @@ /* Checking macros for stdio functions. - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004, 2005 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 @@ -49,7 +49,7 @@ extern int __vsnprintf_chk (char *__restrict __s, size_t __n, int __flag, __builtin___vsnprintf_chk (str, len, __USE_FORTIFY_LEVEL - 1, __bos (str), \ fmt, ap) -#endif +#endif #if __USE_FORTIFY_LEVEL > 1 @@ -74,5 +74,16 @@ extern int __vprintf_chk (int __flag, __const char *__restrict __format, extern char *__gets_chk (char *__str, size_t); #define gets(__str) \ - ((__bos (__str) == (size_t) -1) \ - ? (gets) (__str) : __gets_chk (__str, __bos (__str))) + ((__bos (__str) == (size_t) -1) \ + ? gets (__str) : __gets_chk (__str, __bos (__str))) + +extern char *__fgets_chk (char *s, size_t size, int n, FILE *stream); +#define fgets(__str, __n, __fp) \ + ((__bos (__str) == (size_t) -1) \ + ? fgets (__str, __n, __fp) : __fgets_chk (__str, __bos (__str), __n, __fp)) + +extern char *__fgets_unlocked_chk (char *s, size_t size, int n, FILE *stream); +#define fgets_unlocked(__str, __n, __fp) \ + ((__bos (__str) == (size_t) -1) \ + ? fgets_unlocked (__str, __n, __fp) \ + : __fgets_unlocked_chk (__str, __bos (__str), __n, __fp)) diff --git a/malloc/malloc.c b/malloc/malloc.c index 4d2169bf78..5c9e77e9ec 100644 --- a/malloc/malloc.c +++ b/malloc/malloc.c @@ -5513,7 +5513,9 @@ extern char **__libc_argv attribute_hidden; static void malloc_printerr(int action, const char *str, void *ptr) { - if (action & 1) + if ((action & 5) == 5) + __libc_message (action & 2, "%s\n", str); + else if (action & 1) { char buf[2 * sizeof (uintptr_t) + 1]; @@ -5523,8 +5525,7 @@ malloc_printerr(int action, const char *str, void *ptr) *--cp = '0'; __libc_message (action & 2, - action & 4 - ? "%s\n" : "*** glibc detected *** %s: %s: 0x%s ***\n", + "*** glibc detected *** %s: %s: 0x%s ***\n", __libc_argv[0] ?: "<unknown>", str, cp); } else if (action & 2) diff --git a/posix/Makefile b/posix/Makefile index 929ea47790..f79d079320 100644 --- a/posix/Makefile +++ b/posix/Makefile @@ -28,7 +28,7 @@ headers := sys/utsname.h sys/times.h sys/wait.h sys/types.h unistd.h \ bits/local_lim.h tar.h bits/utsname.h bits/confname.h \ bits/waitflags.h bits/waitstatus.h sys/unistd.h sched.h \ bits/sched.h re_comp.h wait.h bits/environments.h cpio.h \ - sys/sysmacros.h spawn.h + sys/sysmacros.h spawn.h bits/unistd.h distribute := confstr.h TESTS TESTS2C.sed testcases.h \ PTESTS PTESTS2C.sed ptestcases.h \ diff --git a/posix/bits/unistd.h b/posix/bits/unistd.h new file mode 100644 index 0000000000..3b9c67cb31 --- /dev/null +++ b/posix/bits/unistd.h @@ -0,0 +1,78 @@ +/* Checking macros for unistd functions. + Copyright (C) 2005 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#ifndef _UNISTD_H +# error "Never include <bits/unistd.h> directly; use <unistd.h> instead." +#endif + +extern ssize_t __read_chk (int __fd, void *__buf, size_t __nbytes, + size_t __buflen) __wur; +#define read(fd, buf, nbytes) \ + (__bos (buf) != (size_t) -1 \ + ? __read_chk (fd, buf, nbytes, __bos (buf)) \ + : read (fd, buf, nbytes)) + +#ifdef __USE_UNIX98 +extern ssize_t __pread_chk (int __fd, void *__buf, size_t __nbytes, + __off_t __offset, size_t __bufsize) __wur; +extern ssize_t __pread64_chk (int __fd, void *__buf, size_t __nbytes, + __off64_t __offset, size_t __bufsize) __wur; +# ifndef __USE_FILE_OFFSET64 +# define pread(fd, buf, nbytes, offset) \ + (__bos (buf) != (size_t) -1 \ + ? __pread64_chk (fd, buf, nbytes, offset, __bos (buf)) \ + : pread (fd, buf, offset, nbytes)) +# else +# define pread(fd, buf, nbytes, offset) \ + (__bos (buf) != (size_t) -1 \ + ? __pread_chk (fd, buf, nbytes, offset, __bos (buf)) \ + : pread (fd, buf, offset, nbytes)) +# endif + +# ifdef __USE_LARGEFILE64 +# define pread64(fd, buf, nbytes, offset) \ + (__bos (buf) != (size_t) -1 \ + ? __pread64_chk (fd, buf, nbytes, offset, __bos (buf)) \ + : pread64 (fd, buf, offset, nbytes)) +# endif +#endif + +#if defined __USE_BSD || defined __USE_XOPEN_EXTENDED || defined __USE_XOPEN2K +extern int __readlink_chk (__const char *__restrict __path, + char *__restrict __buf, size_t __len, + size_t __buflen) + __THROW __nonnull ((1, 2)) __wur; +# define readlink(path, buf, len) \ + (__bos (buf) != (size_t) -1 \ + ? __readlink_chk (path, buf, len, __bos (buf)) \ + : readlink (path, buf, len)) +#endif + +extern char *__getcwd_chk (char *__buf, size_t __size, size_t __buflen) + __THROW __wur; +#define getcwd(buf, size) \ + (__bos (buf) != (size_t) -1 \ + ? __getcwd_chk (buf, size, buflen) : getcwd (buf, size)) + +#if defined __USE_BSD || defined __USE_XOPEN_EXTENDED +extern char *__getwd_chk (char *__buf, size_t buflen) + __THROW __nonnull ((1)) __attribute_deprecated__ __wur; +#define getwd(buf) \ + (__bos (buf) != (size_t) -1 ? __getwd_chk (buf, buflen) : getwd (buf)) +#endif diff --git a/posix/unistd.h b/posix/unistd.h index 97e28fc70b..d6cd152b46 100644 --- a/posix/unistd.h +++ b/posix/unistd.h @@ -1046,6 +1046,7 @@ extern void swab (__const void *__restrict __from, void *__restrict __to, extern char *ctermid (char *__s) __THROW __nonnull ((1)); #endif + /* Define some macros helping to catch buffer overflows. */ #if __USE_FORTIFY_LEVEL > 0 && !defined __cplusplus # include <bits/unistd.h> diff --git a/socket/Makefile b/socket/Makefile index 594e609db5..aa0776e5bf 100644 --- a/socket/Makefile +++ b/socket/Makefile @@ -1,4 +1,4 @@ -# Copyright (C) 1991,95,96,97,98,99,2000,2001 Free Software Foundation, Inc. +# Copyright (C) 1991,1995-2001,2005 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 @@ -22,7 +22,7 @@ subdir := socket headers := sys/socket.h sys/un.h bits/sockaddr.h bits/socket.h \ - sys/socketvar.h net/if.h + bits/socket2.h sys/socketvar.h net/if.h routines := accept bind connect getpeername getsockname getsockopt \ listen recv recvfrom recvmsg send sendmsg sendto \ diff --git a/socket/bits/socket2.h b/socket/bits/socket2.h new file mode 100644 index 0000000000..bb75907744 --- /dev/null +++ b/socket/bits/socket2.h @@ -0,0 +1,38 @@ +/* Checking macros for socket functions. + Copyright (C) 2005 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#ifndef _SYS_SOCKET_H +# error "Never include <bits/socket2.h> directly; use <sys/socket.h> instead." +#endif + +extern ssize_t __recv_chk (int __fd, void *__buf, size_t __n, size_t __buflen, + int __flags); +#define recv(fd, buf, n, flags) \ + (__bos (buf) != (size_t) -1 \ + ? __recv_chk (fd, buf, n, __bos (buf), flags) \ + : recv (fd, buf, n, flags)) + +extern ssize_t __recvfrom_chk (int __fd, void *__restrict __buf, size_t __n, + size_t __buflen, int __flags, + __SOCKADDR_ARG __addr, + socklen_t *__restrict __addr_len); +#define recvfrom(fd, buf, n, flags, addr, addr_len) \ + (__bos (buf) != (size_t) -1 \ + ? __recvfrom_chk (fd, buf, n, __bos (buf), flags, addr, addr_len) \ + : recvfrom (fd, buf, n, flags, addr, addr_len)) diff --git a/socket/sys/socket.h b/socket/sys/socket.h index 4ae1ea9808..4112852ebb 100644 --- a/socket/sys/socket.h +++ b/socket/sys/socket.h @@ -1,5 +1,5 @@ /* Declarations of socket constants, types, and functions. - Copyright (C) 1991,92,1994-2001,2003 Free Software Foundation, Inc. + Copyright (C) 1991,92,1994-2001,2003,2005 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 @@ -231,6 +231,12 @@ extern int sockatmark (int __fd) __THROW; extern int isfdtype (int __fd, int __fdtype) __THROW; #endif + +/* Define some macros helping to catch buffer overflows. */ +#if __USE_FORTIFY_LEVEL > 0 && !defined __cplusplus +# include <bits/socket2.h> +#endif + __END_DECLS #endif /* sys/socket.h */ diff --git a/string/bits/string3.h b/string/bits/string3.h index 87cbe35bb1..8fb66e41c8 100644 --- a/string/bits/string3.h +++ b/string/bits/string3.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2004 Free Software Foundation, Inc. +/* Copyright (C) 2004, 2005 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 @@ -80,10 +80,19 @@ __mempcpy_ichk (void *__restrict __dest, const void *__restrict __src, #endif +/* The first two tests here help to catch a somewhat common problem + where the second and third parameter are transposed. This is + especially problematic if the intended fill value is zero. In this + case no work is done at all. We detect these problems by referring + non-existing functions. */ +extern char *__memset_zero_constant_len_parameter (void *, int, size_t, + size_t); #define memset(dest, ch, len) \ - ((__bos0 (dest) != (size_t) -1) \ - ? __builtin___memset_chk (dest, ch, len, __bos0 (dest)) \ - : __memset_ichk (dest, ch, len)) + (__builtin_constant_p (len) && (len) == 0 \ + ? __memset_zero_constant_len_parameter (dest, ch, len, 0) \ + : ((__bos0 (dest) != (size_t) -1) \ + ? __builtin___memset_chk (dest, ch, len, __bos0 (dest)) \ + : __memset_ichk (dest, ch, len))) static __inline__ void * __attribute__ ((__always_inline__)) __memset_ichk (void *__dest, int __ch, size_t __len) diff --git a/sysdeps/generic/bits/types.h b/sysdeps/generic/bits/types.h index ce48964f14..65c8a9fe90 100644 --- a/sysdeps/generic/bits/types.h +++ b/sysdeps/generic/bits/types.h @@ -1,5 +1,5 @@ /* bits/types.h -- definitions of __*_t types underlying *_t types. - Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc. + Copyright (C) 2002, 2003, 2004, 2005 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 @@ -114,6 +114,9 @@ typedef struct # define __ULONG32_TYPE unsigned long int # define __S64_TYPE __quad_t # define __U64_TYPE __u_quad_t +/* We want __extension__ before typedef's that use nonstandard base types + such as `long long' in C89 mode. */ +# define __STD_TYPE __extension__ typedef #elif __WORDSIZE == 64 # define __SQUAD_TYPE long int # define __UQUAD_TYPE unsigned long int @@ -123,15 +126,13 @@ typedef struct # define __ULONG32_TYPE unsigned int # define __S64_TYPE long int # define __U64_TYPE unsigned long int +/* No need to mark the typedef with __extension__. */ +# define __STD_TYPE typedef #else # error #endif #include <bits/typesizes.h> /* Defines __*_T_TYPE macros. */ -/* We want __extension__ before typedef's that use nonstandard base types - such as `long long' in C89 mode. */ -#define __STD_TYPE __extension__ typedef - __STD_TYPE __DEV_T_TYPE __dev_t; /* Type of device numbers. */ __STD_TYPE __UID_T_TYPE __uid_t; /* Type of user identifications. */ diff --git a/sysdeps/generic/memset_chk.c b/sysdeps/generic/memset_chk.c index c311914395..dfdcfbca3d 100644 --- a/sysdeps/generic/memset_chk.c +++ b/sysdeps/generic/memset_chk.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991, 1997, 2003, 2004 Free Software Foundation, Inc. +/* Copyright (C) 1991, 1997, 2003, 2004, 2005 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 @@ -90,3 +90,7 @@ __memset_chk (dstpp, c, len, dstlen) return dstpp; } +strong_alias (__memset_chk, __memset_zero_constant_len_parameter) + +link_warning (__memset_zero_constant_len_parameter, + "memset used with constant zero length parameter; this could be due to transposed parameters") diff --git a/sysdeps/i386/i686/memset.S b/sysdeps/i386/i686/memset.S index 561188ffec..0b47547141 100644 --- a/sysdeps/i386/i686/memset.S +++ b/sysdeps/i386/i686/memset.S @@ -1,6 +1,6 @@ /* memset/bzero -- set memory area to CH/0 Highly optimized version for ix86, x>=6. - Copyright (C) 1999, 2000, 2003 Free Software Foundation, Inc. + Copyright (C) 1999, 2000, 2003, 2005 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999. @@ -101,3 +101,9 @@ ENTRY (BP_SYM (memset)) #endif END (BP_SYM (memset)) libc_hidden_builtin_def (memset) + +#if defined PIC && !defined NOT_IN_libc && !BZERO_P +strong_alias (__memset_chk, __memset_zero_constant_len_parameter) + .section .gnu.warning.__memset_zero_constant_len_parameter + .string "memset used with constant zero length parameter; this could be due to transposed parameters" +#endif diff --git a/sysdeps/i386/i686/memset_chk.S b/sysdeps/i386/i686/memset_chk.S index d178654994..b71cf32a05 100644 --- a/sysdeps/i386/i686/memset_chk.S +++ b/sysdeps/i386/i686/memset_chk.S @@ -1,5 +1,5 @@ -/* Checking memset for x86-64. - Copyright (C) 2004 Free Software Foundation, Inc. +/* Checking memset for i686. + Copyright (C) 2004, 2005 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 @@ -32,4 +32,8 @@ ENTRY (__memset_chk) jb __chk_fail jmp memset END (__memset_chk) + +strong_alias (__memset_chk, __memset_zero_constant_len_parameter) + .section .gnu.warning.__memset_zero_constant_len_parameter + .string "memset used with constant zero length parameter; this could be due to transposed parameters" #endif diff --git a/sysdeps/unix/sysv/linux/libc_fatal.c b/sysdeps/unix/sysv/linux/libc_fatal.c index a79cfbabb9..4c304250eb 100644 --- a/sysdeps/unix/sysv/linux/libc_fatal.c +++ b/sysdeps/unix/sysv/linux/libc_fatal.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-1995,1997,2000,2002-2004 Free Software Foundation, Inc. +/* Copyright (C) 1993-1995,1997,2000,2002-2005 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 @@ -141,8 +141,32 @@ __libc_message (int do_abort, const char *fmt, ...) va_end (ap_copy); if (do_abort) - /* Terminate the process. */ - abort (); + { + if (do_abort > 1 && written) + { + void *addrs[64]; +#define naddrs (sizeof (addrs) / sizeof (addrs[0])) + int n = __backtrace (addrs, naddrs); + if (n > 2) + { +#define strnsize(str) str, strlen (str) + write (fd, strnsize ("======= Backtrace: =========\n")); + __backtrace_symbols_fd (addrs + 1, n - 1, fd); + + write (fd, strnsize ("======= Memory map: ========\n")); + int fd2 = open ("/proc/self/maps", O_RDONLY); + char buf[1024]; + ssize_t n2; + while ((n2 = read (fd2, buf, sizeof (buf))) > 0) + if (write (fd, buf, n2) != n2) + break; + close (fd2); + } + } + + /* Terminate the process. */ + abort (); + } } diff --git a/sysdeps/x86_64/memset.S b/sysdeps/x86_64/memset.S index 6c47f4c863..6b718b7126 100644 --- a/sysdeps/x86_64/memset.S +++ b/sysdeps/x86_64/memset.S @@ -1,6 +1,6 @@ /* memset/bzero -- set memory area to CH/0 Optimized version for x86-64. - Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc. + Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Andreas Jaeger <aj@suse.de>. @@ -138,3 +138,9 @@ END (memset) #if !BZERO_P libc_hidden_builtin_def (memset) #endif + +#if !BZERO_P && defined PIC && !defined NOT_IN_libc +strong_alias (__memset_chk, __memset_zero_constant_len_parameter) + .section .gnu.warning.__memset_zero_constant_len_parameter + .string "memset used with constant zero length parameter; this could be due to transposed parameters" +#endif diff --git a/sysdeps/x86_64/memset_chk.S b/sysdeps/x86_64/memset_chk.S index e62cb58cc0..063f153bef 100644 --- a/sysdeps/x86_64/memset_chk.S +++ b/sysdeps/x86_64/memset_chk.S @@ -1,5 +1,5 @@ /* Checking memset for x86-64. - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004, 2005 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 @@ -31,4 +31,8 @@ ENTRY (__memset_chk) jb __chk_fail jmp memset END (__memset_chk) + +strong_alias (__memset_chk, __memset_zero_constant_len_parameter) + .section .gnu.warning.__memset_zero_constant_len_parameter + .string "memset used with constant zero length parameter; this could be due to transposed parameters" #endif |