summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2005-02-21 23:14:10 +0000
committerUlrich Drepper <drepper@redhat.com>2005-02-21 23:14:10 +0000
commit553cc5f9ad5408fc7fb49a33417acc1446f0c548 (patch)
treed4feec607359c614b579876e8035ce539dfac3b8
parent53360aa17295db38e5d5e0ed16548f5f002f0fa2 (diff)
* 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>
-rw-r--r--ChangeLog46
-rw-r--r--Versions.def1
-rw-r--r--bits/types.h11
-rw-r--r--debug/Makefile13
-rw-r--r--debug/Versions7
-rw-r--r--debug/chk_fail.c2
-rw-r--r--debug/fgets_chk.c67
-rw-r--r--debug/fgets_u_chk.c65
-rw-r--r--debug/getcwd_chk.c31
-rw-r--r--debug/getwd_chk.c34
-rw-r--r--debug/pread64_chk.c33
-rw-r--r--debug/pread_chk.c33
-rw-r--r--debug/read_chk.c41
-rw-r--r--debug/readlink_chk.c41
-rw-r--r--debug/recv_chk.c33
-rw-r--r--debug/recvfrom_chk.c35
-rw-r--r--debug/tst-chk1.c81
-rw-r--r--include/stdio.h2
-rw-r--r--libio/bits/stdio2.h19
-rw-r--r--malloc/malloc.c7
-rw-r--r--posix/Makefile2
-rw-r--r--posix/bits/unistd.h78
-rw-r--r--posix/unistd.h1
-rw-r--r--socket/Makefile4
-rw-r--r--socket/bits/socket2.h38
-rw-r--r--socket/sys/socket.h8
-rw-r--r--string/bits/string3.h17
-rw-r--r--sysdeps/generic/bits/types.h11
-rw-r--r--sysdeps/generic/memset_chk.c6
-rw-r--r--sysdeps/i386/i686/memset.S8
-rw-r--r--sysdeps/i386/i686/memset_chk.S8
-rw-r--r--sysdeps/unix/sysv/linux/libc_fatal.c30
-rw-r--r--sysdeps/x86_64/memset.S8
-rw-r--r--sysdeps/x86_64/memset_chk.S6
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