diff options
Diffstat (limited to 'REORG.TODO/debug')
117 files changed, 7926 insertions, 0 deletions
diff --git a/REORG.TODO/debug/Depend b/REORG.TODO/debug/Depend new file mode 100644 index 0000000000..f3e1156a4e --- /dev/null +++ b/REORG.TODO/debug/Depend @@ -0,0 +1 @@ +localedata diff --git a/REORG.TODO/debug/Makefile b/REORG.TODO/debug/Makefile new file mode 100644 index 0000000000..cd4975c35b --- /dev/null +++ b/REORG.TODO/debug/Makefile @@ -0,0 +1,199 @@ +# Copyright (C) 1998-2017 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. + +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. + +# You should have received a copy of the GNU Lesser General Public +# License along with the GNU C Library; if not, see +# <http://www.gnu.org/licenses/>. + +# +# Sub-makefile for debug portion of the library. +# +subdir := debug + +include ../Makeconfig + +headers := execinfo.h + +# Note that ptsname_r_chk and getlogin_r are not here, but in +# login/Makefile instead. If that subdir is omitted from the +# build, its _FORTIFY_SOURCE support will be too. +routines = backtrace backtracesyms backtracesymsfd noophooks \ + memcpy_chk memmove_chk mempcpy_chk memset_chk stpcpy_chk \ + strcat_chk strcpy_chk strncat_chk strncpy_chk stpncpy_chk \ + sprintf_chk vsprintf_chk snprintf_chk vsnprintf_chk \ + printf_chk fprintf_chk vprintf_chk vfprintf_chk \ + gets_chk chk_fail readonly-area fgets_chk fgets_u_chk \ + read_chk pread_chk pread64_chk recv_chk recvfrom_chk \ + readlink_chk readlinkat_chk getwd_chk getcwd_chk \ + realpath_chk fread_chk fread_u_chk \ + wctomb_chk wcscpy_chk wmemcpy_chk wmemmove_chk wmempcpy_chk \ + wcpcpy_chk wcsncpy_chk wcscat_chk wcsncat_chk wmemset_chk \ + wcpncpy_chk \ + swprintf_chk vswprintf_chk wprintf_chk fwprintf_chk \ + vwprintf_chk vfwprintf_chk fgetws_chk fgetws_u_chk \ + confstr_chk getgroups_chk ttyname_r_chk \ + gethostname_chk getdomainname_chk wcrtomb_chk mbsnrtowcs_chk \ + wcsnrtombs_chk mbsrtowcs_chk wcsrtombs_chk mbstowcs_chk \ + wcstombs_chk asprintf_chk vasprintf_chk dprintf_chk \ + vdprintf_chk obprintf_chk \ + longjmp_chk ____longjmp_chk \ + fdelt_chk poll_chk ppoll_chk \ + explicit_bzero_chk \ + stack_chk_fail fortify_fail \ + $(static-only-routines) +static-only-routines := warning-nop stack_chk_fail_local + +# Building the stack-protector failure routines with stack protection +# makes no sense. + +CFLAGS-stack_chk_fail.c = $(no-stack-protector) +CFLAGS-stack_chk_fail_local.c = $(no-stack-protector) + +CFLAGS-backtrace.c = -fno-omit-frame-pointer +CFLAGS-sprintf_chk.c = $(libio-mtsafe) +CFLAGS-snprintf_chk.c = $(libio-mtsafe) +CFLAGS-vsprintf_chk.c = $(libio-mtsafe) +CFLAGS-vsnprintf_chk.c = $(libio-mtsafe) +CFLAGS-asprintf_chk.c = $(libio-mtsafe) +CFLAGS-vasprintf_chk.c = $(libio-mtsafe) +CFLAGS-obprintf_chk.c = $(libio-mtsafe) +CFLAGS-dprintf_chk.c = $(libio-mtsafe) -fexceptions +CFLAGS-vdprintf_chk.c = $(libio-mtsafe) -fexceptions +CFLAGS-printf_chk.c = $(libio-mtsafe) -fexceptions +CFLAGS-fprintf_chk.c = $(libio-mtsafe) -fexceptions +CFLAGS-vprintf_chk.c = $(libio-mtsafe) -fexceptions +CFLAGS-vfprintf_chk.c = $(libio-mtsafe) -fexceptions +CFLAGS-gets_chk.c = $(libio-mtsafe) -fexceptions +CFLAGS-fgets_chk.c = $(libio-mtsafe) -fexceptions +CFLAGS-fgets_u_chk.c = $(libio-mtsafe) -fexceptions +CFLAGS-fread_chk.c = $(libio-mtsafe) -fexceptions +CFLAGS-fread_u_chk.c = $(libio-mtsafe) -fexceptions +CFLAGS-swprintf_chk.c = $(libio-mtsafe) +CFLAGS-vswprintf_chk.c = $(libio-mtsafe) +CFLAGS-wprintf_chk.c = $(libio-mtsafe) -fexceptions +CFLAGS-fwprintf_chk.c = $(libio-mtsafe) -fexceptions +CFLAGS-vwprintf_chk.c = $(libio-mtsafe) -fexceptions +CFLAGS-vfwprintf_chk.c = $(libio-mtsafe) -fexceptions +CFLAGS-fgetws_chk.c = $(libio-mtsafe) -fexceptions +CFLAGS-fgetws_u_chk.c = $(libio-mtsafe) -fexceptions +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 + +# Need to make sure the settings here override what configure might have +# set up for us, so keep the CFLAGS/CPPFLAGS split logical as the order is: +# <user CFLAGS> <test CFLAGS> <user CPPFLAGS> <test CPPFLAGS> +CFLAGS-tst-longjmp_chk.c = -fexceptions -fasynchronous-unwind-tables +CPPFLAGS-tst-longjmp_chk.c = -D_FORTIFY_SOURCE=1 +CFLAGS-tst-longjmp_chk2.c = -fexceptions -fasynchronous-unwind-tables +CPPFLAGS-tst-longjmp_chk2.c = -D_FORTIFY_SOURCE=1 +CFLAGS-tst-longjmp_chk3.c = -fexceptions -fasynchronous-unwind-tables +CPPFLAGS-tst-longjmp_chk3.c = -D_FORTIFY_SOURCE=1 + +# We know these tests have problems with format strings, this is what +# we are testing. Disable that warning. They are also testing +# deprecated functions (notably gets) so disable that warning as well. +# And they also generate warnings from warning attributes, which +# cannot be disabled via pragmas, so require -Wno-error to be used. +CFLAGS-tst-chk1.c = -Wno-format -Wno-deprecated-declarations -Wno-error +CFLAGS-tst-chk2.c = -Wno-format -Wno-deprecated-declarations -Wno-error +CFLAGS-tst-chk3.c = -Wno-format -Wno-deprecated-declarations -Wno-error +CFLAGS-tst-chk4.cc = -Wno-format -Wno-deprecated-declarations -Wno-error +CFLAGS-tst-chk5.cc = -Wno-format -Wno-deprecated-declarations -Wno-error +CFLAGS-tst-chk6.cc = -Wno-format -Wno-deprecated-declarations -Wno-error +CFLAGS-tst-lfschk1.c = -Wno-format -Wno-deprecated-declarations -Wno-error +CFLAGS-tst-lfschk2.c = -Wno-format -Wno-deprecated-declarations -Wno-error +CFLAGS-tst-lfschk3.c = -Wno-format -Wno-deprecated-declarations -Wno-error +CFLAGS-tst-lfschk4.cc = -Wno-format -Wno-deprecated-declarations -Wno-error +CFLAGS-tst-lfschk5.cc = -Wno-format -Wno-deprecated-declarations -Wno-error +CFLAGS-tst-lfschk6.cc = -Wno-format -Wno-deprecated-declarations -Wno-error +LDLIBS-tst-chk4 = -lstdc++ +LDLIBS-tst-chk5 = -lstdc++ +LDLIBS-tst-chk6 = -lstdc++ +LDLIBS-tst-lfschk4 = -lstdc++ +LDLIBS-tst-lfschk5 = -lstdc++ +LDLIBS-tst-lfschk6 = -lstdc++ + +# backtrace_symbols only works if we link with -rdynamic. backtrace +# requires unwind tables on most architectures. +CFLAGS-tst-backtrace2.c += -funwind-tables +CFLAGS-tst-backtrace3.c += -funwind-tables +CFLAGS-tst-backtrace4.c += -funwind-tables +CFLAGS-tst-backtrace5.c += -funwind-tables +CFLAGS-tst-backtrace6.c += -funwind-tables +LDFLAGS-tst-backtrace2 = -rdynamic +LDFLAGS-tst-backtrace3 = -rdynamic +LDFLAGS-tst-backtrace4 = -rdynamic +LDFLAGS-tst-backtrace5 = -rdynamic +LDFLAGS-tst-backtrace6 = -rdynamic + +tests = backtrace-tst tst-longjmp_chk tst-chk1 tst-chk2 tst-chk3 \ + tst-lfschk1 tst-lfschk2 tst-lfschk3 test-strcpy_chk test-stpcpy_chk \ + tst-chk4 tst-chk5 tst-chk6 tst-lfschk4 tst-lfschk5 tst-lfschk6 \ + tst-longjmp_chk2 tst-backtrace2 tst-backtrace3 tst-backtrace4 \ + tst-backtrace5 tst-backtrace6 + +ifeq (,$(CXX)) +tests-unsupported = tst-chk4 tst-chk5 tst-chk6 \ + tst-lfschk4 tst-lfschk5 tst-lfschk6 +endif + +extra-libs = libSegFault libpcprofile +extra-libs-others = $(extra-libs) + +libSegFault-routines = segfault +libSegFault-inhibit-o = $(filter-out .os,$(object-suffixes)) + +libpcprofile-routines = pcprofile +libpcprofile-inhibit-o = $(filter-out .os,$(object-suffixes)) + +others = pcprofiledump +install-bin = pcprofiledump +install-bin-script = xtrace + +ifeq ($(build-shared),yes) +install-bin-script += catchsegv +endif +generated += catchsegv xtrace + +include ../Rules + +ifeq ($(run-built-tests),yes) +LOCALES := de_DE.UTF-8 +include ../gen-locales.mk + +$(objpfx)tst-chk1.out: $(gen-locales) +endif + +sLIBdir := $(shell echo $(slibdir) | sed 's,lib\(\|64\)$$,\\\\$$LIB,') + +$(objpfx)catchsegv: catchsegv.sh $(common-objpfx)soversions.mk \ + $(common-objpfx)config.make + slibpfx=`echo $(slibdir)|sed 's/lib\(64\|\)$$/\\\\\\\\$$LIB/'`; \ + sed -e 's|@VERSION@|$(version)|' -e "s|@SLIB@|$$slibpfx|" \ + -e 's|@PKGVERSION@|$(PKGVERSION)|' \ + -e 's|@REPORT_BUGS_TO@|$(REPORT_BUGS_TO)|' $< > $@.new + chmod 555 $@.new + mv -f $@.new $@ + +$(objpfx)pcprofiledump: $(objpfx)pcprofiledump.o + +$(objpfx)xtrace: xtrace.sh + rm -f $@.new + sed -e 's|@BASH@|$(BASH)|' -e 's|@VERSION@|$(version)|' \ + -e 's|@SLIBDIR@|$(sLIBdir)|' -e 's|@BINDIR@|$(bindir)|' \ + -e 's|@PKGVERSION@|$(PKGVERSION)|' \ + -e 's|@REPORT_BUGS_TO@|$(REPORT_BUGS_TO)|' $^ > $@.new \ + && rm -f $@ && mv $@.new $@ && chmod +x $@ diff --git a/REORG.TODO/debug/Versions b/REORG.TODO/debug/Versions new file mode 100644 index 0000000000..a6628db356 --- /dev/null +++ b/REORG.TODO/debug/Versions @@ -0,0 +1,64 @@ +libc { + GLIBC_2.1 { + # functions used in other libraries + __backtrace; __backtrace_symbols; __backtrace_symbols_fd; + + # b* + backtrace; backtrace_symbols; backtrace_symbols_fd; + } + GLIBC_2.2 { + # These are to support some gcc features. + __cyg_profile_func_enter; __cyg_profile_func_exit; + } + GLIBC_2.3.4 { + __chk_fail; + __memcpy_chk; __memmove_chk; __mempcpy_chk; __memset_chk; __stpcpy_chk; + __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; + } + GLIBC_2.4 { + __fgets_chk; __fgets_unlocked_chk; + __read_chk; __pread_chk; __pread64_chk; + __readlink_chk; __getcwd_chk; __getwd_chk; + __recv_chk; __recvfrom_chk; + __realpath_chk; __wctomb_chk; + __stpncpy_chk; + __wcscpy_chk; __wmemcpy_chk; __wmemmove_chk; __wmempcpy_chk; __wcpcpy_chk; + __wcsncpy_chk; __wcscat_chk; __wcsncat_chk; __wmemset_chk; __wcpncpy_chk; + __swprintf_chk; __vswprintf_chk; __wprintf_chk; __fwprintf_chk; + __vwprintf_chk; __vfwprintf_chk; __fgetws_chk; __fgetws_unlocked_chk; + __confstr_chk; __getgroups_chk; __ttyname_r_chk; + __gethostname_chk; __getdomainname_chk; __wcrtomb_chk; __mbsnrtowcs_chk; + __wcsnrtombs_chk; __mbsrtowcs_chk; __wcsrtombs_chk; __mbstowcs_chk; + __wcstombs_chk; + + __stack_chk_fail; + } + GLIBC_2.5 { + __readlinkat_chk; + } + GLIBC_2.7 { + __fread_chk; __fread_unlocked_chk; + } + GLIBC_2.8 { + __asprintf_chk; __vasprintf_chk; __dprintf_chk; __vdprintf_chk; + __obstack_printf_chk; __obstack_vprintf_chk; + } + GLIBC_2.11 { + __longjmp_chk; + } + GLIBC_2.15 { + __fdelt_chk; __fdelt_warn; + } + GLIBC_2.16 { + __poll_chk; __ppoll_chk; + } + GLIBC_2.25 { + __explicit_bzero_chk; + } + GLIBC_PRIVATE { + __fortify_fail; + } +} diff --git a/REORG.TODO/debug/asprintf_chk.c b/REORG.TODO/debug/asprintf_chk.c new file mode 100644 index 0000000000..a8ab89185d --- /dev/null +++ b/REORG.TODO/debug/asprintf_chk.c @@ -0,0 +1,36 @@ +/* Copyright (C) 1991-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <libioP.h> +#include <stdarg.h> +#include <stdio.h> + + +/* Write formatted output from FORMAT to a string which is + allocated with malloc and stored in *STRING_PTR. */ +int +__asprintf_chk (char **result_ptr, int flags, const char *format, ...) +{ + va_list arg; + int done; + + va_start (arg, format); + done = __vasprintf_chk (result_ptr, flags, format, arg); + va_end (arg); + + return done; +} diff --git a/REORG.TODO/debug/backtrace-tst.c b/REORG.TODO/debug/backtrace-tst.c new file mode 100644 index 0000000000..cc46c33c3c --- /dev/null +++ b/REORG.TODO/debug/backtrace-tst.c @@ -0,0 +1,45 @@ +#include <execinfo.h> +#include <inttypes.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> + + +static int +compare (const void *p1, const void *p2) +{ + void *ba[20]; + int n = backtrace (ba, sizeof (ba) / sizeof (ba[0])); + if (n != 0) + { + char **names = backtrace_symbols (ba, n); + if (names != NULL) + { + int i; + printf ("called from %s\n", names[0]); + for (i = 1; i < n; ++i) + printf (" %s\n", names[i]); + free (names); + } + } + + return *(const uint32_t *) p1 - *(const uint32_t *) p2; +} + + +int +main (int argc, char *argv[]) +{ + uint32_t arr[20]; + size_t cnt; + + for (cnt = 0; cnt < sizeof (arr) / sizeof (arr[0]); ++cnt) + arr[cnt] = random (); + + qsort (arr, sizeof (arr) / sizeof (arr[0]), sizeof (arr[0]), compare); + + for (cnt = 0; cnt < sizeof (arr) / sizeof (arr[0]); ++cnt) + printf ("%" PRIx32 "\n", arr[cnt]); + + return 0; +} diff --git a/REORG.TODO/debug/backtrace.c b/REORG.TODO/debug/backtrace.c new file mode 100644 index 0000000000..072fc2f7f8 --- /dev/null +++ b/REORG.TODO/debug/backtrace.c @@ -0,0 +1,90 @@ +/* Return backtrace of current program state. Generic version. + Copyright (C) 1998-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <execinfo.h> +#include <signal.h> +#include <frame.h> +#include <sigcontextinfo.h> +#include <ldsodefs.h> + +/* This implementation assumes a stack layout that matches the defaults + used by gcc's `__builtin_frame_address' and `__builtin_return_address' + (FP is the frame pointer register): + + +-----------------+ +-----------------+ + FP -> | previous FP --------> | previous FP ------>... + | | | | + | return address | | return address | + +-----------------+ +-----------------+ + + */ + +/* Get some notion of the current stack. Need not be exactly the top + of the stack, just something somewhere in the current frame. */ +#ifndef CURRENT_STACK_FRAME +# define CURRENT_STACK_FRAME ({ char __csf; &__csf; }) +#endif + +/* By default we assume that the stack grows downward. */ +#ifndef INNER_THAN +# define INNER_THAN < +#endif + +/* By default assume the `next' pointer in struct layout points to the + next struct layout. */ +#ifndef ADVANCE_STACK_FRAME +# define ADVANCE_STACK_FRAME(next) ((struct layout *) (next)) +#endif + +/* By default, the frame pointer is just what we get from gcc. */ +#ifndef FIRST_FRAME_POINTER +# define FIRST_FRAME_POINTER __builtin_frame_address (0) +#endif + +int +__backtrace (void **array, int size) +{ + struct layout *current; + void *top_frame; + void *top_stack; + int cnt = 0; + + top_frame = FIRST_FRAME_POINTER; + top_stack = CURRENT_STACK_FRAME; + + /* We skip the call to this function, it makes no sense to record it. */ + current = ((struct layout *) top_frame); + while (cnt < size) + { + if ((void *) current INNER_THAN top_stack + || !((void *) current INNER_THAN __libc_stack_end)) + /* This means the address is out of range. Note that for the + toplevel we see a frame pointer with value NULL which clearly is + out of range. */ + break; + + array[cnt++] = current->return_address; + + current = ADVANCE_STACK_FRAME (current->next); + } + + return cnt; +} +weak_alias (__backtrace, backtrace) +libc_hidden_def (__backtrace) diff --git a/REORG.TODO/debug/backtracesyms.c b/REORG.TODO/debug/backtracesyms.c new file mode 100644 index 0000000000..d2d8b26505 --- /dev/null +++ b/REORG.TODO/debug/backtracesyms.c @@ -0,0 +1,120 @@ +/* Return list with names for address in backtrace. + Copyright (C) 1998-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <assert.h> +#include <execinfo.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <ldsodefs.h> + +#if __ELF_NATIVE_CLASS == 32 +# define WORD_WIDTH 8 +#else +/* We assume 64bits. */ +# define WORD_WIDTH 16 +#endif + + +char ** +__backtrace_symbols (void *const *array, int size) +{ + Dl_info info[size]; + int status[size]; + int cnt; + size_t total = 0; + char **result; + + /* Fill in the information we can get from `dladdr'. */ + for (cnt = 0; cnt < size; ++cnt) + { + struct link_map *map; + status[cnt] = _dl_addr (array[cnt], &info[cnt], &map, NULL); + if (status[cnt] && info[cnt].dli_fname && info[cnt].dli_fname[0] != '\0') + { + /* We have some info, compute the length of the string which will be + "<file-name>(<sym-name>+offset) [address]. */ + total += (strlen (info[cnt].dli_fname ?: "") + + strlen (info[cnt].dli_sname ?: "") + + 3 + WORD_WIDTH + 3 + WORD_WIDTH + 5); + + /* The load bias is more useful to the user than the load + address. The use of these addresses is to calculate an + address in the ELF file, so its prelinked bias is not + something we want to subtract out. */ + info[cnt].dli_fbase = (void *) map->l_addr; + } + else + total += 5 + WORD_WIDTH; + } + + /* Allocate memory for the result. */ + result = (char **) malloc (size * sizeof (char *) + total); + if (result != NULL) + { + char *last = (char *) (result + size); + + for (cnt = 0; cnt < size; ++cnt) + { + result[cnt] = last; + + if (status[cnt] + && info[cnt].dli_fname != NULL && info[cnt].dli_fname[0] != '\0') + { + if (info[cnt].dli_sname == NULL) + /* We found no symbol name to use, so describe it as + relative to the file. */ + info[cnt].dli_saddr = info[cnt].dli_fbase; + + if (info[cnt].dli_sname == NULL && info[cnt].dli_saddr == 0) + last += 1 + sprintf (last, "%s(%s) [%p]", + info[cnt].dli_fname ?: "", + info[cnt].dli_sname ?: "", + array[cnt]); + else + { + char sign; + ptrdiff_t offset; + if (array[cnt] >= (void *) info[cnt].dli_saddr) + { + sign = '+'; + offset = array[cnt] - info[cnt].dli_saddr; + } + else + { + sign = '-'; + offset = info[cnt].dli_saddr - array[cnt]; + } + + last += 1 + sprintf (last, "%s(%s%c%#tx) [%p]", + info[cnt].dli_fname ?: "", + info[cnt].dli_sname ?: "", + sign, offset, array[cnt]); + } + } + else + last += 1 + sprintf (last, "[%p]", array[cnt]); + } + assert (last <= (char *) result + size * sizeof (char *) + total); + } + + return result; +} +weak_alias (__backtrace_symbols, backtrace_symbols) diff --git a/REORG.TODO/debug/backtracesymsfd.c b/REORG.TODO/debug/backtracesymsfd.c new file mode 100644 index 0000000000..f34a35d6c3 --- /dev/null +++ b/REORG.TODO/debug/backtracesymsfd.c @@ -0,0 +1,122 @@ +/* Write formatted list with names for addresses in backtrace to a file. + Copyright (C) 1998-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <execinfo.h> +#include <string.h> +#include <sys/uio.h> + +#include <_itoa.h> +#include <ldsodefs.h> + +#if __ELF_NATIVE_CLASS == 32 +# define WORD_WIDTH 8 +#else +/* We assume 64bits. */ +# define WORD_WIDTH 16 +#endif + + +void +__backtrace_symbols_fd (void *const *array, int size, int fd) +{ + struct iovec iov[9]; + int cnt; + + for (cnt = 0; cnt < size; ++cnt) + { + char buf[WORD_WIDTH]; + char buf2[WORD_WIDTH]; + Dl_info info; + struct link_map *map; + size_t last = 0; + + if (_dl_addr (array[cnt], &info, &map, NULL) + && info.dli_fname != NULL && info.dli_fname[0] != '\0') + { + /* Name of the file. */ + iov[0].iov_base = (void *) info.dli_fname; + iov[0].iov_len = strlen (info.dli_fname); + last = 1; + + if (info.dli_sname != NULL || map->l_addr != 0) + { + size_t diff; + + iov[last].iov_base = (void *) "("; + iov[last].iov_len = 1; + ++last; + + if (info.dli_sname != NULL) + { + /* We have a symbol name. */ + iov[last].iov_base = (void *) info.dli_sname; + iov[last].iov_len = strlen (info.dli_sname); + ++last; + } + else + /* We have no symbol, so describe it as relative to the file. + The load bias is more useful to the user than the load + address. The use of these addresses is to calculate an + address in the ELF file, so its prelinked bias is not + something we want to subtract out. */ + info.dli_saddr = (void *) map->l_addr; + + if (array[cnt] >= (void *) info.dli_saddr) + { + iov[last].iov_base = (void *) "+0x"; + diff = array[cnt] - info.dli_saddr; + } + else + { + iov[last].iov_base = (void *) "-0x"; + diff = info.dli_saddr - array[cnt]; + } + iov[last].iov_len = 3; + ++last; + + iov[last].iov_base = _itoa_word ((unsigned long int) diff, + &buf2[WORD_WIDTH], 16, 0); + iov[last].iov_len = (&buf2[WORD_WIDTH] + - (char *) iov[last].iov_base); + ++last; + + iov[last].iov_base = (void *) ")"; + iov[last].iov_len = 1; + ++last; + } + } + + iov[last].iov_base = (void *) "[0x"; + iov[last].iov_len = 3; + ++last; + + iov[last].iov_base = _itoa_word ((unsigned long int) array[cnt], + &buf[WORD_WIDTH], 16, 0); + iov[last].iov_len = &buf[WORD_WIDTH] - (char *) iov[last].iov_base; + ++last; + + iov[last].iov_base = (void *) "]\n"; + iov[last].iov_len = 2; + ++last; + + __writev (fd, iov, last); + } +} +weak_alias (__backtrace_symbols_fd, backtrace_symbols_fd) +libc_hidden_def (__backtrace_symbols_fd) diff --git a/REORG.TODO/debug/catchsegv.sh b/REORG.TODO/debug/catchsegv.sh new file mode 100755 index 0000000000..db4154a362 --- /dev/null +++ b/REORG.TODO/debug/catchsegv.sh @@ -0,0 +1,107 @@ +#!/bin/sh +# Copyright (C) 1998-2017 Free Software Foundation, Inc. +# This file is part of the GNU C Library. +# Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998. + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. + +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. + +# You should have received a copy of the GNU Lesser General Public +# License along with the GNU C Library; if not, see +# <http://www.gnu.org/licenses/>. + +if test $# -eq 0; then + echo "$0: missing program name" >&2 + echo "Try \`$0 --help' for more information." >&2 + exit 1 +fi + +prog="$1" +shift + +if test $# -eq 0; then + case "$prog" in + --h | --he | --hel | --help) + echo 'Usage: catchsegv PROGRAM ARGS...' + echo ' --help print this help, then exit' + echo ' --version print version number, then exit' + echo 'For bug reporting instructions, please see:' + cat <<\EOF +@REPORT_BUGS_TO@. +EOF + exit 0 + ;; + --v | --ve | --ver | --vers | --versi | --versio | --version) + echo 'catchsegv @PKGVERSION@@VERSION@' + echo 'Copyright (C) 2017 Free Software Foundation, Inc. +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +Written by Ulrich Drepper.' + exit 0 + ;; + *) + ;; + esac +fi + +segv_output=`mktemp ${TMPDIR:-/tmp}/segv_output.XXXXXX` || exit + +# Redirect stderr to avoid termination message from shell. +(exec 3>&2 2>/dev/null +LD_PRELOAD=${LD_PRELOAD:+${LD_PRELOAD}:}@SLIB@/libSegFault.so \ +SEGFAULT_USE_ALTSTACK=1 \ +SEGFAULT_OUTPUT_NAME=$segv_output \ +"$prog" ${1+"$@"} 2>&3 3>&-) +exval=$? + +# Check for output. Even if the program terminated correctly it might +# be that a minor process (clone) failed. Therefore we do not check the +# exit code. +if test -s "$segv_output"; then + # The program caught a signal. The output is in the file with the + # name we have in SEGFAULT_OUTPUT_NAME. In the output the names of + # functions in shared objects are available, but names in the static + # part of the program are not. We use addr2line to get this information. + case $prog in + */*) ;; + *) + old_IFS=$IFS + IFS=: + for p in $PATH; do + test -n "$p" || p=. + if test -f "$p/$prog"; then + prog=$p/$prog + break + fi + done + IFS=$old_IFS + ;; + esac + sed '/Backtrace/q' "$segv_output" + sed '1,/Backtrace/d' "$segv_output" | + (while read line; do + line=`echo $line | sed "s@^$prog\\(\\[.*\\)@\1@"` + case "$line" in + \[*) addr=`echo "$line" | sed 's/^\[\(.*\)\]$/\1/'` + complete=`addr2line -f -e "$prog" $addr 2>/dev/null` + if test $? -eq 0; then + echo "`echo "$complete"|sed 'N;s/\(.*\)\n\(.*\)/\2(\1)/;'`$line" + else + echo "$line" + fi + ;; + *) echo "$line" + ;; + esac + done) +fi +rm -f "$segv_output" + +exit $exval diff --git a/REORG.TODO/debug/chk_fail.c b/REORG.TODO/debug/chk_fail.c new file mode 100644 index 0000000000..878c7f0199 --- /dev/null +++ b/REORG.TODO/debug/chk_fail.c @@ -0,0 +1,30 @@ +/* Copyright (C) 2004-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <stdio.h> +#include <stdlib.h> + + +extern char **__libc_argv attribute_hidden; + +void +__attribute__ ((noreturn)) +__chk_fail (void) +{ + __fortify_fail ("buffer overflow detected"); +} +libc_hidden_def (__chk_fail) diff --git a/REORG.TODO/debug/confstr_chk.c b/REORG.TODO/debug/confstr_chk.c new file mode 100644 index 0000000000..73c070f460 --- /dev/null +++ b/REORG.TODO/debug/confstr_chk.c @@ -0,0 +1,29 @@ +/* Copyright (C) 2005-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@readhat.com>, 20055. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <unistd.h> + + +size_t +__confstr_chk (int name, char *buf, size_t len, size_t buflen) +{ + if (__glibc_unlikely (buflen < len)) + __chk_fail (); + + return confstr (name, buf, len); +} diff --git a/REORG.TODO/debug/dprintf_chk.c b/REORG.TODO/debug/dprintf_chk.c new file mode 100644 index 0000000000..79d562a58b --- /dev/null +++ b/REORG.TODO/debug/dprintf_chk.c @@ -0,0 +1,35 @@ +/* Copyright (C) 1991-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <libioP.h> +#include <stdarg.h> +#include <stdio.h> + + +/* Write formatted output to D, according to the format string FORMAT. */ +int +__dprintf_chk (int d, int flags, const char *format, ...) +{ + va_list arg; + int done; + + va_start (arg, format); + done = __vdprintf_chk (d, flags, format, arg); + va_end (arg); + + return done; +} diff --git a/REORG.TODO/debug/execinfo.h b/REORG.TODO/debug/execinfo.h new file mode 100644 index 0000000000..3f31c117bf --- /dev/null +++ b/REORG.TODO/debug/execinfo.h @@ -0,0 +1,43 @@ +/* Copyright (C) 1998-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#ifndef _EXECINFO_H +#define _EXECINFO_H 1 + +#include <features.h> + +__BEGIN_DECLS + +/* Store up to SIZE return address of the current program state in + ARRAY and return the exact number of values stored. */ +extern int backtrace (void **__array, int __size) __nonnull ((1)); + + +/* Return names of functions from the backtrace list in ARRAY in a newly + malloc()ed memory block. */ +extern char **backtrace_symbols (void *const *__array, int __size) + __THROW __nonnull ((1)); + + +/* This function is similar to backtrace_symbols() but it writes the result + immediately to a file. */ +extern void backtrace_symbols_fd (void *const *__array, int __size, int __fd) + __THROW __nonnull ((1)); + +__END_DECLS + +#endif /* execinfo.h */ diff --git a/REORG.TODO/debug/explicit_bzero_chk.c b/REORG.TODO/debug/explicit_bzero_chk.c new file mode 100644 index 0000000000..2680cc344d --- /dev/null +++ b/REORG.TODO/debug/explicit_bzero_chk.c @@ -0,0 +1,44 @@ +/* Generic implementation of __explicit_bzero_chk. + Copyright (C) 1991-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Torbjorn Granlund (tege@sics.se). + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +/* This is the generic definition of __explicit_bzero_chk. The + __explicit_bzero_chk symbol is used as the implementation of + explicit_bzero throughout glibc. If this file is overriden by an + architecture, both __explicit_bzero_chk and + __explicit_bzero_chk_internal have to be defined (the latter not as + an IFUNC). */ + +#include <string.h> + +void +__explicit_bzero_chk (void *dst, size_t len, size_t dstlen) +{ + /* Inline __memset_chk to avoid a PLT reference to __memset_chk. */ + if (__glibc_unlikely (dstlen < len)) + __chk_fail (); + memset (dst, '\0', len); + /* Compiler barrier. */ + asm volatile ("" ::: "memory"); +} + +/* libc-internal references use the hidden + __explicit_bzero_chk_internal symbol. This is necessary if + __explicit_bzero_chk is implemented as an IFUNC because some + targets do not support hidden references to IFUNC symbols. */ +strong_alias (__explicit_bzero_chk, __explicit_bzero_chk_internal) diff --git a/REORG.TODO/debug/fdelt_chk.c b/REORG.TODO/debug/fdelt_chk.c new file mode 100644 index 0000000000..49e0eae97f --- /dev/null +++ b/REORG.TODO/debug/fdelt_chk.c @@ -0,0 +1,29 @@ +/* Copyright (C) 2011-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <sys/select.h> + + +long int +__fdelt_chk (long int d) +{ + if (d < 0 || d >= FD_SETSIZE) + __chk_fail (); + + return d / __NFDBITS; +} +strong_alias (__fdelt_chk, __fdelt_warn) diff --git a/REORG.TODO/debug/fgets_chk.c b/REORG.TODO/debug/fgets_chk.c new file mode 100644 index 0000000000..e4aa983396 --- /dev/null +++ b/REORG.TODO/debug/fgets_chk.c @@ -0,0 +1,61 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + 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 (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 = _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/REORG.TODO/debug/fgets_u_chk.c b/REORG.TODO/debug/fgets_u_chk.c new file mode 100644 index 0000000000..c9ab31fc7e --- /dev/null +++ b/REORG.TODO/debug/fgets_u_chk.c @@ -0,0 +1,59 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + 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 (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 = _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/REORG.TODO/debug/fgetws_chk.c b/REORG.TODO/debug/fgetws_chk.c new file mode 100644 index 0000000000..d77bfb0061 --- /dev/null +++ b/REORG.TODO/debug/fgetws_chk.c @@ -0,0 +1,52 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include "libioP.h" +#include <wchar.h> +#include <sys/param.h> + +wchar_t * +__fgetws_chk (wchar_t *buf, size_t size, int n, _IO_FILE *fp) +{ + _IO_size_t count; + wchar_t *result; + int old_error; + 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. */ + old_error = fp->_IO_file_flags & _IO_ERR_SEEN; + fp->_IO_file_flags &= ~_IO_ERR_SEEN; + count = _IO_getwline (fp, buf, MIN ((size_t) n - 1, size), L'\n', 1); + /* If we read in some bytes and errno is EAGAIN, that error will + be reported for next read. */ + if (count == 0 || (_IO_ferror_unlocked (fp) && 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/REORG.TODO/debug/fgetws_u_chk.c b/REORG.TODO/debug/fgetws_u_chk.c new file mode 100644 index 0000000000..a7e52a8518 --- /dev/null +++ b/REORG.TODO/debug/fgetws_u_chk.c @@ -0,0 +1,60 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + 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 <wchar.h> +#include <sys/param.h> + +wchar_t * +__fgetws_unlocked_chk (wchar_t *buf, size_t size, int n, _IO_FILE *fp) +{ + _IO_size_t count; + wchar_t *result; + int old_error; + 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. */ + old_error = fp->_IO_file_flags & _IO_ERR_SEEN; + fp->_IO_file_flags &= ~_IO_ERR_SEEN; + count = _IO_getwline (fp, buf, MIN ((size_t) n - 1, size), L'\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/REORG.TODO/debug/fortify_fail.c b/REORG.TODO/debug/fortify_fail.c new file mode 100644 index 0000000000..a31977a40f --- /dev/null +++ b/REORG.TODO/debug/fortify_fail.c @@ -0,0 +1,33 @@ +/* Copyright (C) 2007-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <stdio.h> +#include <stdlib.h> + + +extern char **__libc_argv attribute_hidden; + +void +__attribute__ ((noreturn)) internal_function +__fortify_fail (const char *msg) +{ + /* The loop is added only to keep gcc happy. */ + while (1) + __libc_message (2, "*** %s ***: %s terminated\n", + msg, __libc_argv[0] ?: "<unknown>"); +} +libc_hidden_def (__fortify_fail) diff --git a/REORG.TODO/debug/fprintf_chk.c b/REORG.TODO/debug/fprintf_chk.c new file mode 100644 index 0000000000..bf7a28c589 --- /dev/null +++ b/REORG.TODO/debug/fprintf_chk.c @@ -0,0 +1,44 @@ +/* Copyright (C) 1991-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <stdarg.h> +#include <stdio.h> +#include "../libio/libioP.h" + + +/* Write formatted output to FP from the format string FORMAT. */ +int +___fprintf_chk (FILE *fp, int flag, const char *format, ...) +{ + va_list ap; + int done; + + _IO_acquire_lock_clear_flags2 (fp); + if (flag > 0) + fp->_flags2 |= _IO_FLAGS2_FORTIFY; + + va_start (ap, format); + done = vfprintf (fp, format, ap); + va_end (ap); + + if (flag > 0) + fp->_flags2 &= ~_IO_FLAGS2_FORTIFY; + _IO_release_lock (fp); + + return done; +} +ldbl_strong_alias (___fprintf_chk, __fprintf_chk) diff --git a/REORG.TODO/debug/fread_chk.c b/REORG.TODO/debug/fread_chk.c new file mode 100644 index 0000000000..b99a4e477f --- /dev/null +++ b/REORG.TODO/debug/fread_chk.c @@ -0,0 +1,54 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + 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> + +size_t +__fread_chk (void *__restrict ptr, size_t ptrlen, + size_t size, size_t n, FILE *__restrict stream) +{ + size_t bytes_requested = size * n; + if (__builtin_expect ((n | size) + >= (((size_t) 1) << (8 * sizeof (size_t) / 2)), 0)) + { + if (size != 0 && bytes_requested / size != n) + __chk_fail (); + } + + if (__glibc_unlikely (bytes_requested > ptrlen)) + __chk_fail (); + + CHECK_FILE (stream, 0); + if (bytes_requested == 0) + return 0; + + size_t bytes_read; + _IO_acquire_lock (stream); + bytes_read = _IO_sgetn (stream, (char *) ptr, bytes_requested); + _IO_release_lock (stream); + return bytes_requested == bytes_read ? n : bytes_read / size; +} diff --git a/REORG.TODO/debug/fread_u_chk.c b/REORG.TODO/debug/fread_u_chk.c new file mode 100644 index 0000000000..f546a53561 --- /dev/null +++ b/REORG.TODO/debug/fread_u_chk.c @@ -0,0 +1,51 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + 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> + +size_t +__fread_unlocked_chk (void *__restrict ptr, size_t ptrlen, + size_t size, size_t n, FILE *__restrict stream) +{ + size_t bytes_requested = size * n; + if (__builtin_expect ((n | size) + >= (((size_t) 1) << (8 * sizeof (size_t) / 2)), 0)) + { + if (size != 0 && bytes_requested / size != n) + __chk_fail (); + } + + if (__glibc_unlikely (bytes_requested > ptrlen)) + __chk_fail (); + + CHECK_FILE (stream, 0); + if (bytes_requested == 0) + return 0; + + size_t bytes_read = _IO_sgetn (stream, (char *) ptr, bytes_requested); + return bytes_requested == bytes_read ? n : bytes_read / size; +} diff --git a/REORG.TODO/debug/fwprintf_chk.c b/REORG.TODO/debug/fwprintf_chk.c new file mode 100644 index 0000000000..0926924646 --- /dev/null +++ b/REORG.TODO/debug/fwprintf_chk.c @@ -0,0 +1,43 @@ +/* Copyright (C) 1991-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <stdarg.h> +#include <wchar.h> +#include "../libio/libioP.h" + + +/* Write formatted output to FP from the format string FORMAT. */ +int +__fwprintf_chk (FILE *fp, int flag, const wchar_t *format, ...) +{ + va_list ap; + int done; + + _IO_acquire_lock_clear_flags2 (fp); + if (flag > 0) + fp->_flags2 |= _IO_FLAGS2_FORTIFY; + + va_start (ap, format); + done = _IO_vfwprintf (fp, format, ap); + va_end (ap); + + if (flag > 0) + fp->_flags2 &= ~_IO_FLAGS2_FORTIFY; + _IO_release_lock (fp); + + return done; +} diff --git a/REORG.TODO/debug/getcwd_chk.c b/REORG.TODO/debug/getcwd_chk.c new file mode 100644 index 0000000000..e3372a9e3c --- /dev/null +++ b/REORG.TODO/debug/getcwd_chk.c @@ -0,0 +1,30 @@ +/* Copyright (C) 2005-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <errno.h> +#include <unistd.h> +#include <sys/param.h> + + +char * +__getcwd_chk (char *buf, size_t size, size_t buflen) +{ + if (size > buflen) + __chk_fail (); + + return __getcwd (buf, size); +} diff --git a/REORG.TODO/debug/getdomainname_chk.c b/REORG.TODO/debug/getdomainname_chk.c new file mode 100644 index 0000000000..6a62a1180c --- /dev/null +++ b/REORG.TODO/debug/getdomainname_chk.c @@ -0,0 +1,28 @@ +/* Copyright (C) 2005-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <unistd.h> + + +int +__getdomainname_chk (char *buf, size_t buflen, size_t nreal) +{ + if (buflen > nreal) + __chk_fail (); + + return getdomainname (buf, buflen); +} diff --git a/REORG.TODO/debug/getgroups_chk.c b/REORG.TODO/debug/getgroups_chk.c new file mode 100644 index 0000000000..0cbfa80ae5 --- /dev/null +++ b/REORG.TODO/debug/getgroups_chk.c @@ -0,0 +1,35 @@ +/* Copyright (C) 2005-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <errno.h> +#include <unistd.h> + + +int +__getgroups_chk (int size, __gid_t list[], size_t listlen) +{ + if (__glibc_unlikely (size < 0)) + { + __set_errno (EINVAL); + return -1; + } + + if (__glibc_unlikely (size * sizeof (__gid_t) > listlen)) + __chk_fail (); + + return __getgroups (size, list); +} diff --git a/REORG.TODO/debug/gethostname_chk.c b/REORG.TODO/debug/gethostname_chk.c new file mode 100644 index 0000000000..1710381039 --- /dev/null +++ b/REORG.TODO/debug/gethostname_chk.c @@ -0,0 +1,28 @@ +/* Copyright (C) 2005-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <unistd.h> + + +int +__gethostname_chk (char *buf, size_t buflen, size_t nreal) +{ + if (buflen > nreal) + __chk_fail (); + + return __gethostname (buf, buflen); +} diff --git a/REORG.TODO/debug/gets_chk.c b/REORG.TODO/debug/gets_chk.c new file mode 100644 index 0000000000..2118ca2af0 --- /dev/null +++ b/REORG.TODO/debug/gets_chk.c @@ -0,0 +1,75 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + 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 "../libio/libioP.h" +#include <limits.h> + +char * +__gets_chk (char *buf, size_t size) +{ + _IO_size_t count; + int ch; + char *retval; + + if (size == 0) + __chk_fail (); + + _IO_acquire_lock (_IO_stdin); + ch = _IO_getc_unlocked (_IO_stdin); + if (ch == EOF) + { + retval = NULL; + goto unlock_return; + } + if (ch == '\n') + count = 0; + else + { + /* 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 = _IO_stdin->_IO_file_flags & _IO_ERR_SEEN; + _IO_stdin->_IO_file_flags &= ~_IO_ERR_SEEN; + buf[0] = (char) ch; + count = _IO_getline (_IO_stdin, buf + 1, size - 1, '\n', 0) + 1; + if (_IO_stdin->_IO_file_flags & _IO_ERR_SEEN) + { + retval = NULL; + goto unlock_return; + } + else + _IO_stdin->_IO_file_flags |= old_error; + } + if (count >= size) + __chk_fail (); + buf[count] = 0; + retval = buf; +unlock_return: + _IO_release_lock (_IO_stdin); + return retval; +} + +link_warning (__gets_chk, "the `gets' function is dangerous and should not be used.") diff --git a/REORG.TODO/debug/getwd_chk.c b/REORG.TODO/debug/getwd_chk.c new file mode 100644 index 0000000000..0c6289cc00 --- /dev/null +++ b/REORG.TODO/debug/getwd_chk.c @@ -0,0 +1,33 @@ +/* Copyright (C) 2005-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#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/REORG.TODO/debug/longjmp_chk.c b/REORG.TODO/debug/longjmp_chk.c new file mode 100644 index 0000000000..1a927f5ac1 --- /dev/null +++ b/REORG.TODO/debug/longjmp_chk.c @@ -0,0 +1,27 @@ +/* Copyright (C) 2009-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <setjmp.h> + +// XXX Should move to include/setjmp.h +extern void ____longjmp_chk (__jmp_buf __env, int __val) + __attribute__ ((__noreturn__)); + +#define __longjmp ____longjmp_chk +#define __libc_siglongjmp __longjmp_chk + +#include <setjmp/longjmp.c> diff --git a/REORG.TODO/debug/mbsnrtowcs_chk.c b/REORG.TODO/debug/mbsnrtowcs_chk.c new file mode 100644 index 0000000000..ee8fe18018 --- /dev/null +++ b/REORG.TODO/debug/mbsnrtowcs_chk.c @@ -0,0 +1,30 @@ +/* Copyright (C) 2005-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <locale.h> +#include <wchar.h> + + +size_t +__mbsnrtowcs_chk (wchar_t *dst, const char **src, size_t nmc, size_t len, + mbstate_t *ps, size_t dstlen) +{ + if (__glibc_unlikely (dstlen < len)) + __chk_fail (); + + return __mbsnrtowcs (dst, src, nmc, len, ps); +} diff --git a/REORG.TODO/debug/mbsrtowcs_chk.c b/REORG.TODO/debug/mbsrtowcs_chk.c new file mode 100644 index 0000000000..7602e0fffc --- /dev/null +++ b/REORG.TODO/debug/mbsrtowcs_chk.c @@ -0,0 +1,30 @@ +/* Copyright (C) 2005-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <locale.h> +#include <wchar.h> + + +size_t +__mbsrtowcs_chk (wchar_t *dst, const char **src, size_t len, + mbstate_t *ps, size_t dstlen) +{ + if (__glibc_unlikely (dstlen < len)) + __chk_fail (); + + return __mbsrtowcs (dst, src, len, ps); +} diff --git a/REORG.TODO/debug/mbstowcs_chk.c b/REORG.TODO/debug/mbstowcs_chk.c new file mode 100644 index 0000000000..8b1cf94f76 --- /dev/null +++ b/REORG.TODO/debug/mbstowcs_chk.c @@ -0,0 +1,34 @@ +/* Copyright (C) 2005-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <locale.h> +#include <string.h> +#include <wchar.h> + + +size_t +__mbstowcs_chk (wchar_t *dst, const char *src, size_t len, size_t dstlen) +{ + if (__glibc_unlikely (dstlen < len)) + __chk_fail (); + + mbstate_t state; + + memset (&state, '\0', sizeof state); + /* Return how many we wrote (or maybe an error). */ + return __mbsrtowcs (dst, &src, len, &state); +} diff --git a/REORG.TODO/debug/memcpy_chk.c b/REORG.TODO/debug/memcpy_chk.c new file mode 100644 index 0000000000..1ee8ea6cb4 --- /dev/null +++ b/REORG.TODO/debug/memcpy_chk.c @@ -0,0 +1,31 @@ +/* Copy memory to memory until the specified number of bytes + has been copied with error checking. Overlap is NOT handled correctly. + Copyright (C) 1991-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Torbjorn Granlund (tege@sics.se). + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <string.h> +#include <memcopy.h> + +void * +__memcpy_chk (void *dstpp, const void *srcpp, size_t len, size_t dstlen) +{ + if (__glibc_unlikely (dstlen < len)) + __chk_fail (); + + return memcpy (dstpp, srcpp, len); +} diff --git a/REORG.TODO/debug/memmove_chk.c b/REORG.TODO/debug/memmove_chk.c new file mode 100644 index 0000000000..abd21306e2 --- /dev/null +++ b/REORG.TODO/debug/memmove_chk.c @@ -0,0 +1,35 @@ +/* Copy memory to memory until the specified number of bytes + has been copied with error checking. Overlap is handled correctly. + Copyright (C) 1991-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Torbjorn Granlund (tege@sics.se). + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <string.h> +#include <memcopy.h> + +#ifndef MEMMOVE_CHK +# define MEMMOVE_CHK __memmove_chk +#endif + +void * +MEMMOVE_CHK (void *dest, const void *src, size_t len, size_t destlen) +{ + if (__glibc_unlikely (destlen < len)) + __chk_fail (); + + return memmove (dest, src, len); +} diff --git a/REORG.TODO/debug/mempcpy_chk.c b/REORG.TODO/debug/mempcpy_chk.c new file mode 100644 index 0000000000..1ec3233def --- /dev/null +++ b/REORG.TODO/debug/mempcpy_chk.c @@ -0,0 +1,32 @@ +/* Copy memory to memory until the specified number of bytes + has been copied, return pointer to following byte, with error checking. + Overlap is NOT handled correctly. + Copyright (C) 1991-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Torbjorn Granlund (tege@sics.se). + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <string.h> +#include <memcopy.h> + +void * +__mempcpy_chk (void *dstpp, const void *srcpp, size_t len, size_t dstlen) +{ + if (__glibc_unlikely (dstlen < len)) + __chk_fail (); + + return __mempcpy (dstpp, srcpp, len); +} diff --git a/REORG.TODO/debug/memset_chk.c b/REORG.TODO/debug/memset_chk.c new file mode 100644 index 0000000000..ff15c3b4ba --- /dev/null +++ b/REORG.TODO/debug/memset_chk.c @@ -0,0 +1,28 @@ +/* Copyright (C) 1991-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <string.h> +#include <memcopy.h> + +void * +__memset_chk (void *dstpp, int c, size_t len, size_t dstlen) +{ + if (__glibc_unlikely (dstlen < len)) + __chk_fail (); + + return memset (dstpp, c, len); +} diff --git a/REORG.TODO/debug/noophooks.c b/REORG.TODO/debug/noophooks.c new file mode 100644 index 0000000000..d98f3725d1 --- /dev/null +++ b/REORG.TODO/debug/noophooks.c @@ -0,0 +1,26 @@ +/* Noop hooks for the instrumenting functions. + Copyright (C) 1999-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <libc-internal.h> + +void +__cyg_profile_func_enter (void *this_fn, void *call_site) +{ +} +strong_alias (__cyg_profile_func_enter, __cyg_profile_func_exit) diff --git a/REORG.TODO/debug/obprintf_chk.c b/REORG.TODO/debug/obprintf_chk.c new file mode 100644 index 0000000000..12f021cb9d --- /dev/null +++ b/REORG.TODO/debug/obprintf_chk.c @@ -0,0 +1,115 @@ +/* Print output of stream to given obstack. + Copyright (C) 1996-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + + +#include <stdlib.h> +#include <libioP.h> +#include "../libio/strfile.h" +#include <assert.h> +#include <string.h> +#include <errno.h> +#include <obstack.h> +#include <stdarg.h> +#include <stdio_ext.h> + + +struct _IO_obstack_file +{ + struct _IO_FILE_plus file; + struct obstack *obstack; +}; + +extern const struct _IO_jump_t _IO_obstack_jumps libio_vtable attribute_hidden; + +int +__obstack_vprintf_chk (struct obstack *obstack, int flags, const char *format, + va_list args) +{ + struct obstack_FILE + { + struct _IO_obstack_file ofile; + } new_f; + int result; + int size; + int room; + +#ifdef _IO_MTSAFE_IO + new_f.ofile.file.file._lock = NULL; +#endif + + _IO_no_init (&new_f.ofile.file.file, _IO_USER_LOCK, -1, NULL, NULL); + _IO_JUMPS (&new_f.ofile.file) = &_IO_obstack_jumps; + room = obstack_room (obstack); + size = obstack_object_size (obstack) + room; + if (size == 0) + { + /* We have to handle the allocation a bit different since the + `_IO_str_init_static' function would handle a size of zero + different from what we expect. */ + + /* Get more memory. */ + obstack_make_room (obstack, 64); + + /* Recompute how much room we have. */ + room = obstack_room (obstack); + size = room; + + assert (size != 0); + } + + _IO_str_init_static_internal ((struct _IO_strfile_ *) &new_f.ofile, + obstack_base (obstack), + size, obstack_next_free (obstack)); + /* Now allocate the rest of the current chunk. */ + assert (size == (new_f.ofile.file.file._IO_write_end + - new_f.ofile.file.file._IO_write_base)); + assert (new_f.ofile.file.file._IO_write_ptr + == (new_f.ofile.file.file._IO_write_base + + obstack_object_size (obstack))); + obstack_blank_fast (obstack, room); + + new_f.ofile.obstack = obstack; + + /* For flags > 0 (i.e. __USE_FORTIFY_LEVEL > 1) request that %n + can only come from read-only format strings. */ + if (flags > 0) + new_f.ofile.file.file._flags2 |= _IO_FLAGS2_FORTIFY; + + result = _IO_vfprintf (&new_f.ofile.file.file, format, args); + + /* Shrink the buffer to the space we really currently need. */ + obstack_blank_fast (obstack, (new_f.ofile.file.file._IO_write_ptr + - new_f.ofile.file.file._IO_write_end)); + + return result; +} +libc_hidden_def (__obstack_vprintf_chk) + + +int +__obstack_printf_chk (struct obstack *obstack, int flags, const char *format, + ...) +{ + int result; + va_list ap; + va_start (ap, format); + result = __obstack_vprintf_chk (obstack, flags, format, ap); + va_end (ap); + return result; +} diff --git a/REORG.TODO/debug/pcprofile.c b/REORG.TODO/debug/pcprofile.c new file mode 100644 index 0000000000..b6402ef63b --- /dev/null +++ b/REORG.TODO/debug/pcprofile.c @@ -0,0 +1,91 @@ +/* Profile PC and write result to FIFO. + Copyright (C) 1999-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <errno.h> +#include <fcntl.h> +#include <stdint.h> +#include <stdlib.h> +#include <unistd.h> + +/* Nonzero if we are actually doing something. */ +static int active; + +/* The file descriptor of the FIFO. */ +static int fd; + + +static void +__attribute__ ((constructor)) +install (void) +{ + /* See whether the environment variable `PCPROFILE_OUTPUT' is defined. + If yes, it should name a FIFO. We open it and mark ourself as active. */ + const char *outfile = getenv ("PCPROFILE_OUTPUT"); + + if (outfile != NULL && *outfile != '\0') + { + fd = open (outfile, O_RDWR | O_CREAT, 0666); + + if (fd != -1) + { + uint32_t word; + + active = 1; + + /* Write a magic word which tells the reader about the byte + order and the size of the following entries. */ + word = 0xdeb00000 | sizeof (void *); + if (TEMP_FAILURE_RETRY (write (fd, &word, 4)) != 4) + { + /* If even this fails we shouldn't try further. */ + close (fd); + fd = -1; + active = 0; + } + } + } +} + + +static void +__attribute__ ((destructor)) +uninstall (void) +{ + if (active) + close (fd); +} + + +void +__cyg_profile_func_enter (void *this_fn, void *call_site) +{ + void *buf[2]; + + if (! active) + return; + + /* Now write out the current position and that of the caller. We do + this now, and don't cache the because we want real-time output. */ + buf[0] = this_fn; + buf[1] = call_site; + + write (fd, buf, sizeof buf); +} +/* We don't handle entry and exit differently here. */ +strong_alias (__cyg_profile_func_enter, __cyg_profile_func_exit) diff --git a/REORG.TODO/debug/pcprofiledump.c b/REORG.TODO/debug/pcprofiledump.c new file mode 100644 index 0000000000..a32cdefcf9 --- /dev/null +++ b/REORG.TODO/debug/pcprofiledump.c @@ -0,0 +1,231 @@ +/* Dump information generated by PC profiling. + Copyright (C) 1999-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +/* This is mainly an example. It shows how programs which want to use + the information should read the file. */ +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <argp.h> +#include <byteswap.h> +#include <errno.h> +#include <error.h> +#include <fcntl.h> +#include <inttypes.h> +#include <libintl.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <stdint.h> + +#include "../version.h" + +#define PACKAGE _libc_intl_domainname + +#ifndef _ +# define _(Str) gettext (Str) +#endif + +#ifndef N_ +# define N_(Str) Str +#endif + +/* Definitions of arguments for argp functions. */ +static const struct argp_option options[] = +{ + { "unbuffered", 'u', NULL, 0, N_("Don't buffer output") }, + { NULL, 0, NULL, 0, NULL } +}; + +/* Short description of program. */ +static const char doc[] = N_("Dump information generated by PC profiling."); + +/* Strings for arguments in help texts. */ +static const char args_doc[] = N_("[FILE]"); + +/* Function to print some extra text in the help message. */ +static char *more_help (int key, const char *text, void *input); + +/* Prototype for option handler. */ +static error_t parse_opt (int key, char *arg, struct argp_state *state); + +/* Name and version of program. */ +static void print_version (FILE *stream, struct argp_state *state); +void (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version; + +/* Data structure to communicate with argp functions. */ +static struct argp argp = +{ + options, parse_opt, args_doc, doc, NULL, more_help +}; + + +int +main (int argc, char *argv[]) +{ + /* Set locale via LC_ALL. */ + setlocale (LC_ALL, ""); + + /* Set the text message domain. */ + textdomain (PACKAGE); + + /* Parse and process arguments. */ + int remaining; + argp_parse (&argp, argc, argv, 0, &remaining, NULL); + + int fd; + if (remaining == argc) + fd = STDIN_FILENO; + else if (remaining + 1 != argc) + { + argp_help (&argp, stdout, ARGP_HELP_SEE | ARGP_HELP_EXIT_ERR, + program_invocation_short_name); + exit (1); + } + else + { + /* Open the given file. */ + fd = open (argv[remaining], O_RDONLY); + + if (fd == -1) + error (EXIT_FAILURE, errno, _("cannot open input file")); + } + + /* Read the first 4-byte word. It contains the information about + the word size and the endianess. */ + uint32_t word; + if (TEMP_FAILURE_RETRY (read (fd, &word, 4)) != 4) + error (EXIT_FAILURE, errno, _("cannot read header")); + + /* Check whether we have to swap the byte order. */ + int must_swap = (word & 0xfffffff0) == bswap_32 (0xdeb00000); + if (must_swap) + word = bswap_32 (word); + + /* We have two loops, one for 32 bit pointers, one for 64 bit pointers. */ + if (word == 0xdeb00004) + { + union + { + uint32_t ptrs[2]; + char bytes[8]; + } pair; + + while (1) + { + size_t len = sizeof (pair); + size_t n; + + while (len > 0 + && (n = TEMP_FAILURE_RETRY (read (fd, &pair.bytes[8 - len], + len))) != 0) + len -= n; + + if (len != 0) + /* Nothing to read. */ + break; + + printf ("this = %#010" PRIx32 ", caller = %#010" PRIx32 "\n", + must_swap ? bswap_32 (pair.ptrs[0]) : pair.ptrs[0], + must_swap ? bswap_32 (pair.ptrs[1]) : pair.ptrs[1]); + } + } + else if (word == 0xdeb00008) + { + union + { + uint64_t ptrs[2]; + char bytes[16]; + } pair; + + while (1) + { + size_t len = sizeof (pair); + size_t n; + + while (len > 0 + && (n = TEMP_FAILURE_RETRY (read (fd, &pair.bytes[8 - len], + len))) != 0) + len -= n; + + if (len != 0) + /* Nothing to read. */ + break; + + printf ("this = %#018" PRIx64 ", caller = %#018" PRIx64 "\n", + must_swap ? bswap_64 (pair.ptrs[0]) : pair.ptrs[0], + must_swap ? bswap_64 (pair.ptrs[1]) : pair.ptrs[1]); + } + } + else + /* This should not happen. */ + error (EXIT_FAILURE, 0, _("invalid pointer size")); + + /* Clean up. */ + close (fd); + + return 0; +} + +static error_t +parse_opt (int key, char *arg, struct argp_state *state) +{ + switch (key) + { + case 'u': + setbuf (stdout, NULL); + break; + default: + return ARGP_ERR_UNKNOWN; + } + return 0; +} + +static char * +more_help (int key, const char *text, void *input) +{ + char *tp = NULL; + switch (key) + { + case ARGP_KEY_HELP_EXTRA: + /* We print some extra information. */ + if (asprintf (&tp, gettext ("\ +For bug reporting instructions, please see:\n\ +%s.\n"), REPORT_BUGS_TO) < 0) + return NULL; + return tp; + default: + break; + } + return (char *) text; +} + +/* Print the version information. */ +static void +print_version (FILE *stream, struct argp_state *state) +{ + fprintf (stream, "pcprofiledump %s%s\n", PKGVERSION, VERSION); + fprintf (stream, gettext ("\ +Copyright (C) %s Free Software Foundation, Inc.\n\ +This is free software; see the source for copying conditions. There is NO\n\ +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\ +"), "2017"); + fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper"); +} diff --git a/REORG.TODO/debug/poll_chk.c b/REORG.TODO/debug/poll_chk.c new file mode 100644 index 0000000000..5f6a707b9a --- /dev/null +++ b/REORG.TODO/debug/poll_chk.c @@ -0,0 +1,28 @@ +/* Copyright (C) 2012-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <sys/poll.h> + + +int +__poll_chk (struct pollfd *fds, nfds_t nfds, int timeout, __SIZE_TYPE__ fdslen) +{ + if (fdslen / sizeof (*fds) < nfds) + __chk_fail (); + + return __poll (fds, nfds, timeout); +} diff --git a/REORG.TODO/debug/ppoll_chk.c b/REORG.TODO/debug/ppoll_chk.c new file mode 100644 index 0000000000..1b80de8eb8 --- /dev/null +++ b/REORG.TODO/debug/ppoll_chk.c @@ -0,0 +1,29 @@ +/* Copyright (C) 2012-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <sys/poll.h> + + +int +__ppoll_chk (struct pollfd *fds, nfds_t nfds, const struct timespec *timeout, + const __sigset_t *ss, __SIZE_TYPE__ fdslen) +{ + if (fdslen / sizeof (*fds) < nfds) + __chk_fail (); + + return ppoll (fds, nfds, timeout, ss); +} diff --git a/REORG.TODO/debug/pread64_chk.c b/REORG.TODO/debug/pread64_chk.c new file mode 100644 index 0000000000..b9cae453a6 --- /dev/null +++ b/REORG.TODO/debug/pread64_chk.c @@ -0,0 +1,29 @@ +/* Copyright (C) 2005-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <unistd.h> +#include <sys/param.h> + + +ssize_t +__pread64_chk (int fd, void *buf, size_t nbytes, off64_t offset, size_t buflen) +{ + if (nbytes > buflen) + __chk_fail (); + + return __libc_pread64 (fd, buf, nbytes, offset); +} diff --git a/REORG.TODO/debug/pread_chk.c b/REORG.TODO/debug/pread_chk.c new file mode 100644 index 0000000000..408fbf35ef --- /dev/null +++ b/REORG.TODO/debug/pread_chk.c @@ -0,0 +1,29 @@ +/* Copyright (C) 2005-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <unistd.h> +#include <sys/param.h> + + +ssize_t +__pread_chk (int fd, void *buf, size_t nbytes, off_t offset, size_t buflen) +{ + if (nbytes > buflen) + __chk_fail (); + + return __pread (fd, buf, nbytes, offset); +} diff --git a/REORG.TODO/debug/printf_chk.c b/REORG.TODO/debug/printf_chk.c new file mode 100644 index 0000000000..a481ed6795 --- /dev/null +++ b/REORG.TODO/debug/printf_chk.c @@ -0,0 +1,44 @@ +/* Copyright (C) 1991-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <stdarg.h> +#include <stdio.h> +#include "../libio/libioP.h" + + +/* Write formatted output to stdout from the format string FORMAT. */ +int +___printf_chk (int flag, const char *format, ...) +{ + va_list ap; + int done; + + _IO_acquire_lock_clear_flags2 (stdout); + if (flag > 0) + stdout->_flags2 |= _IO_FLAGS2_FORTIFY; + + va_start (ap, format); + done = vfprintf (stdout, format, ap); + va_end (ap); + + if (flag > 0) + stdout->_flags2 &= ~_IO_FLAGS2_FORTIFY; + _IO_release_lock (stdout); + + return done; +} +ldbl_strong_alias (___printf_chk, __printf_chk) diff --git a/REORG.TODO/debug/read_chk.c b/REORG.TODO/debug/read_chk.c new file mode 100644 index 0000000000..e72b64dfca --- /dev/null +++ b/REORG.TODO/debug/read_chk.c @@ -0,0 +1,37 @@ +/* Copyright (C) 2005-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#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) +{ + if (nbytes > buflen) + __chk_fail (); + +#ifdef HAVE_INLINED_SYSCALLS + return INLINE_SYSCALL (read, 3, fd, buf, nbytes); +#else + return __read (fd, buf, nbytes); +#endif +} diff --git a/REORG.TODO/debug/readlink_chk.c b/REORG.TODO/debug/readlink_chk.c new file mode 100644 index 0000000000..03273b4c49 --- /dev/null +++ b/REORG.TODO/debug/readlink_chk.c @@ -0,0 +1,37 @@ +/* Copyright (C) 2005-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#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) +{ + if (len > buflen) + __chk_fail (); + +#ifdef HAVE_INLINED_SYSCALLS + return INLINE_SYSCALL (readlink, 3, path, buf, len); +#else + return __readlink (path, buf, len); +#endif +} diff --git a/REORG.TODO/debug/readlinkat_chk.c b/REORG.TODO/debug/readlinkat_chk.c new file mode 100644 index 0000000000..e51e792aa6 --- /dev/null +++ b/REORG.TODO/debug/readlinkat_chk.c @@ -0,0 +1,30 @@ +/* Copyright (C) 2006-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <unistd.h> +#include <sys/param.h> + + +ssize_t +__readlinkat_chk (int fd, const char *path, void *buf, size_t len, + size_t buflen) +{ + if (len > buflen) + __chk_fail (); + + return readlinkat (fd, path, buf, len); +} diff --git a/REORG.TODO/debug/readonly-area.c b/REORG.TODO/debug/readonly-area.c new file mode 100644 index 0000000000..922e87fe63 --- /dev/null +++ b/REORG.TODO/debug/readonly-area.c @@ -0,0 +1,33 @@ +/* Copyright (C) 2004-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <stdlib.h> + +/* Return 1 if the whole area PTR .. PTR+SIZE is not writable. + Return -1 if it is writable. */ + +int +__readonly_area (const void *ptr, size_t size) +{ + /* We cannot determine in general whether memory is writable or not. + This must be handled in a system-dependent manner. to not + unconditionally break code we need to return here a positive + answer. This disables this security measure but that is the + price people have to pay for using systems without a real + implementation of this interface. */ + return 1; +} diff --git a/REORG.TODO/debug/realpath_chk.c b/REORG.TODO/debug/realpath_chk.c new file mode 100644 index 0000000000..5029fa6f25 --- /dev/null +++ b/REORG.TODO/debug/realpath_chk.c @@ -0,0 +1,59 @@ +/* Copyright (C) 2005-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <limits.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + + +char * +__realpath_chk (const char *buf, char *resolved, size_t resolvedlen) +{ +#ifdef PATH_MAX + if (resolvedlen < PATH_MAX) + __chk_fail (); + + return __realpath (buf, resolved); +#else + long int pathmax =__pathconf (buf, _PC_PATH_MAX); + if (pathmax != -1) + { + /* We do have a fixed limit. */ + if (resolvedlen < pathmax) + __chk_fail (); + + return __realpath (buf, resolved); + } + + /* Since there is no fixed limit we check whether the size is large + enough. */ + char *res = __realpath (buf, NULL); + if (res != NULL) + { + size_t actlen = strlen (res) + 1; + if (actlen > resolvedlen) + __chk_fail (); + + memcpy (resolved, res, actlen); + free (res); + res = resolved; + } + + return res; +#endif +} diff --git a/REORG.TODO/debug/recv_chk.c b/REORG.TODO/debug/recv_chk.c new file mode 100644 index 0000000000..bfd95f4095 --- /dev/null +++ b/REORG.TODO/debug/recv_chk.c @@ -0,0 +1,29 @@ +/* Copyright (C) 2005-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <sys/param.h> +#include <sys/socket.h> + + +ssize_t +__recv_chk (int fd, void *buf, size_t n, size_t buflen, int flags) +{ + if (n > buflen) + __chk_fail (); + + return __recv (fd, buf, n, flags); +} diff --git a/REORG.TODO/debug/recvfrom_chk.c b/REORG.TODO/debug/recvfrom_chk.c new file mode 100644 index 0000000000..7b9a08b00a --- /dev/null +++ b/REORG.TODO/debug/recvfrom_chk.c @@ -0,0 +1,30 @@ +/* Copyright (C) 2005-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#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) +{ + if (n > buflen) + __chk_fail (); + + return __recvfrom (fd, buf, n, flags, addr, addr_len); +} diff --git a/REORG.TODO/debug/segfault.c b/REORG.TODO/debug/segfault.c new file mode 100644 index 0000000000..78c1cf5d1d --- /dev/null +++ b/REORG.TODO/debug/segfault.c @@ -0,0 +1,210 @@ +/* Catch segmentation faults and print backtrace. + Copyright (C) 1998-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <alloca.h> +#include <ctype.h> +#include <errno.h> +#include <execinfo.h> +#include <fcntl.h> +#include <signal.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <_itoa.h> +#include <ldsodefs.h> + +/* This file defines macros to access the content of the sigcontext element + passed up by the signal handler. */ +#include <sigcontextinfo.h> + +/* Get code to possibly dump the content of all registers. */ +#include <register-dump.h> + +/* We'll use this a lot. */ +#define WRITE_STRING(s) write (fd, s, strlen (s)) + +/* Name of the output file. */ +static const char *fname; + + +/* We better should not use `strerror' since it can call far too many + other functions which might fail. Do it here ourselves. */ +static void +write_strsignal (int fd, int signal) +{ + if (signal < 0 || signal >= _NSIG || _sys_siglist[signal] == NULL) + { + char buf[30]; + char *ptr = _itoa_word (signal, &buf[sizeof (buf)], 10, 0); + WRITE_STRING ("signal "); + write (fd, buf, &buf[sizeof (buf)] - ptr); + } + else + WRITE_STRING (_sys_siglist[signal]); +} + + +/* This function is called when a segmentation fault is caught. The system + is in an unstable state now. This means especially that malloc() might + not work anymore. */ +static void +catch_segfault (int signal, SIGCONTEXT ctx) +{ + int fd, cnt, i; + void **arr; + struct sigaction sa; + uintptr_t pc; + + /* This is the name of the file we are writing to. If none is given + or we cannot write to this file write to stderr. */ + fd = 2; + if (fname != NULL) + { + fd = open (fname, O_TRUNC | O_WRONLY | O_CREAT, 0666); + if (fd == -1) + fd = 2; + } + + WRITE_STRING ("*** "); + write_strsignal (fd, signal); + WRITE_STRING ("\n"); + +#ifdef REGISTER_DUMP + REGISTER_DUMP; +#endif + + WRITE_STRING ("\nBacktrace:\n"); + + /* Get the backtrace. */ + arr = alloca (256 * sizeof (void *)); + cnt = backtrace (arr, 256); + + /* Now try to locate the PC from signal context in the backtrace. + Normally it will be found at arr[2], but it might appear later + if there were some signal handler wrappers. Allow a few bytes + difference to cope with as many arches as possible. */ + pc = (uintptr_t) GET_PC (ctx); + for (i = 0; i < cnt; ++i) + if ((uintptr_t) arr[i] >= pc - 16 && (uintptr_t) arr[i] <= pc + 16) + break; + + /* If we haven't found it, better dump full backtrace even including + the signal handler frames instead of not dumping anything. */ + if (i == cnt) + i = 0; + + /* Now generate nicely formatted output. */ + __backtrace_symbols_fd (arr + i, cnt - i, fd); + +#ifdef HAVE_PROC_SELF + /* Now the link map. */ + int mapfd = open ("/proc/self/maps", O_RDONLY); + if (mapfd != -1) + { + write (fd, "\nMemory map:\n\n", 14); + + char buf[256]; + ssize_t n; + + while ((n = TEMP_FAILURE_RETRY (read (mapfd, buf, sizeof (buf)))) > 0) + TEMP_FAILURE_RETRY (write (fd, buf, n)); + + close (mapfd); + } +#endif + + /* Pass on the signal (so that a core file is produced). */ + sa.sa_handler = SIG_DFL; + sigemptyset (&sa.sa_mask); + sa.sa_flags = 0; + sigaction (signal, &sa, NULL); + raise (signal); +} + + +static void +__attribute__ ((constructor)) +install_handler (void) +{ + struct sigaction sa; + const char *sigs = getenv ("SEGFAULT_SIGNALS"); + const char *name; + + sa.sa_handler = (void *) catch_segfault; + sigemptyset (&sa.sa_mask); + sa.sa_flags = SA_RESTART; + + /* Maybe we are expected to use an alternative stack. */ + if (getenv ("SEGFAULT_USE_ALTSTACK") != 0) + { + void *stack_mem = malloc (2 * SIGSTKSZ); + stack_t ss; + + if (stack_mem != NULL) + { + ss.ss_sp = stack_mem; + ss.ss_flags = 0; + ss.ss_size = 2 * SIGSTKSZ; + + if (sigaltstack (&ss, NULL) == 0) + sa.sa_flags |= SA_ONSTACK; + } + } + + if (sigs == NULL) + sigaction (SIGSEGV, &sa, NULL); + else if (sigs[0] == '\0') + /* Do not do anything. */ + return; + else + { + const char *where; + int all = __strcasecmp (sigs, "all") == 0; + +#define INSTALL_FOR_SIG(sig, name) \ + where = __strcasestr (sigs, name); \ + if (all || (where != NULL \ + && (where == sigs || !isalnum (where[-1])) \ + && !isalnum (where[sizeof (name) - 1]))) \ + sigaction (sig, &sa, NULL); + + INSTALL_FOR_SIG (SIGSEGV, "segv"); + INSTALL_FOR_SIG (SIGILL, "ill"); +#ifdef SIGBUS + INSTALL_FOR_SIG (SIGBUS, "bus"); +#endif +#ifdef SIGSTKFLT + INSTALL_FOR_SIG (SIGSTKFLT, "stkflt"); +#endif + INSTALL_FOR_SIG (SIGABRT, "abrt"); + INSTALL_FOR_SIG (SIGFPE, "fpe"); + } + + /* Preserve the output file name if there is any given. */ + name = getenv ("SEGFAULT_OUTPUT_NAME"); + if (name != NULL && name[0] != '\0') + { + int ret = access (name, R_OK | W_OK); + + if (ret == 0 || (ret == -1 && errno == ENOENT)) + fname = __strdup (name); + } +} diff --git a/REORG.TODO/debug/snprintf_chk.c b/REORG.TODO/debug/snprintf_chk.c new file mode 100644 index 0000000000..4a79cc59f0 --- /dev/null +++ b/REORG.TODO/debug/snprintf_chk.c @@ -0,0 +1,39 @@ +/* Copyright (C) 1991-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <libioP.h> +#include <stdarg.h> +#include <stdio.h> + + +/* Write formatted output into S, according to the format + string FORMAT, writing no more than MAXLEN characters. */ +/* VARARGS5 */ +int +___snprintf_chk (char *s, size_t maxlen, int flags, size_t slen, + const char *format, ...) +{ + va_list arg; + int done; + + va_start (arg, format); + done = __vsnprintf_chk (s, maxlen, flags, slen, format, arg); + va_end (arg); + + return done; +} +ldbl_strong_alias (___snprintf_chk, __snprintf_chk) diff --git a/REORG.TODO/debug/sprintf_chk.c b/REORG.TODO/debug/sprintf_chk.c new file mode 100644 index 0000000000..b4b89596f1 --- /dev/null +++ b/REORG.TODO/debug/sprintf_chk.c @@ -0,0 +1,36 @@ +/* Copyright (C) 1991-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <libioP.h> +#include <stdarg.h> +#include <stdio.h> + +/* Write formatted output into S, according to the format string FORMAT. */ +/* VARARGS4 */ +int +___sprintf_chk (char *s, int flags, size_t slen, const char *format, ...) +{ + va_list arg; + int done; + + va_start (arg, format); + done = __vsprintf_chk (s, flags, slen, format, arg); + va_end (arg); + + return done; +} +ldbl_strong_alias (___sprintf_chk, __sprintf_chk) diff --git a/REORG.TODO/debug/stack_chk_fail.c b/REORG.TODO/debug/stack_chk_fail.c new file mode 100644 index 0000000000..4f7346481d --- /dev/null +++ b/REORG.TODO/debug/stack_chk_fail.c @@ -0,0 +1,31 @@ +/* Copyright (C) 2005-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <stdio.h> +#include <stdlib.h> + + +extern char **__libc_argv attribute_hidden; + +void +__attribute__ ((noreturn)) +__stack_chk_fail (void) +{ + __fortify_fail ("stack smashing detected"); +} + +strong_alias (__stack_chk_fail, __stack_chk_fail_local) diff --git a/REORG.TODO/debug/stack_chk_fail_local.c b/REORG.TODO/debug/stack_chk_fail_local.c new file mode 100644 index 0000000000..eb0a759c4b --- /dev/null +++ b/REORG.TODO/debug/stack_chk_fail_local.c @@ -0,0 +1,46 @@ +/* Copyright (C) 2005-2017 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. + + In addition to the permissions in the GNU Lesser General Public + License, the Free Software Foundation gives you unlimited + permission to link the compiled version of this file with other + programs, and to distribute those programs without any restriction + coming from the use of this file. (The GNU Lesser General Public + License restrictions do apply in other respects; for example, they + cover modification of the file, and distribution when not linked + into another program.) + + Note that people who make modified versions of this file are not + obligated to grant this special exception for their modified + versions; it is their choice whether to do so. The GNU Lesser + General Public License gives permission to release a modified + version without this exception; this exception also makes it + possible to release a modified version which carries forward this + exception. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <sys/cdefs.h> + +extern void __stack_chk_fail (void) __attribute__ ((noreturn)); + +/* On some architectures, this helps needless PIC pointer setup + that would be needed just for the __stack_chk_fail call. */ + +void __attribute__ ((noreturn)) attribute_hidden +__stack_chk_fail_local (void) +{ + __stack_chk_fail (); +} diff --git a/REORG.TODO/debug/stpcpy_chk.c b/REORG.TODO/debug/stpcpy_chk.c new file mode 100644 index 0000000000..3f140e61c5 --- /dev/null +++ b/REORG.TODO/debug/stpcpy_chk.c @@ -0,0 +1,34 @@ +/* Copyright (C) 1992-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <string.h> + + +/* Copy SRC to DEST, returning the address of the terminating '\0' in DEST. */ +char * +__stpcpy_chk (char *dest, const char *src, size_t destlen) +{ + size_t len = strlen (src); + if (len >= destlen) + __chk_fail (); + + return memcpy (dest, src, len + 1) + len; +} diff --git a/REORG.TODO/debug/stpncpy_chk.c b/REORG.TODO/debug/stpncpy_chk.c new file mode 100644 index 0000000000..52d2634ad4 --- /dev/null +++ b/REORG.TODO/debug/stpncpy_chk.c @@ -0,0 +1,32 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +/* This is almost copied from strncpy.c, written by Torbjorn Granlund. */ + +#include <string.h> + + +/* Copy no more than N characters of SRC to DEST, returning the address of + the terminating '\0' in DEST, if any, or else DEST + N. */ +char * +__stpncpy_chk (char *dest, const char *src, size_t n, size_t destlen) +{ + if (__builtin_expect (destlen < n, 0)) + __chk_fail (); + + return __stpncpy (dest, src, n); +} diff --git a/REORG.TODO/debug/strcat_chk.c b/REORG.TODO/debug/strcat_chk.c new file mode 100644 index 0000000000..610c6bc358 --- /dev/null +++ b/REORG.TODO/debug/strcat_chk.c @@ -0,0 +1,54 @@ +/* Copyright (C) 1991-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <string.h> +#include <memcopy.h> + + +/* Append SRC on the end of DEST. */ +char * +__strcat_chk (char *dest, const char *src, size_t destlen) +{ + char *s1 = dest; + const char *s2 = src; + char c; + + /* Find the end of the string. */ + do + { + if (__glibc_unlikely (destlen-- == 0)) + __chk_fail (); + c = *s1++; + } + while (c != '\0'); + + /* Make S1 point before the next character, so we can increment + it while memory is read (wins on pipelined cpus). */ + ++destlen; + s1 -= 2; + + do + { + if (__glibc_unlikely (destlen-- == 0)) + __chk_fail (); + c = *s2++; + *++s1 = c; + } + while (c != '\0'); + + return dest; +} diff --git a/REORG.TODO/debug/strcpy_chk.c b/REORG.TODO/debug/strcpy_chk.c new file mode 100644 index 0000000000..3fb1cac10e --- /dev/null +++ b/REORG.TODO/debug/strcpy_chk.c @@ -0,0 +1,33 @@ +/* Copyright (C) 1991-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <stddef.h> +#include <string.h> +#include <memcopy.h> + +#undef strcpy + +/* Copy SRC to DEST with checking of destination buffer overflow. */ +char * +__strcpy_chk (char *dest, const char *src, size_t destlen) +{ + size_t len = strlen (src); + if (len >= destlen) + __chk_fail (); + + return memcpy (dest, src, len + 1); +} diff --git a/REORG.TODO/debug/strncat_chk.c b/REORG.TODO/debug/strncat_chk.c new file mode 100644 index 0000000000..d285f54448 --- /dev/null +++ b/REORG.TODO/debug/strncat_chk.c @@ -0,0 +1,95 @@ +/* Copyright (C) 1991-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <string.h> + +#include <memcopy.h> + + +char * +__strncat_chk (char *s1, const char *s2, size_t n, size_t s1len) +{ + char c; + char *s = s1; + + /* Find the end of S1. */ + do + { + if (__glibc_unlikely (s1len-- == 0)) + __chk_fail (); + c = *s1++; + } + while (c != '\0'); + + /* Make S1 point before next character, so we can increment + it while memory is read (wins on pipelined cpus). */ + ++s1len; + s1 -= 2; + + if (n >= 4) + { + size_t n4 = n >> 2; + do + { + if (__glibc_unlikely (s1len-- == 0)) + __chk_fail (); + c = *s2++; + *++s1 = c; + if (c == '\0') + return s; + if (__glibc_unlikely (s1len-- == 0)) + __chk_fail (); + c = *s2++; + *++s1 = c; + if (c == '\0') + return s; + if (__glibc_unlikely (s1len-- == 0)) + __chk_fail (); + c = *s2++; + *++s1 = c; + if (c == '\0') + return s; + if (__glibc_unlikely (s1len-- == 0)) + __chk_fail (); + c = *s2++; + *++s1 = c; + if (c == '\0') + return s; + } while (--n4 > 0); + n &= 3; + } + + while (n > 0) + { + if (__glibc_unlikely (s1len-- == 0)) + __chk_fail (); + c = *s2++; + *++s1 = c; + if (c == '\0') + return s; + n--; + } + + if (c != '\0') + { + if (__glibc_unlikely (s1len-- == 0)) + __chk_fail (); + *++s1 = '\0'; + } + + return s; +} diff --git a/REORG.TODO/debug/strncpy_chk.c b/REORG.TODO/debug/strncpy_chk.c new file mode 100644 index 0000000000..1901532201 --- /dev/null +++ b/REORG.TODO/debug/strncpy_chk.c @@ -0,0 +1,29 @@ +/* Copyright (C) 1991-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <string.h> +#include <memcopy.h> + + +char * +__strncpy_chk (char *s1, const char *s2, size_t n, size_t s1len) +{ + if (__builtin_expect (s1len < n, 0)) + __chk_fail (); + + return strncpy (s1, s2, n); +} diff --git a/REORG.TODO/debug/swprintf_chk.c b/REORG.TODO/debug/swprintf_chk.c new file mode 100644 index 0000000000..b5ae2a75f9 --- /dev/null +++ b/REORG.TODO/debug/swprintf_chk.c @@ -0,0 +1,35 @@ +/* Copyright (C) 1991-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <stdarg.h> +#include <wchar.h> + +/* Write formatted output into S, according to the format string FORMAT. */ +/* VARARGS5 */ +int +__swprintf_chk (wchar_t *s, size_t n, int flag, size_t s_len, + const wchar_t *format, ...) +{ + va_list arg; + int done; + + va_start (arg, format); + done = __vswprintf_chk (s, n, flag, s_len, format, arg); + va_end (arg); + + return done; +} diff --git a/REORG.TODO/debug/test-stpcpy_chk.c b/REORG.TODO/debug/test-stpcpy_chk.c new file mode 100644 index 0000000000..2bec1c7f3e --- /dev/null +++ b/REORG.TODO/debug/test-stpcpy_chk.c @@ -0,0 +1,46 @@ +/* Test and measure stpcpy checking functions. + Copyright (C) 1999-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Written by Jakub Jelinek <jakub@redhat.com>, 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#define STRCPY_RESULT(dst, len) ((dst) + (len)) +#define TEST_MAIN +#define TEST_NAME "stpcpy_chk" +#include "../string/test-string.h" + +extern void __attribute__ ((noreturn)) __chk_fail (void); +char *simple_stpcpy_chk (char *, const char *, size_t); +extern char *normal_stpcpy (char *, const char *, size_t) + __asm ("stpcpy"); +extern char *__stpcpy_chk (char *, const char *, size_t); + +IMPL (simple_stpcpy_chk, 0) +IMPL (normal_stpcpy, 1) +IMPL (__stpcpy_chk, 2) + +char * +simple_stpcpy_chk (char *dst, const char *src, size_t len) +{ + if (! len) + __chk_fail (); + while ((*dst++ = *src++) != '\0') + if (--len == 0) + __chk_fail (); + return dst - 1; +} + +#include "test-strcpy_chk.c" diff --git a/REORG.TODO/debug/test-strcpy_chk.c b/REORG.TODO/debug/test-strcpy_chk.c new file mode 100644 index 0000000000..8b729bd6ba --- /dev/null +++ b/REORG.TODO/debug/test-strcpy_chk.c @@ -0,0 +1,356 @@ +/* Test and measure __strcpy_chk functions. + Copyright (C) 1999-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Written by Jakub Jelinek <jakub@redhat.com>, 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#ifndef STRCPY_RESULT +# define STRCPY_RESULT(dst, len) dst +# define TEST_MAIN +# define TEST_NAME "strcpy_chk" +# include "../string/test-string.h" + +/* This test case implicitly tests the availability of the __chk_fail + symbol, which is part of the public ABI and may be used + externally. */ +extern void __attribute__ ((noreturn)) __chk_fail (void); +char *simple_strcpy_chk (char *, const char *, size_t); +extern char *normal_strcpy (char *, const char *, size_t) + __asm ("strcpy"); +extern char *__strcpy_chk (char *, const char *, size_t); + +IMPL (simple_strcpy_chk, 0) +IMPL (normal_strcpy, 1) +IMPL (__strcpy_chk, 2) + +char * +simple_strcpy_chk (char *dst, const char *src, size_t len) +{ + char *ret = dst; + if (! len) + __chk_fail (); + while ((*dst++ = *src++) != '\0') + if (--len == 0) + __chk_fail (); + return ret; +} +#endif + +#include <fcntl.h> +#include <paths.h> +#include <setjmp.h> +#include <signal.h> + +static int test_main (void); +#define TEST_FUNCTION test_main +#include <support/test-driver.c> +#include <support/support.h> + +volatile int chk_fail_ok; +jmp_buf chk_fail_buf; + +static void +handler (int sig) +{ + if (chk_fail_ok) + { + chk_fail_ok = 0; + longjmp (chk_fail_buf, 1); + } + else + _exit (127); +} + +typedef char *(*proto_t) (char *, const char *, size_t); + +static void +do_one_test (impl_t *impl, char *dst, const char *src, + size_t len, size_t dlen) +{ + char *res; + if (dlen <= len) + { + if (impl->test == 1) + return; + + chk_fail_ok = 1; + if (setjmp (chk_fail_buf) == 0) + { + res = CALL (impl, dst, src, dlen); + printf ("*** Function %s (%zd; %zd) did not __chk_fail\n", + impl->name, len, dlen); + chk_fail_ok = 0; + ret = 1; + } + return; + } + else + res = CALL (impl, dst, src, dlen); + + if (res != STRCPY_RESULT (dst, len)) + { + printf ("Wrong result in function %s %p %p\n", impl->name, + res, STRCPY_RESULT (dst, len)); + ret = 1; + return; + } + + if (strcmp (dst, src) != 0) + { + printf ("Wrong result in function %s dst \"%s\" src \"%s\"\n", + impl->name, dst, src); + ret = 1; + return; + } +} + +static void +do_test (size_t align1, size_t align2, size_t len, size_t dlen, int max_char) +{ + size_t i; + char *s1, *s2; + + align1 &= 7; + if (align1 + len >= page_size) + return; + + align2 &= 7; + if (align2 + len >= page_size) + return; + + s1 = (char *) buf1 + align1; + s2 = (char *) buf2 + align2; + + for (i = 0; i < len; i++) + s1[i] = 32 + 23 * i % (max_char - 32); + s1[len] = 0; + + FOR_EACH_IMPL (impl, 0) + do_one_test (impl, s2, s1, len, dlen); +} + +static void +do_random_tests (void) +{ + size_t i, j, n, align1, align2, len, dlen; + unsigned char *p1 = buf1 + page_size - 512; + unsigned char *p2 = buf2 + page_size - 512; + unsigned char *res; + + for (n = 0; n < ITERATIONS; n++) + { + align1 = random () & 31; + if (random () & 1) + align2 = random () & 31; + else + align2 = align1 + (random () & 24); + len = random () & 511; + j = align1; + if (align2 > j) + j = align2; + if (len + j >= 511) + len = 510 - j - (random () & 7); + j = len + align1 + 64; + if (j > 512) + j = 512; + for (i = 0; i < j; i++) + { + if (i == len + align1) + p1[i] = 0; + else + { + p1[i] = random () & 255; + if (i >= align1 && i < len + align1 && !p1[i]) + p1[i] = (random () & 127) + 3; + } + } + + switch (random () & 7) + { + case 0: + dlen = len - (random () & 31); + if (dlen > len) + dlen = len; + break; + case 1: + dlen = (size_t) -1; + break; + case 2: + dlen = len + 1 + (random () & 65535); + break; + case 3: + dlen = len + 1 + (random () & 255); + break; + case 4: + dlen = len + 1 + (random () & 31); + break; + case 5: + dlen = len + 1 + (random () & 7); + break; + case 6: + dlen = len + 1 + (random () & 3); + break; + default: + dlen = len + 1; + break; + } + + FOR_EACH_IMPL (impl, 1) + { + if (dlen <= len) + { + if (impl->test != 1) + { + chk_fail_ok = 1; + if (setjmp (chk_fail_buf) == 0) + { + res = (unsigned char *) + CALL (impl, (char *) p2 + align2, + (char *) p1 + align1, dlen); + printf ("Iteration %zd - did not __chk_fail\n", n); + chk_fail_ok = 0; + ret = 1; + } + } + continue; + } + memset (p2 - 64, '\1', 512 + 64); + res = (unsigned char *) + CALL (impl, (char *) p2 + align2, (char *) p1 + align1, dlen); + if (res != STRCPY_RESULT (p2 + align2, len)) + { + printf ("\ +Iteration %zd - wrong result in function %s (%zd, %zd, %zd) %p != %p\n", + n, impl->name, align1, align2, len, res, + STRCPY_RESULT (p2 + align2, len)); + ret = 1; + } + for (j = 0; j < align2 + 64; ++j) + { + if (p2[j - 64] != '\1') + { + printf ("\ +Iteration %zd - garbage before, %s (%zd, %zd, %zd)\n", + n, impl->name, align1, align2, len); + ret = 1; + break; + } + } + for (j = align2 + len + 1; j < 512; ++j) + { + if (p2[j] != '\1') + { + printf ("\ +Iteration %zd - garbage after, %s (%zd, %zd, %zd)\n", + n, impl->name, align1, align2, len); + ret = 1; + break; + } + } + if (memcmp (p1 + align1, p2 + align2, len + 1)) + { + printf ("\ +Iteration %zd - different strings, %s (%zd, %zd, %zd)\n", + n, impl->name, align1, align2, len); + ret = 1; + } + } + } +} + +static int +test_main (void) +{ + size_t i; + + set_fortify_handler (handler); + + test_init (); + + printf ("%23s", ""); + FOR_EACH_IMPL (impl, 0) + printf ("\t%s", impl->name); + putchar ('\n'); + + for (i = 0; i < 16; ++i) + { + do_test (0, 0, i, i + 1, 127); + do_test (0, 0, i, i + 1, 255); + do_test (0, i, i, i + 1, 127); + do_test (i, 0, i, i + 1, 255); + } + + for (i = 1; i < 8; ++i) + { + do_test (0, 0, 8 << i, (8 << i) + 1, 127); + do_test (8 - i, 2 * i, (8 << i), (8 << i) + 1, 127); + } + + for (i = 1; i < 8; ++i) + { + do_test (i, 2 * i, (8 << i), (8 << i) + 1, 127); + do_test (2 * i, i, (8 << i), (8 << i) + 1, 255); + do_test (i, i, (8 << i), (8 << i) + 1, 127); + do_test (i, i, (8 << i), (8 << i) + 1, 255); + } + + for (i = 0; i < 16; ++i) + { + do_test (0, 0, i, i + 256, 127); + do_test (0, 0, i, i + 256, 255); + do_test (0, i, i, i + 256, 127); + do_test (i, 0, i, i + 256, 255); + } + + for (i = 1; i < 8; ++i) + { + do_test (0, 0, 8 << i, (8 << i) + 256, 127); + do_test (8 - i, 2 * i, (8 << i), (8 << i) + 256, 127); + } + + for (i = 1; i < 8; ++i) + { + do_test (i, 2 * i, (8 << i), (8 << i) + 256, 127); + do_test (2 * i, i, (8 << i), (8 << i) + 256, 255); + do_test (i, i, (8 << i), (8 << i) + 256, 127); + do_test (i, i, (8 << i), (8 << i) + 256, 255); + } + + for (i = 0; i < 16; ++i) + { + do_test (0, 0, i, i, 127); + do_test (0, 0, i, i + 2, 255); + do_test (0, i, i, i + 3, 127); + do_test (i, 0, i, i + 4, 255); + } + + for (i = 1; i < 8; ++i) + { + do_test (0, 0, 8 << i, (8 << i) - 15, 127); + do_test (8 - i, 2 * i, (8 << i), (8 << i) + 5, 127); + } + + for (i = 1; i < 8; ++i) + { + do_test (i, 2 * i, (8 << i), (8 << i) + i, 127); + do_test (2 * i, i, (8 << i), (8 << i) + (i - 1), 255); + do_test (i, i, (8 << i), (8 << i) + i + 2, 127); + do_test (i, i, (8 << i), (8 << i) + i + 3, 255); + } + + do_random_tests (); + return ret; +} diff --git a/REORG.TODO/debug/tst-backtrace.h b/REORG.TODO/debug/tst-backtrace.h new file mode 100644 index 0000000000..ba173c90b0 --- /dev/null +++ b/REORG.TODO/debug/tst-backtrace.h @@ -0,0 +1,48 @@ +/* Test backtrace and backtrace_symbols: common code for examining + backtraces. + Copyright (C) 2013-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <stdbool.h> +#include <stdio.h> +#include <string.h> + +/* Set to a non-zero value if the test fails. */ +volatile int ret; + +/* Accesses to X are used to prevent optimization. */ +volatile int x; + +/* Called if the test fails. */ +#define FAIL() \ + do { printf ("Failure on line %d\n", __LINE__); ret = 1; } while (0) + +/* Use this attribute to prevent inlining, so that all expected frames + are present. */ +#define NO_INLINE __attribute__ ((noinline, noclone, weak)) + +/* Look for a match in SYM from backtrace_symbols to NAME, a fragment + of a function name. Ignore the filename before '(', but presume + that the function names are chosen so they cannot accidentally + match the hex offset before the closing ')'. */ + +static inline bool +match (const char *sym, const char *name) +{ + char *p = strchr (sym, '('); + return p != NULL && strstr (p, name) != NULL; +} diff --git a/REORG.TODO/debug/tst-backtrace2.c b/REORG.TODO/debug/tst-backtrace2.c new file mode 100644 index 0000000000..86f88dee82 --- /dev/null +++ b/REORG.TODO/debug/tst-backtrace2.c @@ -0,0 +1,103 @@ +/* Test backtrace and backtrace_symbols. + Copyright (C) 2009-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <execinfo.h> +#include <search.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "tst-backtrace.h" + +/* The backtrace should include at least f1, f2, f3, and do_test. */ +#define NUM_FUNCTIONS 4 + +NO_INLINE void +fn1 (void) +{ + void *addresses[NUM_FUNCTIONS]; + char **symbols; + int n; + int i; + + /* Get the backtrace addresses. */ + n = backtrace (addresses, sizeof (addresses) / sizeof (addresses[0])); + printf ("Obtained backtrace with %d functions\n", n); + /* Check that there are at least four functions. */ + if (n < NUM_FUNCTIONS) + { + FAIL (); + return; + } + /* Convert them to symbols. */ + symbols = backtrace_symbols (addresses, n); + /* Check that symbols were obtained. */ + if (symbols == NULL) + { + FAIL (); + return; + } + for (i = 0; i < n; ++i) + printf ("Function %d: %s\n", i, symbols[i]); + /* Check that the function names obtained are accurate. */ + if (!match (symbols[0], "fn1")) + { + FAIL (); + return; + } + /* Symbol names are not available for static functions, so we do not + check f2. */ + if (!match (symbols[2], "fn3")) + { + FAIL (); + return; + } + /* Symbol names are not available for static functions, so we do not + check do_test. */ +} + +NO_INLINE int +fn2 (void) +{ + fn1 (); + /* Prevent tail calls. */ + return x; +} + +NO_INLINE int +fn3 (void) +{ + fn2(); + /* Prevent tail calls. */ + return x; +} + +NO_INLINE int +do_test (void) +{ + /* Test BZ #18084. */ + void *buffer[1]; + + if (backtrace (buffer, 0) != 0) + FAIL (); + + fn3 (); + return ret; +} + +#include <support/test-driver.c> diff --git a/REORG.TODO/debug/tst-backtrace3.c b/REORG.TODO/debug/tst-backtrace3.c new file mode 100644 index 0000000000..e57a70bb11 --- /dev/null +++ b/REORG.TODO/debug/tst-backtrace3.c @@ -0,0 +1,81 @@ +/* Test backtrace and backtrace_symbols for recursive calls. + Copyright (C) 2010-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <execinfo.h> +#include <search.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "tst-backtrace.h" + +/* The backtrace should include at least 3 * fn, and do_test. */ +#define NUM_FUNCTIONS 4 + +NO_INLINE int +fn (int c) +{ + void *addresses[NUM_FUNCTIONS]; + char **symbols; + int n; + int i; + + if (c > 0) + { + fn (c - 1); + return x; + } + /* Get the backtrace addresses. */ + n = backtrace (addresses, sizeof (addresses) / sizeof (addresses[0])); + printf ("Obtained backtrace with %d functions\n", n); + /* Check that there are at least four functions. */ + if (n < NUM_FUNCTIONS) + { + FAIL (); + return 1; + } + /* Convert them to symbols. */ + symbols = backtrace_symbols (addresses, n); + /* Check that symbols were obtained. */ + if (symbols == NULL) + { + FAIL (); + return 1; + } + for (i = 0; i < n; ++i) + printf ("Function %d: %s\n", i, symbols[i]); + /* Check that the function names obtained are accurate. */ + for (i = 0; i < n - 1; ++i) + if (!match (symbols[i], "fn")) + { + FAIL (); + return 1; + } + /* Symbol names are not available for static functions, so we do not + check do_test. */ + return x; +} + +NO_INLINE int +do_test (void) +{ + fn (2); + return ret; +} + +#include <support/test-driver.c> diff --git a/REORG.TODO/debug/tst-backtrace4.c b/REORG.TODO/debug/tst-backtrace4.c new file mode 100644 index 0000000000..5c3423655c --- /dev/null +++ b/REORG.TODO/debug/tst-backtrace4.c @@ -0,0 +1,121 @@ +/* Test backtrace and backtrace_symbols for signal frames. + Copyright (C) 2011-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <execinfo.h> +#include <search.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <signal.h> +#include <unistd.h> + +#include "tst-backtrace.h" + +/* The backtrace should include at least handle_signal, a signal + trampoline, 3 * fn, and do_test. */ +#define NUM_FUNCTIONS 6 + +volatile int sig_handled = 0; + +void +handle_signal (int signum) +{ + void *addresses[NUM_FUNCTIONS]; + char **symbols; + int n; + int i; + + sig_handled = 1; + + /* Get the backtrace addresses. */ + n = backtrace (addresses, sizeof (addresses) / sizeof (addresses[0])); + printf ("Obtained backtrace with %d functions (want at least %d)\n", + n, NUM_FUNCTIONS); + /* Check that there are at least NUM_FUNCTIONS functions. */ + if (n < NUM_FUNCTIONS) + { + FAIL (); + /* Only return if we got no symbols at all. The partial output is + still useful for debugging failures. */ + if (n <= 0) + return; + } + /* Convert them to symbols. */ + symbols = backtrace_symbols (addresses, n); + /* Check that symbols were obtained. */ + if (symbols == NULL) + { + FAIL (); + return; + } + for (i = 0; i < n; ++i) + printf ("Function %d: %s\n", i, symbols[i]); + /* Check that the function names obtained are accurate. */ + if (!match (symbols[0], "handle_signal")) + FAIL (); + /* Do not check name for signal trampoline. */ + for (i = 2; i < n - 1; i++) + if (!match (symbols[i], "fn")) + { + FAIL (); + return; + } + /* Symbol names are not available for static functions, so we do not + check do_test. */ +} + +NO_INLINE int +fn (int c) +{ + pid_t parent_pid, child_pid; + + if (c > 0) + { + fn (c - 1); + return x; + } + + signal (SIGUSR1, handle_signal); + parent_pid = getpid (); + + child_pid = fork (); + if (child_pid == (pid_t) -1) + abort (); + else if (child_pid == 0) + { + sleep (1); + kill (parent_pid, SIGUSR1); + _exit (0); + } + + /* In the parent. */ + while (sig_handled == 0) + ; + + return 0; +} + +NO_INLINE int +do_test (void) +{ + fn (2); + return ret; +} + +#include <support/test-driver.c> diff --git a/REORG.TODO/debug/tst-backtrace5.c b/REORG.TODO/debug/tst-backtrace5.c new file mode 100644 index 0000000000..0b85e4482e --- /dev/null +++ b/REORG.TODO/debug/tst-backtrace5.c @@ -0,0 +1,139 @@ +/* Test backtrace and backtrace_symbols for signal frames, where a + system call was interrupted by a signal. + Copyright (C) 2011-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <execinfo.h> +#include <search.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <signal.h> +#include <unistd.h> + +#include "tst-backtrace.h" + +#ifndef SIGACTION_FLAGS +# define SIGACTION_FLAGS 0 +#endif + +/* The backtrace should include at least handle_signal, a signal + trampoline, read, 3 * fn, and do_test. */ +#define NUM_FUNCTIONS 7 + +void +handle_signal (int signum) +{ + void *addresses[NUM_FUNCTIONS]; + char **symbols; + int n; + int i; + + /* Get the backtrace addresses. */ + n = backtrace (addresses, sizeof (addresses) / sizeof (addresses[0])); + printf ("Obtained backtrace with %d functions\n", n); + /* Check that there are at least seven functions. */ + if (n < NUM_FUNCTIONS) + { + FAIL (); + return; + } + /* Convert them to symbols. */ + symbols = backtrace_symbols (addresses, n); + /* Check that symbols were obtained. */ + if (symbols == NULL) + { + FAIL (); + return; + } + for (i = 0; i < n; ++i) + printf ("Function %d: %s\n", i, symbols[i]); + /* Check that the function names obtained are accurate. */ + if (!match (symbols[0], "handle_signal")) + { + FAIL (); + return; + } + /* Do not check name for signal trampoline. */ + i = 2; + if (!match (symbols[i++], "read")) + { + /* Perhaps symbols[2] is __kernel_vsyscall? */ + if (!match (symbols[i++], "read")) + { + FAIL (); + return; + } + } + for (; i < n - 1; i++) + if (!match (symbols[i], "fn")) + { + FAIL (); + return; + } + /* Symbol names are not available for static functions, so we do not + check do_test. */ +} + +NO_INLINE int +fn (int c, int flags) +{ + pid_t parent_pid, child_pid; + int pipefd[2]; + char r[1]; + struct sigaction act; + + if (c > 0) + { + fn (c - 1, flags); + return x; + } + + memset (&act, 0, sizeof (act)); + act.sa_handler = handle_signal; + act.sa_flags = flags; + sigemptyset (&act.sa_mask); + sigaction (SIGUSR1, &act, NULL); + parent_pid = getpid (); + if (pipe (pipefd) == -1) + abort (); + + child_pid = fork (); + if (child_pid == (pid_t) -1) + abort (); + else if (child_pid == 0) + { + sleep (1); + kill (parent_pid, SIGUSR1); + _exit (0); + } + + /* In the parent. */ + read (pipefd[0], r, 1); + + return 0; +} + +NO_INLINE int +do_test (void) +{ + fn (2, SIGACTION_FLAGS); + return ret; +} + +#include <support/test-driver.c> diff --git a/REORG.TODO/debug/tst-backtrace6.c b/REORG.TODO/debug/tst-backtrace6.c new file mode 100644 index 0000000000..64ede3ce3a --- /dev/null +++ b/REORG.TODO/debug/tst-backtrace6.c @@ -0,0 +1,28 @@ +/* Test backtrace and backtrace_symbols for signal frames, where a + system call was interrupted by a signal. + Copyright (C) 2013-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <signal.h> + +#ifdef SA_SIGINFO +# define SIGACTION_FLAGS SA_SIGINFO +# include <debug/tst-backtrace5.c> +#else +# define TEST_FUNCTION 0 +# include "../test-skeleton.c" +#endif diff --git a/REORG.TODO/debug/tst-chk1.c b/REORG.TODO/debug/tst-chk1.c new file mode 100644 index 0000000000..60c8e1e1d0 --- /dev/null +++ b/REORG.TODO/debug/tst-chk1.c @@ -0,0 +1,1717 @@ +/* Copyright (C) 2004-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Jakub Jelinek <jakub@redhat.com>, 2004. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +/* This file tests gets. Force it to be declared. */ +#include <features.h> +#undef __GLIBC_USE_DEPRECATED_GETS +#define __GLIBC_USE_DEPRECATED_GETS 1 + +#include <assert.h> +#include <fcntl.h> +#include <locale.h> +#include <obstack.h> +#include <setjmp.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <wchar.h> +#include <sys/poll.h> +#include <sys/select.h> +#include <sys/socket.h> +#include <sys/un.h> + + +#define obstack_chunk_alloc malloc +#define obstack_chunk_free free + +char *temp_filename; +static void do_prepare (void); +static int do_test (void); +#define PREPARE(argc, argv) do_prepare () +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" + +static void +do_prepare (void) +{ + int temp_fd = create_temp_file ("tst-chk1.", &temp_filename); + if (temp_fd == -1) + { + printf ("cannot create temporary file: %m\n"); + exit (1); + } + + const char *strs = "abcdefgh\nABCDEFGHI\nabcdefghij\nABCDEFGHIJ"; + if ((size_t) write (temp_fd, strs, strlen (strs)) != strlen (strs)) + { + puts ("could not write test strings into file"); + unlink (temp_filename); + exit (1); + } +} + +volatile int chk_fail_ok; +volatile int ret; +jmp_buf chk_fail_buf; + +static void +handler (int sig) +{ + if (chk_fail_ok) + { + chk_fail_ok = 0; + longjmp (chk_fail_buf, 1); + } + else + _exit (127); +} + +char buf[10]; +wchar_t wbuf[10]; +volatile size_t l0; +volatile char *p; +volatile wchar_t *wp; +const char *str1 = "JIHGFEDCBA"; +const char *str2 = "F"; +const char *str3 = "%s%n%s%n"; +const char *str4 = "Hello, "; +const char *str5 = "World!\n"; +const wchar_t *wstr1 = L"JIHGFEDCBA"; +const wchar_t *wstr2 = L"F"; +const wchar_t *wstr3 = L"%s%n%s%n"; +const wchar_t *wstr4 = L"Hello, "; +const wchar_t *wstr5 = L"World!\n"; +char buf2[10] = "%s"; +int num1 = 67; +int num2 = 987654; + +#define FAIL() \ + do { printf ("Failure on line %d\n", __LINE__); ret = 1; } while (0) +#define CHK_FAIL_START \ + chk_fail_ok = 1; \ + if (! setjmp (chk_fail_buf)) \ + { +#define CHK_FAIL_END \ + chk_fail_ok = 0; \ + FAIL (); \ + } +#if __USE_FORTIFY_LEVEL >= 2 && (!defined __cplusplus || defined __va_arg_pack) +# define CHK_FAIL2_START CHK_FAIL_START +# define CHK_FAIL2_END CHK_FAIL_END +#else +# define CHK_FAIL2_START +# define CHK_FAIL2_END +#endif + +static int +do_test (void) +{ + set_fortify_handler (handler); + + struct A { char buf1[9]; char buf2[1]; } a; + struct wA { wchar_t buf1[9]; wchar_t buf2[1]; } wa; + + printf ("Test checking routines at fortify level %d\n", +#ifdef __USE_FORTIFY_LEVEL + (int) __USE_FORTIFY_LEVEL +#else + 0 +#endif + ); + +#if defined __USE_FORTIFY_LEVEL && !defined __fortify_function + printf ("Test skipped"); + if (l0 == 0) + return 0; +#endif + + /* These ops can be done without runtime checking of object size. */ + memcpy (buf, "abcdefghij", 10); + memmove (buf + 1, buf, 9); + if (memcmp (buf, "aabcdefghi", 10)) + FAIL (); + + memcpy (buf, "abcdefghij", 10); + bcopy (buf, buf + 1, 9); + if (memcmp (buf, "aabcdefghi", 10)) + FAIL (); + + if (mempcpy (buf + 5, "abcde", 5) != buf + 10 + || memcmp (buf, "aabcdabcde", 10)) + FAIL (); + + memset (buf + 8, 'j', 2); + if (memcmp (buf, "aabcdabcjj", 10)) + FAIL (); + + bzero (buf + 8, 2); + if (memcmp (buf, "aabcdabc\0\0", 10)) + FAIL (); + + explicit_bzero (buf + 6, 4); + if (memcmp (buf, "aabcda\0\0\0\0", 10)) + FAIL (); + + strcpy (buf + 4, "EDCBA"); + if (memcmp (buf, "aabcEDCBA", 10)) + FAIL (); + + if (stpcpy (buf + 8, "F") != buf + 9 || memcmp (buf, "aabcEDCBF", 10)) + FAIL (); + + strncpy (buf + 6, "X", 4); + if (memcmp (buf, "aabcEDX\0\0", 10)) + FAIL (); + + if (sprintf (buf + 7, "%s", "67") != 2 || memcmp (buf, "aabcEDX67", 10)) + FAIL (); + + if (snprintf (buf + 7, 3, "%s", "987654") != 6 + || memcmp (buf, "aabcEDX98", 10)) + FAIL (); + + /* These ops need runtime checking, but shouldn't __chk_fail. */ + memcpy (buf, "abcdefghij", l0 + 10); + memmove (buf + 1, buf, l0 + 9); + if (memcmp (buf, "aabcdefghi", 10)) + FAIL (); + + memcpy (buf, "abcdefghij", l0 + 10); + bcopy (buf, buf + 1, l0 + 9); + if (memcmp (buf, "aabcdefghi", 10)) + FAIL (); + + if (mempcpy (buf + 5, "abcde", l0 + 5) != buf + 10 + || memcmp (buf, "aabcdabcde", 10)) + FAIL (); + + memset (buf + 8, 'j', l0 + 2); + if (memcmp (buf, "aabcdabcjj", 10)) + FAIL (); + + bzero (buf + 8, l0 + 2); + if (memcmp (buf, "aabcdabc\0\0", 10)) + FAIL (); + + explicit_bzero (buf + 6, l0 + 4); + if (memcmp (buf, "aabcda\0\0\0\0", 10)) + FAIL (); + + strcpy (buf + 4, str1 + 5); + if (memcmp (buf, "aabcEDCBA", 10)) + FAIL (); + + if (stpcpy (buf + 8, str2) != buf + 9 || memcmp (buf, "aabcEDCBF", 10)) + FAIL (); + + strncpy (buf + 6, "X", l0 + 4); + if (memcmp (buf, "aabcEDX\0\0", 10)) + FAIL (); + + if (stpncpy (buf + 5, "cd", l0 + 5) != buf + 7 + || memcmp (buf, "aabcEcd\0\0", 10)) + FAIL (); + + if (sprintf (buf + 7, "%d", num1) != 2 || memcmp (buf, "aabcEcd67", 10)) + FAIL (); + + if (snprintf (buf + 7, 3, "%d", num2) != 6 || memcmp (buf, "aabcEcd98", 10)) + FAIL (); + + buf[l0 + 8] = '\0'; + strcat (buf, "A"); + if (memcmp (buf, "aabcEcd9A", 10)) + FAIL (); + + buf[l0 + 7] = '\0'; + strncat (buf, "ZYXWV", l0 + 2); + if (memcmp (buf, "aabcEcdZY", 10)) + FAIL (); + + /* The following tests are supposed to succeed at all fortify + levels, even though they overflow a.buf1 into a.buf2. */ + memcpy (a.buf1, "abcdefghij", l0 + 10); + memmove (a.buf1 + 1, a.buf1, l0 + 9); + if (memcmp (a.buf1, "aabcdefghi", 10)) + FAIL (); + + memcpy (a.buf1, "abcdefghij", l0 + 10); + bcopy (a.buf1, a.buf1 + 1, l0 + 9); + if (memcmp (a.buf1, "aabcdefghi", 10)) + FAIL (); + + if (mempcpy (a.buf1 + 5, "abcde", l0 + 5) != a.buf1 + 10 + || memcmp (a.buf1, "aabcdabcde", 10)) + FAIL (); + + memset (a.buf1 + 8, 'j', l0 + 2); + if (memcmp (a.buf1, "aabcdabcjj", 10)) + FAIL (); + + bzero (a.buf1 + 8, l0 + 2); + if (memcmp (a.buf1, "aabcdabc\0\0", 10)) + FAIL (); + + explicit_bzero (a.buf1 + 6, l0 + 4); + if (memcmp (a.buf1, "aabcda\0\0\0\0", 10)) + FAIL (); + +#if __USE_FORTIFY_LEVEL < 2 + /* The following tests are supposed to crash with -D_FORTIFY_SOURCE=2 + and sufficient GCC support, as the string operations overflow + from a.buf1 into a.buf2. */ + strcpy (a.buf1 + 4, str1 + 5); + if (memcmp (a.buf1, "aabcEDCBA", 10)) + FAIL (); + + if (stpcpy (a.buf1 + 8, str2) != a.buf1 + 9 + || memcmp (a.buf1, "aabcEDCBF", 10)) + FAIL (); + + strncpy (a.buf1 + 6, "X", l0 + 4); + if (memcmp (a.buf1, "aabcEDX\0\0", 10)) + FAIL (); + + if (sprintf (a.buf1 + 7, "%d", num1) != 2 + || memcmp (a.buf1, "aabcEDX67", 10)) + FAIL (); + + if (snprintf (a.buf1 + 7, 3, "%d", num2) != 6 + || memcmp (a.buf1, "aabcEDX98", 10)) + FAIL (); + + a.buf1[l0 + 8] = '\0'; + strcat (a.buf1, "A"); + if (memcmp (a.buf1, "aabcEDX9A", 10)) + FAIL (); + + a.buf1[l0 + 7] = '\0'; + strncat (a.buf1, "ZYXWV", l0 + 2); + if (memcmp (a.buf1, "aabcEDXZY", 10)) + FAIL (); + +#endif + +#if __USE_FORTIFY_LEVEL >= 1 + /* Now check if all buffer overflows are caught at runtime. + N.B. All tests involving a length parameter need to be done + twice: once with the length a compile-time constant, once without. */ + + CHK_FAIL_START + memcpy (buf + 1, "abcdefghij", 10); + CHK_FAIL_END + + CHK_FAIL_START + memcpy (buf + 1, "abcdefghij", l0 + 10); + CHK_FAIL_END + + CHK_FAIL_START + memmove (buf + 2, buf + 1, 9); + CHK_FAIL_END + + CHK_FAIL_START + memmove (buf + 2, buf + 1, l0 + 9); + CHK_FAIL_END + + CHK_FAIL_START + bcopy (buf + 1, buf + 2, 9); + CHK_FAIL_END + + CHK_FAIL_START + bcopy (buf + 1, buf + 2, l0 + 9); + CHK_FAIL_END + + CHK_FAIL_START + p = (char *) mempcpy (buf + 6, "abcde", 5); + CHK_FAIL_END + + CHK_FAIL_START + p = (char *) mempcpy (buf + 6, "abcde", l0 + 5); + CHK_FAIL_END + + CHK_FAIL_START + memset (buf + 9, 'j', 2); + CHK_FAIL_END + + CHK_FAIL_START + memset (buf + 9, 'j', l0 + 2); + CHK_FAIL_END + + CHK_FAIL_START + bzero (buf + 9, 2); + CHK_FAIL_END + + CHK_FAIL_START + bzero (buf + 9, l0 + 2); + CHK_FAIL_END + + CHK_FAIL_START + explicit_bzero (buf + 9, 2); + CHK_FAIL_END + + CHK_FAIL_START + explicit_bzero (buf + 9, l0 + 2); + CHK_FAIL_END + + CHK_FAIL_START + strcpy (buf + 5, str1 + 5); + CHK_FAIL_END + + CHK_FAIL_START + p = stpcpy (buf + 9, str2); + CHK_FAIL_END + + CHK_FAIL_START + strncpy (buf + 7, "X", 4); + CHK_FAIL_END + + CHK_FAIL_START + strncpy (buf + 7, "X", l0 + 4); + CHK_FAIL_END + + CHK_FAIL_START + stpncpy (buf + 6, "cd", 5); + CHK_FAIL_END + + CHK_FAIL_START + stpncpy (buf + 6, "cd", l0 + 5); + CHK_FAIL_END + +# if !defined __cplusplus || defined __va_arg_pack + CHK_FAIL_START + sprintf (buf + 8, "%d", num1); + CHK_FAIL_END + + CHK_FAIL_START + snprintf (buf + 8, 3, "%d", num2); + CHK_FAIL_END + + CHK_FAIL_START + snprintf (buf + 8, l0 + 3, "%d", num2); + CHK_FAIL_END + + CHK_FAIL_START + swprintf (wbuf + 8, 3, L"%d", num1); + CHK_FAIL_END + + CHK_FAIL_START + swprintf (wbuf + 8, l0 + 3, L"%d", num1); + CHK_FAIL_END +# endif + + memcpy (buf, str1 + 2, 9); + CHK_FAIL_START + strcat (buf, "AB"); + CHK_FAIL_END + + memcpy (buf, str1 + 3, 8); + CHK_FAIL_START + strncat (buf, "ZYXWV", 3); + CHK_FAIL_END + + memcpy (buf, str1 + 3, 8); + CHK_FAIL_START + strncat (buf, "ZYXWV", l0 + 3); + CHK_FAIL_END + + CHK_FAIL_START + memcpy (a.buf1 + 1, "abcdefghij", 10); + CHK_FAIL_END + + CHK_FAIL_START + memcpy (a.buf1 + 1, "abcdefghij", l0 + 10); + CHK_FAIL_END + + CHK_FAIL_START + memmove (a.buf1 + 2, a.buf1 + 1, 9); + CHK_FAIL_END + + CHK_FAIL_START + memmove (a.buf1 + 2, a.buf1 + 1, l0 + 9); + CHK_FAIL_END + + CHK_FAIL_START + bcopy (a.buf1 + 1, a.buf1 + 2, 9); + CHK_FAIL_END + + CHK_FAIL_START + bcopy (a.buf1 + 1, a.buf1 + 2, l0 + 9); + CHK_FAIL_END + + CHK_FAIL_START + p = (char *) mempcpy (a.buf1 + 6, "abcde", 5); + CHK_FAIL_END + + CHK_FAIL_START + p = (char *) mempcpy (a.buf1 + 6, "abcde", l0 + 5); + CHK_FAIL_END + + CHK_FAIL_START + memset (a.buf1 + 9, 'j', 2); + CHK_FAIL_END + + CHK_FAIL_START + memset (a.buf1 + 9, 'j', l0 + 2); + CHK_FAIL_END + + CHK_FAIL_START + bzero (a.buf1 + 9, 2); + CHK_FAIL_END + + CHK_FAIL_START + bzero (a.buf1 + 9, l0 + 2); + CHK_FAIL_END + + CHK_FAIL_START + explicit_bzero (a.buf1 + 9, 2); + CHK_FAIL_END + + CHK_FAIL_START + explicit_bzero (a.buf1 + 9, l0 + 2); + CHK_FAIL_END + +# if __USE_FORTIFY_LEVEL >= 2 +# define O 0 +# else +# define O 1 +# endif + + CHK_FAIL_START + strcpy (a.buf1 + (O + 4), str1 + 5); + CHK_FAIL_END + + CHK_FAIL_START + p = stpcpy (a.buf1 + (O + 8), str2); + CHK_FAIL_END + + CHK_FAIL_START + strncpy (a.buf1 + (O + 6), "X", 4); + CHK_FAIL_END + + CHK_FAIL_START + strncpy (a.buf1 + (O + 6), "X", l0 + 4); + CHK_FAIL_END + +# if !defined __cplusplus || defined __va_arg_pack + CHK_FAIL_START + sprintf (a.buf1 + (O + 7), "%d", num1); + CHK_FAIL_END + + CHK_FAIL_START + snprintf (a.buf1 + (O + 7), 3, "%d", num2); + CHK_FAIL_END + + CHK_FAIL_START + snprintf (a.buf1 + (O + 7), l0 + 3, "%d", num2); + CHK_FAIL_END +# endif + + memcpy (a.buf1, str1 + (3 - O), 8 + O); + CHK_FAIL_START + strcat (a.buf1, "AB"); + CHK_FAIL_END + + memcpy (a.buf1, str1 + (4 - O), 7 + O); + CHK_FAIL_START + strncat (a.buf1, "ZYXWV", l0 + 3); + CHK_FAIL_END +#endif + + + /* These ops can be done without runtime checking of object size. */ + wmemcpy (wbuf, L"abcdefghij", 10); + wmemmove (wbuf + 1, wbuf, 9); + if (wmemcmp (wbuf, L"aabcdefghi", 10)) + FAIL (); + + if (wmempcpy (wbuf + 5, L"abcde", 5) != wbuf + 10 + || wmemcmp (wbuf, L"aabcdabcde", 10)) + FAIL (); + + wmemset (wbuf + 8, L'j', 2); + if (wmemcmp (wbuf, L"aabcdabcjj", 10)) + FAIL (); + + wcscpy (wbuf + 4, L"EDCBA"); + if (wmemcmp (wbuf, L"aabcEDCBA", 10)) + FAIL (); + + if (wcpcpy (wbuf + 8, L"F") != wbuf + 9 || wmemcmp (wbuf, L"aabcEDCBF", 10)) + FAIL (); + + wcsncpy (wbuf + 6, L"X", 4); + if (wmemcmp (wbuf, L"aabcEDX\0\0", 10)) + FAIL (); + + if (swprintf (wbuf + 7, 3, L"%ls", L"987654") >= 0 + || wmemcmp (wbuf, L"aabcEDX98", 10)) + FAIL (); + + if (swprintf (wbuf + 7, 3, L"64") != 2 + || wmemcmp (wbuf, L"aabcEDX64", 10)) + FAIL (); + + /* These ops need runtime checking, but shouldn't __chk_fail. */ + wmemcpy (wbuf, L"abcdefghij", l0 + 10); + wmemmove (wbuf + 1, wbuf, l0 + 9); + if (wmemcmp (wbuf, L"aabcdefghi", 10)) + FAIL (); + + if (wmempcpy (wbuf + 5, L"abcde", l0 + 5) != wbuf + 10 + || wmemcmp (wbuf, L"aabcdabcde", 10)) + FAIL (); + + wmemset (wbuf + 8, L'j', l0 + 2); + if (wmemcmp (wbuf, L"aabcdabcjj", 10)) + FAIL (); + + wcscpy (wbuf + 4, wstr1 + 5); + if (wmemcmp (wbuf, L"aabcEDCBA", 10)) + FAIL (); + + if (wcpcpy (wbuf + 8, wstr2) != wbuf + 9 || wmemcmp (wbuf, L"aabcEDCBF", 10)) + FAIL (); + + wcsncpy (wbuf + 6, L"X", l0 + 4); + if (wmemcmp (wbuf, L"aabcEDX\0\0", 10)) + FAIL (); + + if (wcpncpy (wbuf + 5, L"cd", l0 + 5) != wbuf + 7 + || wmemcmp (wbuf, L"aabcEcd\0\0", 10)) + FAIL (); + + if (swprintf (wbuf + 7, 3, L"%d", num2) >= 0 + || wmemcmp (wbuf, L"aabcEcd98", 10)) + FAIL (); + + wbuf[l0 + 8] = L'\0'; + wcscat (wbuf, L"A"); + if (wmemcmp (wbuf, L"aabcEcd9A", 10)) + FAIL (); + + wbuf[l0 + 7] = L'\0'; + wcsncat (wbuf, L"ZYXWV", l0 + 2); + if (wmemcmp (wbuf, L"aabcEcdZY", 10)) + FAIL (); + + wmemcpy (wa.buf1, L"abcdefghij", l0 + 10); + wmemmove (wa.buf1 + 1, wa.buf1, l0 + 9); + if (wmemcmp (wa.buf1, L"aabcdefghi", 10)) + FAIL (); + + if (wmempcpy (wa.buf1 + 5, L"abcde", l0 + 5) != wa.buf1 + 10 + || wmemcmp (wa.buf1, L"aabcdabcde", 10)) + FAIL (); + + wmemset (wa.buf1 + 8, L'j', l0 + 2); + if (wmemcmp (wa.buf1, L"aabcdabcjj", 10)) + FAIL (); + +#if __USE_FORTIFY_LEVEL < 2 + /* The following tests are supposed to crash with -D_FORTIFY_SOURCE=2 + and sufficient GCC support, as the string operations overflow + from a.buf1 into a.buf2. */ + wcscpy (wa.buf1 + 4, wstr1 + 5); + if (wmemcmp (wa.buf1, L"aabcEDCBA", 10)) + FAIL (); + + if (wcpcpy (wa.buf1 + 8, wstr2) != wa.buf1 + 9 + || wmemcmp (wa.buf1, L"aabcEDCBF", 10)) + FAIL (); + + wcsncpy (wa.buf1 + 6, L"X", l0 + 4); + if (wmemcmp (wa.buf1, L"aabcEDX\0\0", 10)) + FAIL (); + + if (swprintf (wa.buf1 + 7, 3, L"%d", num2) >= 0 + || wmemcmp (wa.buf1, L"aabcEDX98", 10)) + FAIL (); + + wa.buf1[l0 + 8] = L'\0'; + wcscat (wa.buf1, L"A"); + if (wmemcmp (wa.buf1, L"aabcEDX9A", 10)) + FAIL (); + + wa.buf1[l0 + 7] = L'\0'; + wcsncat (wa.buf1, L"ZYXWV", l0 + 2); + if (wmemcmp (wa.buf1, L"aabcEDXZY", 10)) + FAIL (); + +#endif + +#if __USE_FORTIFY_LEVEL >= 1 + /* Now check if all buffer overflows are caught at runtime. + N.B. All tests involving a length parameter need to be done + twice: once with the length a compile-time constant, once without. */ + + CHK_FAIL_START + wmemcpy (wbuf + 1, L"abcdefghij", 10); + CHK_FAIL_END + + CHK_FAIL_START + wmemcpy (wbuf + 1, L"abcdefghij", l0 + 10); + CHK_FAIL_END + + CHK_FAIL_START + wmemcpy (wbuf + 9, L"abcdefghij", 10); + CHK_FAIL_END + + CHK_FAIL_START + wmemcpy (wbuf + 9, L"abcdefghij", l0 + 10); + CHK_FAIL_END + + CHK_FAIL_START + wmemmove (wbuf + 2, wbuf + 1, 9); + CHK_FAIL_END + + CHK_FAIL_START + wmemmove (wbuf + 2, wbuf + 1, l0 + 9); + CHK_FAIL_END + + CHK_FAIL_START + wp = wmempcpy (wbuf + 6, L"abcde", 5); + CHK_FAIL_END + + CHK_FAIL_START + wp = wmempcpy (wbuf + 6, L"abcde", l0 + 5); + CHK_FAIL_END + + CHK_FAIL_START + wmemset (wbuf + 9, L'j', 2); + CHK_FAIL_END + + CHK_FAIL_START + wmemset (wbuf + 9, L'j', l0 + 2); + CHK_FAIL_END + + CHK_FAIL_START + wcscpy (wbuf + 5, wstr1 + 5); + CHK_FAIL_END + + CHK_FAIL_START + wp = wcpcpy (wbuf + 9, wstr2); + CHK_FAIL_END + + CHK_FAIL_START + wcsncpy (wbuf + 7, L"X", 4); + CHK_FAIL_END + + CHK_FAIL_START + wcsncpy (wbuf + 7, L"X", l0 + 4); + CHK_FAIL_END + + CHK_FAIL_START + wcsncpy (wbuf + 9, L"XABCDEFGH", 8); + CHK_FAIL_END + + CHK_FAIL_START + wcpncpy (wbuf + 9, L"XABCDEFGH", 8); + CHK_FAIL_END + + CHK_FAIL_START + wcpncpy (wbuf + 6, L"cd", 5); + CHK_FAIL_END + + CHK_FAIL_START + wcpncpy (wbuf + 6, L"cd", l0 + 5); + CHK_FAIL_END + + wmemcpy (wbuf, wstr1 + 2, 9); + CHK_FAIL_START + wcscat (wbuf, L"AB"); + CHK_FAIL_END + + wmemcpy (wbuf, wstr1 + 3, 8); + CHK_FAIL_START + wcsncat (wbuf, L"ZYXWV", l0 + 3); + CHK_FAIL_END + + CHK_FAIL_START + wmemcpy (wa.buf1 + 1, L"abcdefghij", 10); + CHK_FAIL_END + + CHK_FAIL_START + wmemcpy (wa.buf1 + 1, L"abcdefghij", l0 + 10); + CHK_FAIL_END + + CHK_FAIL_START + wmemmove (wa.buf1 + 2, wa.buf1 + 1, 9); + CHK_FAIL_END + + CHK_FAIL_START + wmemmove (wa.buf1 + 2, wa.buf1 + 1, l0 + 9); + CHK_FAIL_END + + CHK_FAIL_START + wp = wmempcpy (wa.buf1 + 6, L"abcde", 5); + CHK_FAIL_END + + CHK_FAIL_START + wp = wmempcpy (wa.buf1 + 6, L"abcde", l0 + 5); + CHK_FAIL_END + + CHK_FAIL_START + wmemset (wa.buf1 + 9, L'j', 2); + CHK_FAIL_END + + CHK_FAIL_START + wmemset (wa.buf1 + 9, L'j', l0 + 2); + CHK_FAIL_END + +#if __USE_FORTIFY_LEVEL >= 2 +# define O 0 +#else +# define O 1 +#endif + + CHK_FAIL_START + wcscpy (wa.buf1 + (O + 4), wstr1 + 5); + CHK_FAIL_END + + CHK_FAIL_START + wp = wcpcpy (wa.buf1 + (O + 8), wstr2); + CHK_FAIL_END + + CHK_FAIL_START + wcsncpy (wa.buf1 + (O + 6), L"X", 4); + CHK_FAIL_END + + CHK_FAIL_START + wcsncpy (wa.buf1 + (O + 6), L"X", l0 + 4); + CHK_FAIL_END + + wmemcpy (wa.buf1, wstr1 + (3 - O), 8 + O); + CHK_FAIL_START + wcscat (wa.buf1, L"AB"); + CHK_FAIL_END + + wmemcpy (wa.buf1, wstr1 + (4 - O), 7 + O); + CHK_FAIL_START + wcsncat (wa.buf1, L"ZYXWV", l0 + 3); + CHK_FAIL_END +#endif + + + /* Now checks for %n protection. */ + + /* Constant literals passed directly are always ok + (even with warnings about possible bugs from GCC). */ + int n1, n2; + if (sprintf (buf, "%s%n%s%n", str2, &n1, str2, &n2) != 2 + || n1 != 1 || n2 != 2) + FAIL (); + + /* In this case the format string is not known at compile time, + but resides in read-only memory, so is ok. */ + if (snprintf (buf, 4, str3, str2, &n1, str2, &n2) != 2 + || n1 != 1 || n2 != 2) + FAIL (); + + strcpy (buf2 + 2, "%n%s%n"); + /* When the format string is writable and contains %n, + with -D_FORTIFY_SOURCE=2 it causes __chk_fail. */ + CHK_FAIL2_START + if (sprintf (buf, buf2, str2, &n1, str2, &n1) != 2) + FAIL (); + CHK_FAIL2_END + + CHK_FAIL2_START + if (snprintf (buf, 3, buf2, str2, &n1, str2, &n1) != 2) + FAIL (); + CHK_FAIL2_END + + /* But if there is no %n, even writable format string + should work. */ + buf2[6] = '\0'; + if (sprintf (buf, buf2 + 4, str2) != 1) + FAIL (); + + /* Constant literals passed directly are always ok + (even with warnings about possible bugs from GCC). */ + if (printf ("%s%n%s%n", str4, &n1, str5, &n2) != 14 + || n1 != 7 || n2 != 14) + FAIL (); + + /* In this case the format string is not known at compile time, + but resides in read-only memory, so is ok. */ + if (printf (str3, str4, &n1, str5, &n2) != 14 + || n1 != 7 || n2 != 14) + FAIL (); + + strcpy (buf2 + 2, "%n%s%n"); + /* When the format string is writable and contains %n, + with -D_FORTIFY_SOURCE=2 it causes __chk_fail. */ + CHK_FAIL2_START + if (printf (buf2, str4, &n1, str5, &n1) != 14) + FAIL (); + CHK_FAIL2_END + + /* But if there is no %n, even writable format string + should work. */ + buf2[6] = '\0'; + if (printf (buf2 + 4, str5) != 7) + FAIL (); + + FILE *fp = stdout; + + /* Constant literals passed directly are always ok + (even with warnings about possible bugs from GCC). */ + if (fprintf (fp, "%s%n%s%n", str4, &n1, str5, &n2) != 14 + || n1 != 7 || n2 != 14) + FAIL (); + + /* In this case the format string is not known at compile time, + but resides in read-only memory, so is ok. */ + if (fprintf (fp, str3, str4, &n1, str5, &n2) != 14 + || n1 != 7 || n2 != 14) + FAIL (); + + strcpy (buf2 + 2, "%n%s%n"); + /* When the format string is writable and contains %n, + with -D_FORTIFY_SOURCE=2 it causes __chk_fail. */ + CHK_FAIL2_START + if (fprintf (fp, buf2, str4, &n1, str5, &n1) != 14) + FAIL (); + CHK_FAIL2_END + + /* But if there is no %n, even writable format string + should work. */ + buf2[6] = '\0'; + if (fprintf (fp, buf2 + 4, str5) != 7) + FAIL (); + + char *my_ptr = NULL; + strcpy (buf2 + 2, "%n%s%n"); + /* When the format string is writable and contains %n, + with -D_FORTIFY_SOURCE=2 it causes __chk_fail. */ + CHK_FAIL2_START + if (asprintf (&my_ptr, buf2, str4, &n1, str5, &n1) != 14) + FAIL (); + else + free (my_ptr); + CHK_FAIL2_END + + struct obstack obs; + obstack_init (&obs); + CHK_FAIL2_START + if (obstack_printf (&obs, buf2, str4, &n1, str5, &n1) != 14) + FAIL (); + CHK_FAIL2_END + obstack_free (&obs, NULL); + + my_ptr = NULL; + if (asprintf (&my_ptr, "%s%n%s%n", str4, &n1, str5, &n1) != 14) + FAIL (); + else + free (my_ptr); + + obstack_init (&obs); + if (obstack_printf (&obs, "%s%n%s%n", str4, &n1, str5, &n1) != 14) + FAIL (); + obstack_free (&obs, NULL); + + if (freopen (temp_filename, "r", stdin) == NULL) + { + puts ("could not open temporary file"); + exit (1); + } + + if (gets (buf) != buf || memcmp (buf, "abcdefgh", 9)) + FAIL (); + if (gets (buf) != buf || memcmp (buf, "ABCDEFGHI", 10)) + FAIL (); + +#if __USE_FORTIFY_LEVEL >= 1 + CHK_FAIL_START + if (gets (buf) != buf) + FAIL (); + 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 (); + + rewind (stdin); + + if (fgets (buf, l0 + sizeof (buf), stdin) != buf + || memcmp (buf, "abcdefgh\n", 10)) + FAIL (); + +#if __USE_FORTIFY_LEVEL >= 1 + CHK_FAIL_START + if (fgets (buf, sizeof (buf) + 1, stdin) != buf) + FAIL (); + CHK_FAIL_END + + CHK_FAIL_START + if (fgets (buf, l0 + 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 (); + + rewind (stdin); + + if (fgets_unlocked (buf, l0 + sizeof (buf), stdin) != buf + || memcmp (buf, "abcdefgh\n", 10)) + FAIL (); + +#if __USE_FORTIFY_LEVEL >= 1 + CHK_FAIL_START + if (fgets_unlocked (buf, sizeof (buf) + 1, stdin) != buf) + FAIL (); + CHK_FAIL_END + + CHK_FAIL_START + if (fgets_unlocked (buf, l0 + sizeof (buf) + 1, stdin) != buf) + FAIL (); + CHK_FAIL_END +#endif + + rewind (stdin); + + if (fread (buf, 1, sizeof (buf), stdin) != sizeof (buf) + || memcmp (buf, "abcdefgh\nA", 10)) + FAIL (); + if (fread (buf, sizeof (buf), 1, stdin) != 1 + || memcmp (buf, "BCDEFGHI\na", 10)) + FAIL (); + + rewind (stdin); + + if (fread (buf, l0 + 1, sizeof (buf), stdin) != sizeof (buf) + || memcmp (buf, "abcdefgh\nA", 10)) + FAIL (); + if (fread (buf, sizeof (buf), l0 + 1, stdin) != 1 + || memcmp (buf, "BCDEFGHI\na", 10)) + FAIL (); + +#if __USE_FORTIFY_LEVEL >= 1 + CHK_FAIL_START + if (fread (buf, 1, sizeof (buf) + 1, stdin) != sizeof (buf) + 1) + FAIL (); + CHK_FAIL_END + + CHK_FAIL_START + if (fread (buf, sizeof (buf) + 1, l0 + 1, stdin) != 1) + FAIL (); + CHK_FAIL_END +#endif + + rewind (stdin); + + if (fread_unlocked (buf, 1, sizeof (buf), stdin) != sizeof (buf) + || memcmp (buf, "abcdefgh\nA", 10)) + FAIL (); + if (fread_unlocked (buf, sizeof (buf), 1, stdin) != 1 + || memcmp (buf, "BCDEFGHI\na", 10)) + FAIL (); + + rewind (stdin); + + if (fread_unlocked (buf, 1, 4, stdin) != 4 + || memcmp (buf, "abcdFGHI\na", 10)) + FAIL (); + if (fread_unlocked (buf, 4, 1, stdin) != 1 + || memcmp (buf, "efghFGHI\na", 10)) + FAIL (); + + rewind (stdin); + + if (fread_unlocked (buf, l0 + 1, sizeof (buf), stdin) != sizeof (buf) + || memcmp (buf, "abcdefgh\nA", 10)) + FAIL (); + if (fread_unlocked (buf, sizeof (buf), l0 + 1, stdin) != 1 + || memcmp (buf, "BCDEFGHI\na", 10)) + FAIL (); + +#if __USE_FORTIFY_LEVEL >= 1 + CHK_FAIL_START + if (fread_unlocked (buf, 1, sizeof (buf) + 1, stdin) != sizeof (buf) + 1) + FAIL (); + CHK_FAIL_END + + CHK_FAIL_START + if (fread_unlocked (buf, sizeof (buf) + 1, l0 + 1, stdin) != 1) + 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 (); + + lseek (fileno (stdin), 0, SEEK_SET); + + if (read (fileno (stdin), buf, l0 + sizeof (buf) - 1) != sizeof (buf) - 1 + || memcmp (buf, "abcdefgh\n", 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 + + CHK_FAIL_START + if (read (fileno (stdin), buf, l0 + sizeof (buf) + 1) != sizeof (buf) + 1) + FAIL (); + CHK_FAIL_END +#endif + + if (pread (fileno (stdin), buf, sizeof (buf) - 1, sizeof (buf) - 2) + != sizeof (buf) - 1 + || memcmp (buf, "\nABCDEFGH", 9)) + FAIL (); + if (pread (fileno (stdin), buf, sizeof (buf) - 1, 0) != sizeof (buf) - 1 + || memcmp (buf, "abcdefgh\n", 9)) + FAIL (); + if (pread (fileno (stdin), buf, l0 + sizeof (buf) - 1, sizeof (buf) - 3) + != sizeof (buf) - 1 + || memcmp (buf, "h\nABCDEFG", 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 + + CHK_FAIL_START + if (pread (fileno (stdin), buf, l0 + sizeof (buf) + 1, 2 * sizeof (buf)) + != sizeof (buf) + 1) + FAIL (); + CHK_FAIL_END +#endif + + if (pread64 (fileno (stdin), buf, sizeof (buf) - 1, sizeof (buf) - 2) + != sizeof (buf) - 1 + || memcmp (buf, "\nABCDEFGH", 9)) + FAIL (); + if (pread64 (fileno (stdin), buf, sizeof (buf) - 1, 0) != sizeof (buf) - 1 + || memcmp (buf, "abcdefgh\n", 9)) + FAIL (); + if (pread64 (fileno (stdin), buf, l0 + sizeof (buf) - 1, sizeof (buf) - 3) + != sizeof (buf) - 1 + || memcmp (buf, "h\nABCDEFG", 9)) + FAIL (); + +#if __USE_FORTIFY_LEVEL >= 1 + CHK_FAIL_START + if (pread64 (fileno (stdin), buf, sizeof (buf) + 1, 2 * sizeof (buf)) + != sizeof (buf) + 1) + FAIL (); + CHK_FAIL_END + + CHK_FAIL_START + if (pread64 (fileno (stdin), buf, l0 + sizeof (buf) + 1, 2 * sizeof (buf)) + != sizeof (buf) + 1) + FAIL (); + CHK_FAIL_END +#endif + + if (freopen (temp_filename, "r", stdin) == NULL) + { + puts ("could not open temporary file"); + exit (1); + } + + if (fseek (stdin, 9 + 10 + 11, SEEK_SET)) + { + puts ("could not seek in test file"); + exit (1); + } + +#if __USE_FORTIFY_LEVEL >= 1 + CHK_FAIL_START + if (gets (buf) != buf) + FAIL (); + CHK_FAIL_END +#endif + + /* Check whether missing N$ formats are detected. */ + CHK_FAIL2_START + printf ("%3$d\n", 1, 2, 3, 4); + CHK_FAIL2_END + + CHK_FAIL2_START + fprintf (stdout, "%3$d\n", 1, 2, 3, 4); + CHK_FAIL2_END + + CHK_FAIL2_START + sprintf (buf, "%3$d\n", 1, 2, 3, 4); + CHK_FAIL2_END + + CHK_FAIL2_START + snprintf (buf, sizeof (buf), "%3$d\n", 1, 2, 3, 4); + CHK_FAIL2_END + + int sp[2]; + if (socketpair (PF_UNIX, SOCK_STREAM, 0, sp)) + FAIL (); + else + { + const char *sendstr = "abcdefgh\nABCDEFGH\n0123456789\n"; + if ((size_t) send (sp[0], sendstr, strlen (sendstr), 0) + != strlen (sendstr)) + FAIL (); + + char recvbuf[12]; + if (recv (sp[1], recvbuf, sizeof recvbuf, MSG_PEEK) + != sizeof recvbuf + || memcmp (recvbuf, sendstr, sizeof recvbuf) != 0) + FAIL (); + + if (recv (sp[1], recvbuf + 6, l0 + sizeof recvbuf - 7, MSG_PEEK) + != sizeof recvbuf - 7 + || memcmp (recvbuf + 6, sendstr, sizeof recvbuf - 7) != 0) + FAIL (); + +#if __USE_FORTIFY_LEVEL >= 1 + CHK_FAIL_START + if (recv (sp[1], recvbuf + 1, sizeof recvbuf, MSG_PEEK) + != sizeof recvbuf) + FAIL (); + CHK_FAIL_END + + CHK_FAIL_START + if (recv (sp[1], recvbuf + 4, l0 + sizeof recvbuf - 3, MSG_PEEK) + != sizeof recvbuf - 3) + FAIL (); + CHK_FAIL_END +#endif + + socklen_t sl; + struct sockaddr_un sa_un; + + sl = sizeof (sa_un); + if (recvfrom (sp[1], recvbuf, sizeof recvbuf, MSG_PEEK, + (struct sockaddr *) &sa_un, &sl) + != sizeof recvbuf + || memcmp (recvbuf, sendstr, sizeof recvbuf) != 0) + FAIL (); + + sl = sizeof (sa_un); + if (recvfrom (sp[1], recvbuf + 6, l0 + sizeof recvbuf - 7, MSG_PEEK, + (struct sockaddr *) &sa_un, &sl) != sizeof recvbuf - 7 + || memcmp (recvbuf + 6, sendstr, sizeof recvbuf - 7) != 0) + FAIL (); + +#if __USE_FORTIFY_LEVEL >= 1 + CHK_FAIL_START + sl = sizeof (sa_un); + if (recvfrom (sp[1], recvbuf + 1, sizeof recvbuf, MSG_PEEK, + (struct sockaddr *) &sa_un, &sl) != sizeof recvbuf) + FAIL (); + CHK_FAIL_END + + CHK_FAIL_START + sl = sizeof (sa_un); + if (recvfrom (sp[1], recvbuf + 4, l0 + sizeof recvbuf - 3, MSG_PEEK, + (struct sockaddr *) &sa_un, &sl) != sizeof recvbuf - 3) + FAIL (); + CHK_FAIL_END +#endif + + close (sp[0]); + close (sp[1]); + } + + char fname[] = "/tmp/tst-chk1-dir-XXXXXX\0foo"; + char *enddir = strchr (fname, '\0'); + if (mkdtemp (fname) == NULL) + { + printf ("mkdtemp failed: %m\n"); + return 1; + } + *enddir = '/'; + if (symlink ("bar", fname) != 0) + FAIL (); + + char readlinkbuf[4]; + if (readlink (fname, readlinkbuf, 4) != 3 + || memcmp (readlinkbuf, "bar", 3) != 0) + FAIL (); + if (readlink (fname, readlinkbuf + 1, l0 + 3) != 3 + || memcmp (readlinkbuf, "bbar", 4) != 0) + FAIL (); + +#if __USE_FORTIFY_LEVEL >= 1 + CHK_FAIL_START + if (readlink (fname, readlinkbuf + 2, l0 + 3) != 3) + FAIL (); + CHK_FAIL_END + + CHK_FAIL_START + if (readlink (fname, readlinkbuf + 3, 4) != 3) + FAIL (); + CHK_FAIL_END +#endif + + int tmpfd = open ("/tmp", O_RDONLY | O_DIRECTORY); + if (tmpfd < 0) + FAIL (); + + if (readlinkat (tmpfd, fname + sizeof ("/tmp/") - 1, readlinkbuf, 4) != 3 + || memcmp (readlinkbuf, "bar", 3) != 0) + FAIL (); + if (readlinkat (tmpfd, fname + sizeof ("/tmp/") - 1, readlinkbuf + 1, + l0 + 3) != 3 + || memcmp (readlinkbuf, "bbar", 4) != 0) + FAIL (); + +#if __USE_FORTIFY_LEVEL >= 1 + CHK_FAIL_START + if (readlinkat (tmpfd, fname + sizeof ("/tmp/") - 1, readlinkbuf + 2, + l0 + 3) != 3) + FAIL (); + CHK_FAIL_END + + CHK_FAIL_START + if (readlinkat (tmpfd, fname + sizeof ("/tmp/") - 1, readlinkbuf + 3, + 4) != 3) + FAIL (); + CHK_FAIL_END +#endif + + close (tmpfd); + + char *cwd1 = getcwd (NULL, 0); + if (cwd1 == NULL) + FAIL (); + + char *cwd2 = getcwd (NULL, 250); + if (cwd2 == NULL) + FAIL (); + + if (cwd1 && cwd2) + { + if (strcmp (cwd1, cwd2) != 0) + FAIL (); + + *enddir = '\0'; + if (chdir (fname)) + FAIL (); + + char *cwd3 = getcwd (NULL, 0); + if (cwd3 == NULL) + FAIL (); + if (strcmp (fname, cwd3) != 0) + printf ("getcwd after chdir is '%s' != '%s'," + "get{c,}wd tests skipped\n", cwd3, fname); + else + { + char getcwdbuf[sizeof fname - 3]; + + char *cwd4 = getcwd (getcwdbuf, sizeof getcwdbuf); + if (cwd4 != getcwdbuf + || strcmp (getcwdbuf, fname) != 0) + FAIL (); + + cwd4 = getcwd (getcwdbuf + 1, l0 + sizeof getcwdbuf - 1); + if (cwd4 != getcwdbuf + 1 + || getcwdbuf[0] != fname[0] + || strcmp (getcwdbuf + 1, fname) != 0) + FAIL (); + +#if __USE_FORTIFY_LEVEL >= 1 + CHK_FAIL_START + if (getcwd (getcwdbuf + 2, l0 + sizeof getcwdbuf) + != getcwdbuf + 2) + FAIL (); + CHK_FAIL_END + + CHK_FAIL_START + if (getcwd (getcwdbuf + 2, sizeof getcwdbuf) + != getcwdbuf + 2) + FAIL (); + CHK_FAIL_END +#endif + + if (getwd (getcwdbuf) != getcwdbuf + || strcmp (getcwdbuf, fname) != 0) + FAIL (); + + if (getwd (getcwdbuf + 1) != getcwdbuf + 1 + || strcmp (getcwdbuf + 1, fname) != 0) + FAIL (); + +#if __USE_FORTIFY_LEVEL >= 1 + CHK_FAIL_START + if (getwd (getcwdbuf + 2) != getcwdbuf + 2) + FAIL (); + CHK_FAIL_END +#endif + } + + if (chdir (cwd1) != 0) + FAIL (); + free (cwd3); + } + + free (cwd1); + free (cwd2); + *enddir = '/'; + if (unlink (fname) != 0) + FAIL (); + + *enddir = '\0'; + if (rmdir (fname) != 0) + FAIL (); + + +#if PATH_MAX > 0 + char largebuf[PATH_MAX]; + char *realres = realpath (".", largebuf); + if (realres != largebuf) + FAIL (); + +# if __USE_FORTIFY_LEVEL >= 1 + CHK_FAIL_START + char realbuf[1]; + realres = realpath (".", realbuf); + if (realres != realbuf) + FAIL (); + CHK_FAIL_END +# endif +#endif + + if (setlocale (LC_ALL, "de_DE.UTF-8") != NULL) + { + assert (MB_CUR_MAX <= 10); + + /* First a simple test. */ + char enough[10]; + if (wctomb (enough, L'A') != 1) + FAIL (); + +#if __USE_FORTIFY_LEVEL >= 1 + /* We know the wchar_t encoding is ISO 10646. So pick a + character which has a multibyte representation which does not + fit. */ + CHK_FAIL_START + char smallbuf[2]; + if (wctomb (smallbuf, L'\x100') != 2) + FAIL (); + CHK_FAIL_END +#endif + + mbstate_t s; + memset (&s, '\0', sizeof (s)); + if (wcrtomb (enough, L'D', &s) != 1 || enough[0] != 'D') + FAIL (); + +#if __USE_FORTIFY_LEVEL >= 1 + /* We know the wchar_t encoding is ISO 10646. So pick a + character which has a multibyte representation which does not + fit. */ + CHK_FAIL_START + char smallbuf[2]; + if (wcrtomb (smallbuf, L'\x100', &s) != 2) + FAIL (); + CHK_FAIL_END +#endif + + wchar_t wenough[10]; + memset (&s, '\0', sizeof (s)); + const char *cp = "A"; + if (mbsrtowcs (wenough, &cp, 10, &s) != 1 + || wcscmp (wenough, L"A") != 0) + FAIL (); + + cp = "BC"; + if (mbsrtowcs (wenough, &cp, l0 + 10, &s) != 2 + || wcscmp (wenough, L"BC") != 0) + FAIL (); + +#if __USE_FORTIFY_LEVEL >= 1 + CHK_FAIL_START + wchar_t wsmallbuf[2]; + cp = "ABC"; + mbsrtowcs (wsmallbuf, &cp, 10, &s); + CHK_FAIL_END +#endif + + cp = "A"; + if (mbstowcs (wenough, cp, 10) != 1 + || wcscmp (wenough, L"A") != 0) + FAIL (); + + cp = "DEF"; + if (mbstowcs (wenough, cp, l0 + 10) != 3 + || wcscmp (wenough, L"DEF") != 0) + FAIL (); + +#if __USE_FORTIFY_LEVEL >= 1 + CHK_FAIL_START + wchar_t wsmallbuf[2]; + cp = "ABC"; + mbstowcs (wsmallbuf, cp, 10); + CHK_FAIL_END +#endif + + memset (&s, '\0', sizeof (s)); + cp = "ABC"; + wcscpy (wenough, L"DEF"); + if (mbsnrtowcs (wenough, &cp, 1, 10, &s) != 1 + || wcscmp (wenough, L"AEF") != 0) + FAIL (); + + cp = "IJ"; + if (mbsnrtowcs (wenough, &cp, 1, l0 + 10, &s) != 1 + || wcscmp (wenough, L"IEF") != 0) + FAIL (); + +#if __USE_FORTIFY_LEVEL >= 1 + CHK_FAIL_START + wchar_t wsmallbuf[2]; + cp = "ABC"; + mbsnrtowcs (wsmallbuf, &cp, 3, 10, &s); + CHK_FAIL_END +#endif + + memset (&s, '\0', sizeof (s)); + const wchar_t *wcp = L"A"; + if (wcsrtombs (enough, &wcp, 10, &s) != 1 + || strcmp (enough, "A") != 0) + FAIL (); + + wcp = L"BC"; + if (wcsrtombs (enough, &wcp, l0 + 10, &s) != 2 + || strcmp (enough, "BC") != 0) + FAIL (); + +#if __USE_FORTIFY_LEVEL >= 1 + CHK_FAIL_START + char smallbuf[2]; + wcp = L"ABC"; + wcsrtombs (smallbuf, &wcp, 10, &s); + CHK_FAIL_END +#endif + + memset (enough, 'Z', sizeof (enough)); + wcp = L"EF"; + if (wcstombs (enough, wcp, 10) != 2 + || strcmp (enough, "EF") != 0) + FAIL (); + + wcp = L"G"; + if (wcstombs (enough, wcp, l0 + 10) != 1 + || strcmp (enough, "G") != 0) + FAIL (); + +#if __USE_FORTIFY_LEVEL >= 1 + CHK_FAIL_START + char smallbuf[2]; + wcp = L"ABC"; + wcstombs (smallbuf, wcp, 10); + CHK_FAIL_END +#endif + + memset (&s, '\0', sizeof (s)); + wcp = L"AB"; + if (wcsnrtombs (enough, &wcp, 1, 10, &s) != 1 + || strcmp (enough, "A") != 0) + FAIL (); + + wcp = L"BCD"; + if (wcsnrtombs (enough, &wcp, 1, l0 + 10, &s) != 1 + || strcmp (enough, "B") != 0) + FAIL (); + +#if __USE_FORTIFY_LEVEL >= 1 + CHK_FAIL_START + char smallbuf[2]; + wcp = L"ABC"; + wcsnrtombs (smallbuf, &wcp, 3, 10, &s); + CHK_FAIL_END +#endif + } + else + { + puts ("cannot set locale"); + ret = 1; + } + + int fd = posix_openpt (O_RDWR); + if (fd != -1) + { + char enough[1000]; + if (ptsname_r (fd, enough, sizeof (enough)) != 0) + FAIL (); + +#if __USE_FORTIFY_LEVEL >= 1 + CHK_FAIL_START + char smallbuf[2]; + if (ptsname_r (fd, smallbuf, sizeof (smallbuf) + 1) == 0) + FAIL (); + CHK_FAIL_END +#endif + close (fd); + } + +#if PATH_MAX > 0 + confstr (_CS_GNU_LIBC_VERSION, largebuf, sizeof (largebuf)); +# if __USE_FORTIFY_LEVEL >= 1 + CHK_FAIL_START + char smallbuf[1]; + confstr (_CS_GNU_LIBC_VERSION, smallbuf, sizeof (largebuf)); + CHK_FAIL_END +# endif +#endif + + gid_t grpslarge[5]; + int ngr = getgroups (5, grpslarge); + asm volatile ("" : : "r" (ngr)); +#if __USE_FORTIFY_LEVEL >= 1 + CHK_FAIL_START + char smallbuf[1]; + ngr = getgroups (5, (gid_t *) smallbuf); + asm volatile ("" : : "r" (ngr)); + CHK_FAIL_END +#endif + + fd = open (_PATH_TTY, O_RDONLY); + if (fd != -1) + { + char enough[1000]; + if (ttyname_r (fd, enough, sizeof (enough)) != 0) + FAIL (); + +#if __USE_FORTIFY_LEVEL >= 1 + CHK_FAIL_START + char smallbuf[2]; + if (ttyname_r (fd, smallbuf, sizeof (smallbuf) + 1) == 0) + FAIL (); + CHK_FAIL_END +#endif + close (fd); + } + + char hostnamelarge[1000]; + gethostname (hostnamelarge, sizeof (hostnamelarge)); +#if __USE_FORTIFY_LEVEL >= 1 + CHK_FAIL_START + char smallbuf[1]; + gethostname (smallbuf, sizeof (hostnamelarge)); + CHK_FAIL_END +#endif + + char loginlarge[1000]; + getlogin_r (loginlarge, sizeof (hostnamelarge)); +#if __USE_FORTIFY_LEVEL >= 1 + CHK_FAIL_START + char smallbuf[1]; + getlogin_r (smallbuf, sizeof (loginlarge)); + CHK_FAIL_END +#endif + + char domainnamelarge[1000]; + int res = getdomainname (domainnamelarge, sizeof (domainnamelarge)); + asm volatile ("" : : "r" (res)); +#if __USE_FORTIFY_LEVEL >= 1 + CHK_FAIL_START + char smallbuf[1]; + res = getdomainname (smallbuf, sizeof (domainnamelarge)); + asm volatile ("" : : "r" (res)); + CHK_FAIL_END +#endif + + fd_set s; + FD_ZERO (&s); + + FD_SET (FD_SETSIZE - 1, &s); +#if __USE_FORTIFY_LEVEL >= 1 + CHK_FAIL_START + FD_SET (FD_SETSIZE, &s); + CHK_FAIL_END + + CHK_FAIL_START + FD_SET (l0 + FD_SETSIZE, &s); + CHK_FAIL_END +#endif + + FD_CLR (FD_SETSIZE - 1, &s); +#if __USE_FORTIFY_LEVEL >= 1 + CHK_FAIL_START + FD_CLR (FD_SETSIZE, &s); + CHK_FAIL_END + + CHK_FAIL_START + FD_SET (l0 + FD_SETSIZE, &s); + CHK_FAIL_END +#endif + + FD_ISSET (FD_SETSIZE - 1, &s); +#if __USE_FORTIFY_LEVEL >= 1 + CHK_FAIL_START + FD_ISSET (FD_SETSIZE, &s); + CHK_FAIL_END + + CHK_FAIL_START + FD_ISSET (l0 + FD_SETSIZE, &s); + CHK_FAIL_END +#endif + + struct pollfd fds[1]; + fds[0].fd = STDOUT_FILENO; + fds[0].events = POLLOUT; + poll (fds, 1, 0); +#if __USE_FORTIFY_LEVEL >= 1 + CHK_FAIL_START + poll (fds, 2, 0); + CHK_FAIL_END + + CHK_FAIL_START + poll (fds, l0 + 2, 0); + CHK_FAIL_END +#endif + ppoll (fds, 1, NULL, NULL); +#if __USE_FORTIFY_LEVEL >= 1 + CHK_FAIL_START + ppoll (fds, 2, NULL, NULL); + CHK_FAIL_END + + CHK_FAIL_START + ppoll (fds, l0 + 2, NULL, NULL); + CHK_FAIL_END +#endif + + return ret; +} diff --git a/REORG.TODO/debug/tst-chk2.c b/REORG.TODO/debug/tst-chk2.c new file mode 100644 index 0000000000..be37ce2d22 --- /dev/null +++ b/REORG.TODO/debug/tst-chk2.c @@ -0,0 +1,2 @@ +#define _FORTIFY_SOURCE 1 +#include "tst-chk1.c" diff --git a/REORG.TODO/debug/tst-chk3.c b/REORG.TODO/debug/tst-chk3.c new file mode 100644 index 0000000000..38b8e4fb36 --- /dev/null +++ b/REORG.TODO/debug/tst-chk3.c @@ -0,0 +1,2 @@ +#define _FORTIFY_SOURCE 2 +#include "tst-chk1.c" diff --git a/REORG.TODO/debug/tst-chk4.cc b/REORG.TODO/debug/tst-chk4.cc new file mode 100644 index 0000000000..c82e6aac86 --- /dev/null +++ b/REORG.TODO/debug/tst-chk4.cc @@ -0,0 +1 @@ +#include "tst-chk1.c" diff --git a/REORG.TODO/debug/tst-chk5.cc b/REORG.TODO/debug/tst-chk5.cc new file mode 100644 index 0000000000..be37ce2d22 --- /dev/null +++ b/REORG.TODO/debug/tst-chk5.cc @@ -0,0 +1,2 @@ +#define _FORTIFY_SOURCE 1 +#include "tst-chk1.c" diff --git a/REORG.TODO/debug/tst-chk6.cc b/REORG.TODO/debug/tst-chk6.cc new file mode 100644 index 0000000000..38b8e4fb36 --- /dev/null +++ b/REORG.TODO/debug/tst-chk6.cc @@ -0,0 +1,2 @@ +#define _FORTIFY_SOURCE 2 +#include "tst-chk1.c" diff --git a/REORG.TODO/debug/tst-lfschk1.c b/REORG.TODO/debug/tst-lfschk1.c new file mode 100644 index 0000000000..f3e6d47d5e --- /dev/null +++ b/REORG.TODO/debug/tst-lfschk1.c @@ -0,0 +1,2 @@ +#define _FILE_OFFSET_BITS 64 +#include "tst-chk1.c" diff --git a/REORG.TODO/debug/tst-lfschk2.c b/REORG.TODO/debug/tst-lfschk2.c new file mode 100644 index 0000000000..95d4db1d32 --- /dev/null +++ b/REORG.TODO/debug/tst-lfschk2.c @@ -0,0 +1,2 @@ +#define _FILE_OFFSET_BITS 64 +#include "tst-chk2.c" diff --git a/REORG.TODO/debug/tst-lfschk3.c b/REORG.TODO/debug/tst-lfschk3.c new file mode 100644 index 0000000000..50a1ae1258 --- /dev/null +++ b/REORG.TODO/debug/tst-lfschk3.c @@ -0,0 +1,2 @@ +#define _FILE_OFFSET_BITS 64 +#include "tst-chk3.c" diff --git a/REORG.TODO/debug/tst-lfschk4.cc b/REORG.TODO/debug/tst-lfschk4.cc new file mode 100644 index 0000000000..f3e6d47d5e --- /dev/null +++ b/REORG.TODO/debug/tst-lfschk4.cc @@ -0,0 +1,2 @@ +#define _FILE_OFFSET_BITS 64 +#include "tst-chk1.c" diff --git a/REORG.TODO/debug/tst-lfschk5.cc b/REORG.TODO/debug/tst-lfschk5.cc new file mode 100644 index 0000000000..95d4db1d32 --- /dev/null +++ b/REORG.TODO/debug/tst-lfschk5.cc @@ -0,0 +1,2 @@ +#define _FILE_OFFSET_BITS 64 +#include "tst-chk2.c" diff --git a/REORG.TODO/debug/tst-lfschk6.cc b/REORG.TODO/debug/tst-lfschk6.cc new file mode 100644 index 0000000000..50a1ae1258 --- /dev/null +++ b/REORG.TODO/debug/tst-lfschk6.cc @@ -0,0 +1,2 @@ +#define _FILE_OFFSET_BITS 64 +#include "tst-chk3.c" diff --git a/REORG.TODO/debug/tst-longjmp_chk.c b/REORG.TODO/debug/tst-longjmp_chk.c new file mode 100644 index 0000000000..e4e93d2a36 --- /dev/null +++ b/REORG.TODO/debug/tst-longjmp_chk.c @@ -0,0 +1,78 @@ +/* Basic test to make sure doing a longjmp to a jmpbuf with an invalid sp + is caught by the fortification code. */ +#include <errno.h> +#include <fcntl.h> +#include <paths.h> +#include <setjmp.h> +#include <signal.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + + +static int do_test(void); +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" + + +static jmp_buf b; + + +static void +__attribute__ ((noinline)) +f (void) +{ + char buf[1000]; + asm volatile ("" : "=m" (buf)); + + if (setjmp (b) != 0) + { + puts ("second longjmp succeeded"); + exit (1); + } +} + + +static bool expected_to_fail; + + +static void +handler (int sig) +{ + if (expected_to_fail) + _exit (0); + else + { + static const char msg[] = "unexpected longjmp failure\n"; + TEMP_FAILURE_RETRY (write (STDOUT_FILENO, msg, sizeof (msg) - 1)); + _exit (1); + } +} + + +static int +do_test (void) +{ + set_fortify_handler (handler); + + + expected_to_fail = false; + + if (setjmp (b) == 0) + { + longjmp (b, 1); + /* NOTREACHED */ + printf ("first longjmp returned\n"); + return 1; + } + + + expected_to_fail = true; + + f (); + longjmp (b, 1); + + puts ("second longjmp returned"); + return 1; +} diff --git a/REORG.TODO/debug/tst-longjmp_chk2.c b/REORG.TODO/debug/tst-longjmp_chk2.c new file mode 100644 index 0000000000..23d3436d1d --- /dev/null +++ b/REORG.TODO/debug/tst-longjmp_chk2.c @@ -0,0 +1,130 @@ +/* Verify longjmp fortify checking does not reject signal stacks. + + Test case mostly written by Paolo Bonzini <pbonzini@redhat.com>. */ +#include <assert.h> +#include <setjmp.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <sys/time.h> +#include <sys/resource.h> +#include <unistd.h> + +static int do_test (void); +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" + +static jmp_buf mainloop; +static sigset_t mainsigset; +static volatile sig_atomic_t pass; + +static void +write_indented (const char *str) +{ + for (int i = 0; i < pass; ++i) + write_message (" "); + write_message (str); +} + +static void +stackoverflow_handler (int sig) +{ + stack_t altstack; + /* Sanity check to keep test from looping forever (in case the longjmp + chk code is slightly broken). */ + pass++; + sigaltstack (NULL, &altstack); + write_indented ("in signal handler\n"); + if (altstack.ss_flags & SS_ONSTACK) + write_indented ("on alternate stack\n"); + siglongjmp (mainloop, pass); +} + + +static volatile int * +recurse_1 (int n, volatile int *p) +{ + if (n >= 0) + *recurse_1 (n + 1, p) += n; + return p; +} + + +static int +recurse (int n) +{ + int sum = 0; + return *recurse_1 (n, &sum); +} + + +static int +do_test (void) +{ + char mystack[SIGSTKSZ]; + stack_t altstack; + struct sigaction action; + sigset_t emptyset; + /* Before starting the endless recursion, try to be friendly to the user's + machine. On some Linux 2.2.x systems, there is no stack limit for user + processes at all. We don't want to kill such systems. */ + struct rlimit rl; + rl.rlim_cur = rl.rlim_max = 0x100000; /* 1 MB */ + setrlimit (RLIMIT_STACK, &rl); + /* Install the alternate stack. */ + altstack.ss_sp = mystack; + altstack.ss_size = sizeof (mystack); + altstack.ss_flags = 0; /* no SS_DISABLE */ + if (sigaltstack (&altstack, NULL) < 0) + { + puts ("first sigaltstack failed"); + return 0; + } + /* Install the SIGSEGV handler. */ + sigemptyset (&action.sa_mask); + action.sa_handler = &stackoverflow_handler; + action.sa_flags = SA_ONSTACK; + sigaction (SIGSEGV, &action, (struct sigaction *) NULL); + sigaction (SIGBUS, &action, (struct sigaction *) NULL); + + /* Save the current signal mask. */ + sigemptyset (&emptyset); + sigprocmask (SIG_BLOCK, &emptyset, &mainsigset); + + /* Provoke two stack overflows in a row. */ + if (sigsetjmp (mainloop, 1) != 0) + { + assert (pass != 0); + printf ("%*sout of signal handler\n", pass, ""); + } + else + assert (pass == 0); + + sigaltstack (NULL, &altstack); + if (altstack.ss_flags & SS_ONSTACK) + printf ("%*son alternate stack\n", pass, ""); + else + printf ("%*snot on alternate stack\n", pass, ""); + + if (pass < 2) + { + recurse (0); + puts ("recurse call returned"); + return 2; + } + + altstack.ss_flags |= SS_DISABLE; + if (sigaltstack (&altstack, NULL) == -1) + printf ("disabling alternate stack failed\n"); + else + printf ("disabling alternate stack succeeded \n"); + + /* Restore the signal handlers, in case we trigger a crash after the + tests above. */ + signal (SIGBUS, SIG_DFL); + signal (SIGSEGV, SIG_DFL); + + return 0; +} diff --git a/REORG.TODO/debug/tst-longjmp_chk3.c b/REORG.TODO/debug/tst-longjmp_chk3.c new file mode 100644 index 0000000000..12b367b970 --- /dev/null +++ b/REORG.TODO/debug/tst-longjmp_chk3.c @@ -0,0 +1,85 @@ +/* Make sure longjmp fortification catches bad signal stacks. + Copyright (C) 2013-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <setjmp.h> +#include <signal.h> +#include <string.h> + +static int do_test (void); +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" + +static char buf[SIGSTKSZ * 4]; +static jmp_buf jb; + +static void +handler (int sig) +{ + if (sig == SIGUSR1) + { + if (setjmp (jb) != 0) + { + puts ("setjmp should not have been called"); + kill (getpid (), SIGTERM); + } + } + else if (sig == SIGABRT) + { + /* Yeah it worked. */ + _exit (0); + } +} + +static int +do_test (void) +{ + stack_t ss; + + set_fortify_handler (handler); + + /* Create a valid signal stack and enable it. */ + ss.ss_sp = buf; + ss.ss_size = sizeof (buf); + ss.ss_flags = 0; + if (sigaltstack (&ss, NULL) < 0) + { + printf ("first sigaltstack failed: %m\n"); + return 1; + } + + /* Trigger the signal handler which will create a jmpbuf that points to the + end of the signal stack. */ + signal (SIGUSR1, handler); + kill (getpid (), SIGUSR1); + + /* Shrink the signal stack so the jmpbuf is now invalid. + We adjust the start & end to handle stacks that grow up & down. */ + ss.ss_sp = buf + sizeof (buf) / 2; + ss.ss_size = sizeof (buf) / 4; + if (sigaltstack (&ss, NULL) < 0) + { + printf ("second sigaltstack failed: %m\n"); + return 1; + } + + /* This should fail. */ + longjmp (jb, 1); + + puts ("longjmp returned and shouldn't"); + return 1; +} diff --git a/REORG.TODO/debug/ttyname_r_chk.c b/REORG.TODO/debug/ttyname_r_chk.c new file mode 100644 index 0000000000..5e74df811a --- /dev/null +++ b/REORG.TODO/debug/ttyname_r_chk.c @@ -0,0 +1,28 @@ +/* Copyright (C) 2005-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <unistd.h> + + +int +__ttyname_r_chk (int fd, char *buf, size_t buflen, size_t nreal) +{ + if (buflen > nreal) + __chk_fail (); + + return __ttyname_r (fd, buf, buflen); +} diff --git a/REORG.TODO/debug/vasprintf_chk.c b/REORG.TODO/debug/vasprintf_chk.c new file mode 100644 index 0000000000..5ebfeed239 --- /dev/null +++ b/REORG.TODO/debug/vasprintf_chk.c @@ -0,0 +1,95 @@ +/* Copyright (C) 1995-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + 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 <malloc.h> +#include <string.h> +#include <stdio.h> +#include <stdio_ext.h> +#include "../libio/libioP.h" +#include "../libio/strfile.h" + +int +__vasprintf_chk (char **result_ptr, int flags, const char *format, + va_list args) +{ + /* Initial size of the buffer to be used. Will be doubled each time an + overflow occurs. */ + const _IO_size_t init_string_size = 100; + char *string; + _IO_strfile sf; + int ret; + _IO_size_t needed; + _IO_size_t allocated; + /* No need to clear the memory here (unlike for open_memstream) since + we know we will never seek on the stream. */ + string = (char *) malloc (init_string_size); + if (string == NULL) + return -1; +#ifdef _IO_MTSAFE_IO + sf._sbf._f._lock = NULL; +#endif + _IO_no_init (&sf._sbf._f, _IO_USER_LOCK, -1, NULL, NULL); + _IO_JUMPS (&sf._sbf) = &_IO_str_jumps; + _IO_str_init_static_internal (&sf, string, init_string_size, string); + sf._sbf._f._flags &= ~_IO_USER_BUF; + sf._s._allocate_buffer = (_IO_alloc_type) malloc; + sf._s._free_buffer = (_IO_free_type) free; + + /* For flags > 0 (i.e. __USE_FORTIFY_LEVEL > 1) request that %n + can only come from read-only format strings. */ + if (flags > 0) + sf._sbf._f._flags2 |= _IO_FLAGS2_FORTIFY; + + ret = _IO_vfprintf (&sf._sbf._f, format, args); + if (ret < 0) + { + free (sf._sbf._f._IO_buf_base); + return ret; + } + /* Only use realloc if the size we need is of the same (binary) + order of magnitude then the memory we allocated. */ + needed = sf._sbf._f._IO_write_ptr - sf._sbf._f._IO_write_base + 1; + allocated = sf._sbf._f._IO_write_end - sf._sbf._f._IO_write_base; + if ((allocated >> 1) <= needed) + *result_ptr = (char *) realloc (sf._sbf._f._IO_buf_base, needed); + else + { + *result_ptr = (char *) malloc (needed); + if (*result_ptr != NULL) + { + memcpy (*result_ptr, sf._sbf._f._IO_buf_base, needed - 1); + free (sf._sbf._f._IO_buf_base); + } + else + /* We have no choice, use the buffer we already have. */ + *result_ptr = (char *) realloc (sf._sbf._f._IO_buf_base, needed); + } + if (*result_ptr == NULL) + *result_ptr = sf._sbf._f._IO_buf_base; + (*result_ptr)[needed - 1] = '\0'; + return ret; +} +libc_hidden_def (__vasprintf_chk) diff --git a/REORG.TODO/debug/vdprintf_chk.c b/REORG.TODO/debug/vdprintf_chk.c new file mode 100644 index 0000000000..1bbeedb02e --- /dev/null +++ b/REORG.TODO/debug/vdprintf_chk.c @@ -0,0 +1,67 @@ +/* Copyright (C) 1995-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + 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_ext.h> + +int +__vdprintf_chk (int d, int flags, const char *format, va_list arg) +{ + struct _IO_FILE_plus tmpfil; + struct _IO_wide_data wd; + int done; + +#ifdef _IO_MTSAFE_IO + tmpfil.file._lock = NULL; +#endif + _IO_no_init (&tmpfil.file, _IO_USER_LOCK, 0, &wd, &_IO_wfile_jumps); + _IO_JUMPS (&tmpfil) = &_IO_file_jumps; + _IO_new_file_init_internal (&tmpfil); +#if !_IO_UNIFIED_JUMPTABLES + tmpfil.vtable = NULL; +#endif + if (_IO_file_attach (&tmpfil.file, d) == NULL) + { + _IO_un_link (&tmpfil); + return EOF; + } + tmpfil.file._flags |= _IO_DELETE_DONT_CLOSE; + + _IO_mask_flags (&tmpfil.file, _IO_NO_READS, + _IO_NO_READS+_IO_NO_WRITES+_IO_IS_APPENDING); + + /* For flags > 0 (i.e. __USE_FORTIFY_LEVEL > 1) request that %n + can only come from read-only format strings. */ + if (flags > 0) + tmpfil.file._flags2 |= _IO_FLAGS2_FORTIFY; + + done = _IO_vfprintf (&tmpfil.file, format, arg); + + _IO_FINISH (&tmpfil.file); + + return done; +} +libc_hidden_def (__vdprintf_chk) diff --git a/REORG.TODO/debug/vfprintf_chk.c b/REORG.TODO/debug/vfprintf_chk.c new file mode 100644 index 0000000000..6916a816a1 --- /dev/null +++ b/REORG.TODO/debug/vfprintf_chk.c @@ -0,0 +1,42 @@ +/* Copyright (C) 1991-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <stdarg.h> +#include <stdio.h> +#include "../libio/libioP.h" + + +/* Write formatted output to FP from the format string FORMAT. */ +int +___vfprintf_chk (FILE *fp, int flag, const char *format, va_list ap) +{ + int done; + + _IO_acquire_lock_clear_flags2 (fp); + if (flag > 0) + fp->_flags2 |= _IO_FLAGS2_FORTIFY; + + done = vfprintf (fp, format, ap); + + if (flag > 0) + fp->_flags2 &= ~_IO_FLAGS2_FORTIFY; + _IO_release_lock (fp); + + return done; +} +ldbl_hidden_def (___vfprintf_chk, __vfprintf_chk) +ldbl_strong_alias (___vfprintf_chk, __vfprintf_chk) diff --git a/REORG.TODO/debug/vfwprintf_chk.c b/REORG.TODO/debug/vfwprintf_chk.c new file mode 100644 index 0000000000..4f05b3303b --- /dev/null +++ b/REORG.TODO/debug/vfwprintf_chk.c @@ -0,0 +1,41 @@ +/* Copyright (C) 1991-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <stdarg.h> +#include <wchar.h> +#include "../libio/libioP.h" + + +/* Write formatted output to FP from the format string FORMAT. */ +int +__vfwprintf_chk (FILE *fp, int flag, const wchar_t *format, va_list ap) +{ + int done; + + _IO_acquire_lock_clear_flags2 (fp); + if (flag > 0) + fp->_flags2 |= _IO_FLAGS2_FORTIFY; + + done = _IO_vfwprintf (fp, format, ap); + + if (flag > 0) + fp->_flags2 &= ~_IO_FLAGS2_FORTIFY; + _IO_release_lock (fp); + + return done; +} +libc_hidden_def (__vfwprintf_chk) diff --git a/REORG.TODO/debug/vprintf_chk.c b/REORG.TODO/debug/vprintf_chk.c new file mode 100644 index 0000000000..d28a0f1db3 --- /dev/null +++ b/REORG.TODO/debug/vprintf_chk.c @@ -0,0 +1,41 @@ +/* Copyright (C) 1991-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <stdarg.h> +#include <stdio.h> +#include "../libio/libioP.h" + + +/* Write formatted output to stdout from the format string FORMAT. */ +int +___vprintf_chk (int flag, const char *format, va_list ap) +{ + int done; + + _IO_acquire_lock_clear_flags2 (stdout); + if (flag > 0) + stdout->_flags2 |= _IO_FLAGS2_FORTIFY; + + done = vfprintf (stdout, format, ap); + + if (flag > 0) + stdout->_flags2 &= ~_IO_FLAGS2_FORTIFY; + _IO_release_lock (stdout); + + return done; +} +ldbl_strong_alias (___vprintf_chk, __vprintf_chk) diff --git a/REORG.TODO/debug/vsnprintf_chk.c b/REORG.TODO/debug/vsnprintf_chk.c new file mode 100644 index 0000000000..ff911e33bb --- /dev/null +++ b/REORG.TODO/debug/vsnprintf_chk.c @@ -0,0 +1,70 @@ +/* Copyright (C) 1991-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <stdarg.h> +#include <stdio.h> +#include "../libio/libioP.h" +#include "../libio/strfile.h" + +extern const struct _IO_jump_t _IO_strn_jumps libio_vtable attribute_hidden; + +/* Write formatted output into S, according to the format + string FORMAT, writing no more than MAXLEN characters. */ +/* VARARGS5 */ +int +___vsnprintf_chk (char *s, size_t maxlen, int flags, size_t slen, + const char *format, va_list args) +{ + /* XXX Maybe for less strict version do not fail immediately. + Though, maxlen is supposed to be the size of buffer pointed + to by s, so a conforming program can't pass such maxlen + to *snprintf. */ + if (__glibc_unlikely (slen < maxlen)) + __chk_fail (); + + _IO_strnfile sf; + int ret; +#ifdef _IO_MTSAFE_IO + sf.f._sbf._f._lock = NULL; +#endif + + /* We need to handle the special case where MAXLEN is 0. Use the + overflow buffer right from the start. */ + if (maxlen == 0) + { + s = sf.overflow_buf; + maxlen = sizeof (sf.overflow_buf); + } + + _IO_no_init (&sf.f._sbf._f, _IO_USER_LOCK, -1, NULL, NULL); + _IO_JUMPS (&sf.f._sbf) = &_IO_strn_jumps; + s[0] = '\0'; + + /* For flags > 0 (i.e. __USE_FORTIFY_LEVEL > 1) request that %n + can only come from read-only format strings. */ + if (flags > 0) + sf.f._sbf._f._flags2 |= _IO_FLAGS2_FORTIFY; + + _IO_str_init_static_internal (&sf.f, s, maxlen - 1, s); + ret = _IO_vfprintf (&sf.f._sbf._f, format, args); + + if (sf.f._sbf._f._IO_buf_base != sf.overflow_buf) + *sf.f._sbf._f._IO_write_ptr = '\0'; + return ret; +} +ldbl_hidden_def (___vsnprintf_chk, __vsnprintf_chk) +ldbl_strong_alias (___vsnprintf_chk, __vsnprintf_chk) diff --git a/REORG.TODO/debug/vsprintf_chk.c b/REORG.TODO/debug/vsprintf_chk.c new file mode 100644 index 0000000000..d47bdaefef --- /dev/null +++ b/REORG.TODO/debug/vsprintf_chk.c @@ -0,0 +1,89 @@ +/* Copyright (C) 1994-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <stdarg.h> +#include <stdio.h> +#include "../libio/libioP.h" +#include "../libio/strfile.h" + + +static int _IO_str_chk_overflow (_IO_FILE *fp, int c) __THROW; + +static int +_IO_str_chk_overflow (_IO_FILE *fp, int c) +{ + /* When we come to here this means the user supplied buffer is + filled. */ + __chk_fail (); +} + + +static const struct _IO_jump_t _IO_str_chk_jumps libio_vtable = +{ + JUMP_INIT_DUMMY, + JUMP_INIT(finish, _IO_str_finish), + JUMP_INIT(overflow, _IO_str_chk_overflow), + JUMP_INIT(underflow, _IO_str_underflow), + JUMP_INIT(uflow, _IO_default_uflow), + JUMP_INIT(pbackfail, _IO_str_pbackfail), + JUMP_INIT(xsputn, _IO_default_xsputn), + JUMP_INIT(xsgetn, _IO_default_xsgetn), + JUMP_INIT(seekoff, _IO_str_seekoff), + JUMP_INIT(seekpos, _IO_default_seekpos), + JUMP_INIT(setbuf, _IO_default_setbuf), + JUMP_INIT(sync, _IO_default_sync), + JUMP_INIT(doallocate, _IO_default_doallocate), + JUMP_INIT(read, _IO_default_read), + JUMP_INIT(write, _IO_default_write), + JUMP_INIT(seek, _IO_default_seek), + JUMP_INIT(close, _IO_default_close), + JUMP_INIT(stat, _IO_default_stat), + JUMP_INIT(showmanyc, _IO_default_showmanyc), + JUMP_INIT(imbue, _IO_default_imbue) +}; + + +int +___vsprintf_chk (char *s, int flags, size_t slen, const char *format, + va_list args) +{ + _IO_strfile f; + int ret; +#ifdef _IO_MTSAFE_IO + f._sbf._f._lock = NULL; +#endif + + if (slen == 0) + __chk_fail (); + + _IO_no_init (&f._sbf._f, _IO_USER_LOCK, -1, NULL, NULL); + _IO_JUMPS (&f._sbf) = &_IO_str_chk_jumps; + s[0] = '\0'; + _IO_str_init_static_internal (&f, s, slen - 1, s); + + /* For flags > 0 (i.e. __USE_FORTIFY_LEVEL > 1) request that %n + can only come from read-only format strings. */ + if (flags > 0) + f._sbf._f._flags2 |= _IO_FLAGS2_FORTIFY; + + ret = _IO_vfprintf (&f._sbf._f, format, args); + + *f._sbf._f._IO_write_ptr = '\0'; + return ret; +} +ldbl_hidden_def (___vsprintf_chk, __vsprintf_chk) +ldbl_strong_alias (___vsprintf_chk, __vsprintf_chk) diff --git a/REORG.TODO/debug/vswprintf_chk.c b/REORG.TODO/debug/vswprintf_chk.c new file mode 100644 index 0000000000..35d40263db --- /dev/null +++ b/REORG.TODO/debug/vswprintf_chk.c @@ -0,0 +1,74 @@ +/* Copyright (C) 1991-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <stdarg.h> +#include <wchar.h> +#include "../libio/libioP.h" +#include "../libio/strfile.h" + + +/* Write formatted output into S, according to the format + string FORMAT, writing no more than MAXLEN characters. */ +/* VARARGS5 */ +int +__vswprintf_chk (wchar_t *s, size_t maxlen, int flags, size_t slen, + const wchar_t *format, va_list args) +{ + /* XXX Maybe for less strict version do not fail immediately. + Though, maxlen is supposed to be the size of buffer pointed + to by s, so a conforming program can't pass such maxlen + to *snprintf. */ + if (__glibc_unlikely (slen < maxlen)) + __chk_fail (); + + _IO_wstrnfile sf; + struct _IO_wide_data wd; + int ret; +#ifdef _IO_MTSAFE_IO + sf.f._sbf._f._lock = NULL; +#endif + + /* We need to handle the special case where MAXLEN is 0. Use the + overflow buffer right from the start. */ + if (__glibc_unlikely (maxlen == 0)) + /* Since we have to write at least the terminating L'\0' a buffer + length of zero always makes the function fail. */ + return -1; + + _IO_no_init (&sf.f._sbf._f, _IO_USER_LOCK, 0, &wd, &_IO_wstrn_jumps); + _IO_fwide (&sf.f._sbf._f, 1); + s[0] = L'\0'; + + /* For flags > 0 (i.e. __USE_FORTIFY_LEVEL > 1) request that %n + can only come from read-only format strings. */ + if (flags > 0) + sf.f._sbf._f._flags2 |= _IO_FLAGS2_FORTIFY; + + _IO_wstr_init_static (&sf.f._sbf._f, s, maxlen - 1, s); + ret = _IO_vfwprintf ((_IO_FILE *) &sf.f._sbf, format, args); + + if (sf.f._sbf._f._wide_data->_IO_buf_base == sf.overflow_buf) + /* ISO C99 requires swprintf/vswprintf to return an error if the + output does not fit int he provided buffer. */ + return -1; + + /* Terminate the string. */ + *sf.f._sbf._f._wide_data->_IO_write_ptr = '\0'; + + return ret; +} +libc_hidden_def (__vswprintf_chk) diff --git a/REORG.TODO/debug/vwprintf_chk.c b/REORG.TODO/debug/vwprintf_chk.c new file mode 100644 index 0000000000..1cd53a35a7 --- /dev/null +++ b/REORG.TODO/debug/vwprintf_chk.c @@ -0,0 +1,41 @@ +/* Copyright (C) 1991-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <stdarg.h> +#include <stdio.h> +#include <wchar.h> +#include "../libio/libioP.h" + + +/* Write formatted output to stdout from the format string FORMAT. */ +int +__vwprintf_chk (int flag, const wchar_t *format, va_list ap) +{ + int done; + + _IO_acquire_lock_clear_flags2 (stdout); + if (flag > 0) + stdout->_flags2 |= _IO_FLAGS2_FORTIFY; + + done = _IO_vfwprintf (stdout, format, ap); + + if (flag > 0) + stdout->_flags2 &= ~_IO_FLAGS2_FORTIFY; + _IO_release_lock (stdout); + + return done; +} diff --git a/REORG.TODO/debug/warning-nop.c b/REORG.TODO/debug/warning-nop.c new file mode 100644 index 0000000000..8a740da36a --- /dev/null +++ b/REORG.TODO/debug/warning-nop.c @@ -0,0 +1,70 @@ +/* Dummy nop functions to elicit link-time warnings. + Copyright (C) 2005-2017 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. + + In addition to the permissions in the GNU Lesser General Public + License, the Free Software Foundation gives you unlimited + permission to link the compiled version of this file with other + programs, and to distribute those programs without any restriction + coming from the use of this file. (The GNU Lesser General Public + License restrictions do apply in other respects; for example, they + cover modification of the file, and distribution when not linked + into another program.) + + Note that people who make modified versions of this file are not + obligated to grant this special exception for their modified + versions; it is their choice whether to do so. The GNU Lesser + General Public License gives permission to release a modified + version without this exception; this exception also makes it + possible to release a modified version which carries forward this + exception. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <sys/cdefs.h> + +static void +__attribute__ ((used)) +nop (void) +{ +} + +/* Don't insert any other #include's before this #undef! */ + +#undef __warndecl +#define __warndecl(name, msg) \ + extern void name (void) __attribute__ ((alias ("nop"))) attribute_hidden; \ + link_warning (name, msg) + +#undef __USE_FORTIFY_LEVEL +#define __USE_FORTIFY_LEVEL 99 + +/* Following here we need an #include for each public header file + that uses __warndecl. */ + +/* Define away to avoid warnings with compilers that do not have these + builtins. */ +#define __builtin___memcpy_chk(dest, src, len, bos) NULL +#define __builtin___memmove_chk(dest, src, len, bos) NULL +#define __builtin___mempcpy_chk(dest, src, len, bos) NULL +#define __builtin___memset_chk(dest, ch, len, bos) NULL +#define __builtin___stpcpy_chk(dest, src, bos) NULL +#define __builtin___strcat_chk(dest, src, bos) NULL +#define __builtin___strcpy_chk(dest, src, bos) NULL +#define __builtin___strncat_chk(dest, src, len, bos) NULL +#define __builtin___strncpy_chk(dest, src, len, bos) NULL +#define __builtin_object_size(bos, level) 0 + +#include <string.h> diff --git a/REORG.TODO/debug/wcpcpy_chk.c b/REORG.TODO/debug/wcpcpy_chk.c new file mode 100644 index 0000000000..a0dbbf3b14 --- /dev/null +++ b/REORG.TODO/debug/wcpcpy_chk.c @@ -0,0 +1,44 @@ +/* Copyright (C) 1996-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1996. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <wchar.h> + +#define __need_ptrdiff_t +#include <stddef.h> + + +/* Copy SRC to DEST, returning the address of the terminating L'\0' in + DEST. Check for overflows. */ +wchar_t * +__wcpcpy_chk (wchar_t *dest, const wchar_t *src, size_t destlen) +{ + wchar_t *wcp = (wchar_t *) dest - 1; + wint_t c; + const ptrdiff_t off = src - dest + 1; + + do + { + if (__glibc_unlikely (destlen-- == 0)) + __chk_fail (); + c = wcp[off]; + *++wcp = c; + } + while (c != L'\0'); + + return wcp; +} diff --git a/REORG.TODO/debug/wcpncpy_chk.c b/REORG.TODO/debug/wcpncpy_chk.c new file mode 100644 index 0000000000..99f8be38af --- /dev/null +++ b/REORG.TODO/debug/wcpncpy_chk.c @@ -0,0 +1,32 @@ +/* Copyright (C) 1995-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <wchar.h> + + +/* Copy no more than N wide-characters of SRC to DEST. */ +wchar_t * +__wcpncpy_chk (wchar_t *dest, const wchar_t *src, size_t n, size_t destlen) +{ + if (__glibc_unlikely (destlen < n)) + __chk_fail (); + + /* This function is not often enough used to justify not using a + tail call. */ + return __wcpncpy (dest, src, n); +} diff --git a/REORG.TODO/debug/wcrtomb_chk.c b/REORG.TODO/debug/wcrtomb_chk.c new file mode 100644 index 0000000000..c71212e3da --- /dev/null +++ b/REORG.TODO/debug/wcrtomb_chk.c @@ -0,0 +1,34 @@ +/* Copyright (C) 2005-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <langinfo.h> +#include <locale.h> +#include <stdlib.h> +#include <wchar.h> +#include <locale/localeinfo.h> + + +size_t +__wcrtomb_chk (char *s, wchar_t wchar, mbstate_t *ps, size_t buflen) +{ + /* We do not have to implement the full wctomb semantics since we + know that S cannot be NULL when we come here. */ + if (buflen < MB_CUR_MAX) + __chk_fail (); + + return __wcrtomb (s, wchar, ps); +} diff --git a/REORG.TODO/debug/wcscat_chk.c b/REORG.TODO/debug/wcscat_chk.c new file mode 100644 index 0000000000..a528f06b57 --- /dev/null +++ b/REORG.TODO/debug/wcscat_chk.c @@ -0,0 +1,54 @@ +/* Copyright (C) 1995-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <wchar.h> + + +/* Append SRC on the end of DEST. Check for overflows. */ +wchar_t * +__wcscat_chk (wchar_t *dest, const wchar_t *src, size_t destlen) +{ + wchar_t *s1 = dest; + const wchar_t *s2 = src; + wchar_t c; + + /* Find the end of the string. */ + do + { + if (__glibc_unlikely (destlen-- == 0)) + __chk_fail (); + c = *s1++; + } + while (c != L'\0'); + + /* Make S1 point before the next character, so we can increment + it while memory is read (wins on pipelined cpus). */ + s1 -= 2; + ++destlen; + + do + { + if (__glibc_unlikely (destlen-- == 0)) + __chk_fail (); + c = *s2++; + *++s1 = c; + } + while (c != L'\0'); + + return dest; +} diff --git a/REORG.TODO/debug/wcscpy_chk.c b/REORG.TODO/debug/wcscpy_chk.c new file mode 100644 index 0000000000..0c2d0924a4 --- /dev/null +++ b/REORG.TODO/debug/wcscpy_chk.c @@ -0,0 +1,60 @@ +/* Copyright (C) 1995-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <stddef.h> +#include <wchar.h> + + +/* Copy SRC to DEST. */ +wchar_t * +__wcscpy_chk (wchar_t *dest, const wchar_t *src, size_t n) +{ + wint_t c; + wchar_t *wcp; + + if (__alignof__ (wchar_t) >= sizeof (wchar_t)) + { + const ptrdiff_t off = dest - src - 1; + + wcp = (wchar_t *) src; + + do + { + if (__glibc_unlikely (n-- == 0)) + __chk_fail (); + c = *wcp++; + wcp[off] = c; + } + while (c != L'\0'); + } + else + { + wcp = dest; + + do + { + if (__glibc_unlikely (n-- == 0)) + __chk_fail (); + c = *src++; + *wcp++ = c; + } + while (c != L'\0'); + } + + return dest; +} diff --git a/REORG.TODO/debug/wcsncat_chk.c b/REORG.TODO/debug/wcsncat_chk.c new file mode 100644 index 0000000000..74d428ff63 --- /dev/null +++ b/REORG.TODO/debug/wcsncat_chk.c @@ -0,0 +1,95 @@ +/* Copyright (C) 1995-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <wchar.h> + + +/* Append no more than N wide-character of SRC onto DEST. */ +wchar_t * +__wcsncat_chk (wchar_t *dest, const wchar_t *src, size_t n, size_t destlen) +{ + wchar_t c; + wchar_t * const s = dest; + + /* Find the end of DEST. */ + do + { + if (__glibc_unlikely (destlen-- == 0)) + __chk_fail (); + c = *dest++; + } + while (c != L'\0'); + + /* Make DEST point before next character, so we can increment + it while memory is read (wins on pipelined cpus). */ + ++destlen; + dest -= 2; + + if (n >= 4) + { + size_t n4 = n >> 2; + do + { + if (__glibc_unlikely (destlen-- == 0)) + __chk_fail (); + c = *src++; + *++dest = c; + if (c == L'\0') + return s; + if (__glibc_unlikely (destlen-- == 0)) + __chk_fail (); + c = *src++; + *++dest = c; + if (c == L'\0') + return s; + if (__glibc_unlikely (destlen-- == 0)) + __chk_fail (); + c = *src++; + *++dest = c; + if (c == L'\0') + return s; + if (__glibc_unlikely (destlen-- == 0)) + __chk_fail (); + c = *src++; + *++dest = c; + if (c == L'\0') + return s; + } while (--n4 > 0); + n &= 3; + } + + while (n > 0) + { + if (__glibc_unlikely (destlen-- == 0)) + __chk_fail (); + c = *src++; + *++dest = c; + if (c == L'\0') + return s; + n--; + } + + if (c != L'\0') + { + if (__glibc_unlikely (destlen-- == 0)) + __chk_fail (); + *++dest = L'\0'; + } + + return s; +} diff --git a/REORG.TODO/debug/wcsncpy_chk.c b/REORG.TODO/debug/wcsncpy_chk.c new file mode 100644 index 0000000000..d4383e4399 --- /dev/null +++ b/REORG.TODO/debug/wcsncpy_chk.c @@ -0,0 +1,32 @@ +/* Copyright (C) 1995-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <wchar.h> + + +/* Copy no more than N wide-characters of SRC to DEST. */ +wchar_t * +__wcsncpy_chk (wchar_t *dest, const wchar_t *src, size_t n, size_t destlen) +{ + if (__glibc_unlikely (destlen < n)) + __chk_fail (); + + /* This function is not often enough used to justify not using a + tail call. */ + return __wcsncpy (dest, src, n); +} diff --git a/REORG.TODO/debug/wcsnrtombs_chk.c b/REORG.TODO/debug/wcsnrtombs_chk.c new file mode 100644 index 0000000000..0c9deb42fb --- /dev/null +++ b/REORG.TODO/debug/wcsnrtombs_chk.c @@ -0,0 +1,30 @@ +/* Copyright (C) 2005-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <locale.h> +#include <wchar.h> + + +size_t +__wcsnrtombs_chk (char *dst, const wchar_t **src, size_t nwc, size_t len, + mbstate_t *ps, size_t dstlen) +{ + if (__glibc_unlikely (dstlen < len)) + __chk_fail (); + + return __wcsnrtombs (dst, src, nwc, len, ps); +} diff --git a/REORG.TODO/debug/wcsrtombs_chk.c b/REORG.TODO/debug/wcsrtombs_chk.c new file mode 100644 index 0000000000..46b335ddff --- /dev/null +++ b/REORG.TODO/debug/wcsrtombs_chk.c @@ -0,0 +1,30 @@ +/* Copyright (C) 2005-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <locale.h> +#include <wchar.h> + + +size_t +__wcsrtombs_chk (char *dst, const wchar_t **src, size_t len, + mbstate_t *ps, size_t dstlen) +{ + if (__glibc_unlikely (dstlen < len)) + __chk_fail (); + + return __wcsrtombs (dst, src, len, ps); +} diff --git a/REORG.TODO/debug/wcstombs_chk.c b/REORG.TODO/debug/wcstombs_chk.c new file mode 100644 index 0000000000..3e6b437f56 --- /dev/null +++ b/REORG.TODO/debug/wcstombs_chk.c @@ -0,0 +1,35 @@ +/* Copyright (C) 2005-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <locale.h> +#include <string.h> +#include <wchar.h> + + +size_t +__wcstombs_chk (char *dst, const wchar_t *src, size_t len, size_t dstlen) +{ + if (__glibc_unlikely (dstlen < len)) + __chk_fail (); + + mbstate_t state; + + memset (&state, '\0', sizeof state); + + /* Return how many we wrote (or maybe an error). */ + return __wcsrtombs (dst, &src, len, &state); +} diff --git a/REORG.TODO/debug/wctomb_chk.c b/REORG.TODO/debug/wctomb_chk.c new file mode 100644 index 0000000000..4c396ef315 --- /dev/null +++ b/REORG.TODO/debug/wctomb_chk.c @@ -0,0 +1,35 @@ +/* Copyright (C) 2005-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <locale.h> +#include <stdlib.h> +#include <wcsmbs/wcsmbsload.h> + + +extern mbstate_t __wctomb_state attribute_hidden; /* Defined in wctomb.c. */ + + +int +__wctomb_chk (char *s, wchar_t wchar, size_t buflen) +{ + /* We do not have to implement the full wctomb semantics since we + know that S cannot be NULL when we come here. */ + if (buflen < MB_CUR_MAX) + __chk_fail (); + + return __wcrtomb (s, wchar, &__wctomb_state); +} diff --git a/REORG.TODO/debug/wmemcpy_chk.c b/REORG.TODO/debug/wmemcpy_chk.c new file mode 100644 index 0000000000..73aa837ef2 --- /dev/null +++ b/REORG.TODO/debug/wmemcpy_chk.c @@ -0,0 +1,29 @@ +/* Copyright (C) 1996-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@gnu.org>, 1996. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <wchar.h> +#include <string.h> + + +wchar_t * +__wmemcpy_chk (wchar_t *s1, const wchar_t *s2, size_t n, size_t ns1) +{ + if (__glibc_unlikely (ns1 < n)) + __chk_fail (); + return (wchar_t *) memcpy ((char *) s1, (char *) s2, n * sizeof (wchar_t)); +} diff --git a/REORG.TODO/debug/wmemmove_chk.c b/REORG.TODO/debug/wmemmove_chk.c new file mode 100644 index 0000000000..d6a07ff204 --- /dev/null +++ b/REORG.TODO/debug/wmemmove_chk.c @@ -0,0 +1,29 @@ +/* Copyright (C) 1996-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper, <drepper@gnu.ai.mit.edu> + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <wchar.h> +#include <string.h> + + +wchar_t * +__wmemmove_chk (wchar_t *s1, const wchar_t *s2, size_t n, size_t ns1) +{ + if (__glibc_unlikely (ns1 < n)) + __chk_fail (); + return (wchar_t *) memmove ((char *) s1, (char *) s2, n * sizeof (wchar_t)); +} diff --git a/REORG.TODO/debug/wmempcpy_chk.c b/REORG.TODO/debug/wmempcpy_chk.c new file mode 100644 index 0000000000..643b7aa75f --- /dev/null +++ b/REORG.TODO/debug/wmempcpy_chk.c @@ -0,0 +1,30 @@ +/* Copyright (C) 1999-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@gnu.org>, 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <wchar.h> +#include <string.h> + + +wchar_t * +__wmempcpy_chk (wchar_t *s1, const wchar_t *s2, size_t n, size_t ns1) +{ + if (__glibc_unlikely (ns1 < n)) + __chk_fail (); + return (wchar_t *) __mempcpy ((char *) s1, (char *) s2, + n * sizeof (wchar_t)); +} diff --git a/REORG.TODO/debug/wmemset_chk.c b/REORG.TODO/debug/wmemset_chk.c new file mode 100644 index 0000000000..ad05462aa2 --- /dev/null +++ b/REORG.TODO/debug/wmemset_chk.c @@ -0,0 +1,29 @@ +/* Copyright (C) 1996-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@gnu.org>, 1996. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <wchar.h> + + +wchar_t * +__wmemset_chk (wchar_t *s, wchar_t c, size_t n, size_t dstlen) +{ + if (__glibc_unlikely (dstlen < n)) + __chk_fail (); + + return wmemset (s, c, n); +} diff --git a/REORG.TODO/debug/wprintf_chk.c b/REORG.TODO/debug/wprintf_chk.c new file mode 100644 index 0000000000..5b35050006 --- /dev/null +++ b/REORG.TODO/debug/wprintf_chk.c @@ -0,0 +1,44 @@ +/* Copyright (C) 1991-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <stdarg.h> +#include <stdio.h> +#include <wchar.h> +#include "../libio/libioP.h" + + +/* Write formatted output to stdout from the format string FORMAT. */ +int +__wprintf_chk (int flag, const wchar_t *format, ...) +{ + va_list ap; + int done; + + _IO_acquire_lock_clear_flags2 (stdout); + if (flag > 0) + stdout->_flags2 |= _IO_FLAGS2_FORTIFY; + + va_start (ap, format); + done = _IO_vfwprintf (stdout, format, ap); + va_end (ap); + + if (flag > 0) + stdout->_flags2 &= ~_IO_FLAGS2_FORTIFY; + _IO_release_lock (stdout); + + return done; +} diff --git a/REORG.TODO/debug/xtrace.sh b/REORG.TODO/debug/xtrace.sh new file mode 100755 index 0000000000..fd14f298d9 --- /dev/null +++ b/REORG.TODO/debug/xtrace.sh @@ -0,0 +1,195 @@ +#! @BASH@ +# Copyright (C) 1999-2017 Free Software Foundation, Inc. +# This file is part of the GNU C Library. +# Contributed by Ulrich Drepper <drepper@gnu.org>, 1999. + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. + +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. + +# You should have received a copy of the GNU Lesser General Public +# License along with the GNU C Library; if not, see +# <http://www.gnu.org/licenses/>. + +pcprofileso='@SLIBDIR@/libpcprofile.so' +pcprofiledump='@BINDIR@/pcprofiledump' +TEXTDOMAIN=libc + +# Print usage message. +do_usage() { + printf $"Usage: xtrace [OPTION]... PROGRAM [PROGRAMOPTION]...\n" + exit 0 +} + +# Refer to --help option. +help_info() { + printf >&2 $"Try \`%s --help' or \`%s --usage' for more information.\n" xtrace xtrace + exit 1 +} + +# Message for missing argument. +do_missing_arg() { + printf >&2 $"%s: option '%s' requires an argument.\n" xtrace "$1" + help_info +} + +# Print help message +do_help() { + printf $"Usage: xtrace [OPTION]... PROGRAM [PROGRAMOPTION]...\n" + printf $"Trace execution of program by printing currently executed function. + + --data=FILE Don't run the program, just print the data from FILE. + + -?,--help Print this help and exit + --usage Give a short usage message + -V,--version Print version information and exit + +Mandatory arguments to long options are also mandatory for any corresponding +short options. + +" + printf $"For bug reporting instructions, please see:\\n%s.\\n" \ + "@REPORT_BUGS_TO@" + exit 0 +} + +do_version() { + echo 'xtrace @PKGVERSION@@VERSION@' + printf $"Copyright (C) %s Free Software Foundation, Inc. +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +" "2017" + printf $"Written by %s. +" "Ulrich Drepper" + exit 0 +} + +# Print out function name, file, and line number in a nicely formatted way. +format_line() { + fct=$1 + file=${2%%:*} + line=${2##*:} + width=$(expr $COLUMNS - 30) + filelen=$(expr length $file) + if test "$filelen" -gt "$width"; then + rwidth=$(expr $width - 3) + file="...$(expr substr $file $(expr 1 + $filelen - $rwidth) $rwidth)" + fi + printf '%-20s %-*s %6s\n' $fct $width $file $line +} + + +# If the variable COLUMNS is not set do this now. +COLUMNS=${COLUMNS:-80} + +# If `TERMINAL_PROG' is not set, set it to `xterm'. +TERMINAL_PROG=${TERMINAL_PROG:-xterm} + +# The data file to process, if any. +data= + +# Process arguments. But stop as soon as the program name is found. +while test $# -gt 0; do + case "$1" in + --d | --da | --dat | --data) + if test $# -eq 1; then + do_missing_arg $1 + fi + shift + data="$1" + ;; + --d=* | --da=* | --dat=* | --data=*) + data=${1##*=} + ;; + -\? | --h | --he | --hel | --help) + do_help + ;; + -V | --v | --ve | --ver | --vers | --versi | --versio | --version) + do_version + ;; + --u | --us | --usa | --usag | --usage) + do_usage + ;; + --) + # Stop processing arguments. + shift + break + ;; + --*) + printf >&2 $"xtrace: unrecognized option \`$1'\n" + help_info + ;; + *) + # Unknown option. This means the rest is the program name and parameters. + break + ;; + esac + shift +done + +# See whether any arguments are left. +if test $# -eq 0; then + printf >&2 $"No program name given\n" + help_info +fi + +# Determine the program name and check whether it exists. +program=$1 +shift +if test ! -f "$program"; then + printf >&2 $"executable \`$program' not found\n" + help_info +fi +if test ! -x "$program"; then + printf >&2 $"\`$program' is no executable\n" + help_info +fi + +# We have two modes. If a data file is given simply print the included data. +printf "%-20s %-*s %6s\n" Function $(expr $COLUMNS - 30) File Line +for i in $(seq 1 $COLUMNS); do printf -; done; printf '\n' +if test -n "$data"; then + $pcprofiledump "$data" | + sed 's/this = \([^,]*\).*/\1/' | + addr2line -fC -e "$program" | + while read fct; do + read file + if test "$fct" != '??' -a "$file" != '??:0'; then + format_line "$fct" "$file" + fi + done +else + fifo=$(mktemp -ut xtrace.XXXXXX) || exit + trap 'rm -f "$fifo"; exit 1' HUP INT QUIT TERM PIPE + mkfifo -m 0600 $fifo || exit 1 + + # Now start the program and let it write to the FIFO. + $TERMINAL_PROG -T "xtrace - $program $*" -e /bin/sh -c "LD_PRELOAD=$pcprofileso PCPROFILE_OUTPUT=$fifo $program $*; read < $fifo" & + termpid=$! + $pcprofiledump -u "$fifo" | + while read line; do + echo "$line" | + sed 's/this = \([^,]*\).*/\1/' | + addr2line -fC -e "$program" + done | + while read fct; do + read file + if test "$fct" != '??' -a "$file" != '??:0'; then + format_line "$fct" "$file" + fi + done + read -p "Press return here to close $TERMINAL_PROG($program)." + echo > "$fifo" + rm "$fifo" +fi + +exit 0 +# Local Variables: +# mode:ksh +# End: |