From 10ffcd52f0578b13b48bdf84e73759353b29b673 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Tue, 19 Jul 2005 23:46:55 +0000 Subject: [PATCH] * stdio-common/Makefile (aux): Add fxprintf. * stdio-common/fxprintf.c: New file. * include/stdio.h: Add declaration for stdio.h. * argp/argp-fmtstream.c: Use __fxprintf instead of inline stream orientation test and two separate function calls. * argp/argp-help.c: Likewise. * assert/assert-perr.c: Likewise. * assert/assert.c: Likewise. * gmon/gmon.c: Likewise. * inet/rcmd.c: Likewise. * malloc/obstack.c: Likewise. * misc/error.c: Likewise. * misc/getpass.c: Likewise. * posix/getopt.c: Likewise. * resolv/res_hconf.c: Likewise. * stdio-common/perror.c: Likewise. * stdio-common/psignal.c: Likewise. * stdlib/fmtmsg.c: Likewise. * sunrpc/auth_unix.c: Likewise. * sunrpc/clnt_perr.c: Likewise. * sunrpc/clnt_tcp.c: Likewise. * sunrpc/clnt_udp.c: Likewise. * sunrpc/clnt_unix.c: Likewise. * sunrpc/svc_simple.c: Likewise. * sunrpc/svc_tcp.c: Likewise. * sunrpc/svc_udp.c: Likewise. * sunrpc/svc_unix.c: Likewise. * sunrpc/xdr.c: Likewise. * sunrpc/xdr_array.c: Likewise. * sunrpc/xdr_rec.c: Likewise. * sunrpc/xdr_ref.c: Likewise. * sysdeps/generic/wordexp.c: Likewise. * misc/Makefile: Add rules to build and run tst-error1. * misc/tst-error1.c: New file. * misc/error.c: Fix memory leak and possibly endless loop. --- ChangeLog | 37 ++++++++++++++++++++ configure | 30 +++++++++++++++- include/stdio.h | 2 ++ misc/Makefile | 15 ++++++-- misc/error.c | 77 ++++++++++++++++++++++++----------------- misc/tst-error1.c | 26 ++++++++++++++ stdio-common/Makefile | 2 +- stdio-common/fxprintf.c | 42 ++++++++++++++++++++++ 8 files changed, 195 insertions(+), 36 deletions(-) create mode 100644 misc/tst-error1.c create mode 100644 stdio-common/fxprintf.c diff --git a/ChangeLog b/ChangeLog index 72659d6fbf..dd4c6b89b1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,42 @@ 2005-07-19 Ulrich Drepper + * stdio-common/Makefile (aux): Add fxprintf. + * stdio-common/fxprintf.c: New file. + * include/stdio.h: Add declaration for stdio.h. + * argp/argp-fmtstream.c: Use __fxprintf instead of inline stream + orientation test and two separate function calls. + * argp/argp-help.c: Likewise. + * assert/assert-perr.c: Likewise. + * assert/assert.c: Likewise. + * gmon/gmon.c: Likewise. + * inet/rcmd.c: Likewise. + * malloc/obstack.c: Likewise. + * misc/error.c: Likewise. + * misc/getpass.c: Likewise. + * posix/getopt.c: Likewise. + * resolv/res_hconf.c: Likewise. + * stdio-common/perror.c: Likewise. + * stdio-common/psignal.c: Likewise. + * stdlib/fmtmsg.c: Likewise. + * sunrpc/auth_unix.c: Likewise. + * sunrpc/clnt_perr.c: Likewise. + * sunrpc/clnt_tcp.c: Likewise. + * sunrpc/clnt_udp.c: Likewise. + * sunrpc/clnt_unix.c: Likewise. + * sunrpc/svc_simple.c: Likewise. + * sunrpc/svc_tcp.c: Likewise. + * sunrpc/svc_udp.c: Likewise. + * sunrpc/svc_unix.c: Likewise. + * sunrpc/xdr.c: Likewise. + * sunrpc/xdr_array.c: Likewise. + * sunrpc/xdr_rec.c: Likewise. + * sunrpc/xdr_ref.c: Likewise. + * sysdeps/generic/wordexp.c: Likewise. + + * misc/Makefile: Add rules to build and run tst-error1. + * misc/tst-error1.c: New file. + * misc/error.c: Fix memory leak and possibly endless loop. + * configure.in: Check for -fstack-protector gcc option. * config.make.in (have-ssp): Add template. * nscd/Makefile (nscd-cflags): Add -fstack-protector if supported. diff --git a/configure b/configure index 402da463f9..a449415c01 100755 --- a/configure +++ b/configure @@ -313,7 +313,7 @@ ac_includes_default="\ # include #endif" -ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS with_fp with_cvs enable_check_abi oldest_abi bindnow force_install all_warnings build build_cpu build_vendor build_os host host_cpu host_vendor host_os subdirs add_ons base_machine sysnames INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA LN_S CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC OBJEXT BUILD_CC cross_compiling CPP CXX CXXFLAGS ac_ct_CXX AR OBJDUMP RANLIB ac_ct_RANLIB MIG AS LD PWD_P MAKE MSGFMT MAKEINFO SED AUTOCONF SYSINCLUDES libc_cv_gcc_static_libgcc BASH libc_cv_have_bash2 KSH libc_cv_have_ksh AWK PERL INSTALL_INFO BISON VERSIONING libc_cv_asm_protected_directive libc_cv_initfinit_array libc_cv_cc_with_libunwind libc_cv_z_nodelete libc_cv_z_nodlopen libc_cv_z_initfirst libc_cv_z_relro libc_cv_Bgroup libc_cv_libgcc_s_suffix libc_cv_as_needed ASFLAGS_config libc_cv_z_combreloc libc_cv_z_execstack libc_cv_fpie fno_unit_at_a_time libc_cv_have_initfini no_whole_archive exceptions LIBGD have_libaudit have_selinux EGREP sizeof_long_double libc_cv_gcc_unwind_find_fde uname_sysname uname_release uname_version old_glibc_headers libc_cv_slibdir libc_cv_localedir libc_cv_sysconfdir libc_cv_rootsbindir libc_cv_forced_unwind use_ldconfig ldd_rewrite_script gnu_ld gnu_as elf xcoff static shared pic_default profile omitfp bounded static_nss nopic_initfini DEFINES mach_interface_list VERSION RELEASE LIBOBJS LTLIBOBJS' +ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS with_fp with_cvs enable_check_abi oldest_abi bindnow force_install all_warnings build build_cpu build_vendor build_os host host_cpu host_vendor host_os subdirs add_ons base_machine sysnames INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA LN_S CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC OBJEXT BUILD_CC cross_compiling CPP CXX CXXFLAGS ac_ct_CXX AR OBJDUMP RANLIB ac_ct_RANLIB MIG AS LD PWD_P MAKE MSGFMT MAKEINFO SED AUTOCONF SYSINCLUDES libc_cv_gcc_static_libgcc BASH libc_cv_have_bash2 KSH libc_cv_have_ksh AWK PERL INSTALL_INFO BISON VERSIONING libc_cv_asm_protected_directive libc_cv_initfinit_array libc_cv_cc_with_libunwind libc_cv_z_nodelete libc_cv_z_nodlopen libc_cv_z_initfirst libc_cv_z_relro libc_cv_Bgroup libc_cv_libgcc_s_suffix libc_cv_as_needed ASFLAGS_config libc_cv_z_combreloc libc_cv_z_execstack libc_cv_fpie fno_unit_at_a_time libc_cv_ssp libc_cv_have_initfini no_whole_archive exceptions LIBGD have_libaudit have_selinux EGREP sizeof_long_double libc_cv_gcc_unwind_find_fde uname_sysname uname_release uname_version old_glibc_headers libc_cv_slibdir libc_cv_localedir libc_cv_sysconfdir libc_cv_rootsbindir libc_cv_forced_unwind use_ldconfig ldd_rewrite_script gnu_ld gnu_as elf xcoff static shared pic_default profile omitfp bounded static_nss nopic_initfini DEFINES mach_interface_list VERSION RELEASE LIBOBJS LTLIBOBJS' ac_subst_files='' # Initialize some variables set by options. @@ -5799,6 +5799,33 @@ if test $libc_cv_fno_unit_at_a_time = yes; then fi +echo "$as_me:$LINENO: checking for -fstack-protector" >&5 +echo $ECHO_N "checking for -fstack-protector... $ECHO_C" >&6 +if test "${libc_cv_ssp+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat > conftest.c <&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } +then + libc_cv_ssp=yes +else + libc_cv_ssp=no +fi +rm -f conftest* +fi +echo "$as_me:$LINENO: result: $libc_cv_ssp" >&5 +echo "${ECHO_T}$libc_cv_ssp" >&6 + + if test $elf != yes; then echo "$as_me:$LINENO: checking for .init and .fini sections" >&5 echo $ECHO_N "checking for .init and .fini sections... $ECHO_C" >&6 @@ -8434,6 +8461,7 @@ s,@libc_cv_z_combreloc@,$libc_cv_z_combreloc,;t t s,@libc_cv_z_execstack@,$libc_cv_z_execstack,;t t s,@libc_cv_fpie@,$libc_cv_fpie,;t t s,@fno_unit_at_a_time@,$fno_unit_at_a_time,;t t +s,@libc_cv_ssp@,$libc_cv_ssp,;t t s,@libc_cv_have_initfini@,$libc_cv_have_initfini,;t t s,@no_whole_archive@,$no_whole_archive,;t t s,@exceptions@,$exceptions,;t t diff --git a/include/stdio.h b/include/stdio.h index c8c89ad878..5b47c53883 100644 --- a/include/stdio.h +++ b/include/stdio.h @@ -79,6 +79,8 @@ extern int __ftrylockfile (FILE *__stream); extern int __getc_unlocked (FILE *__fp); extern wint_t __getwc_unlocked (FILE *__fp); +extern int __fxprintf (FILE *__fp, const char *__fmt, const wchar_t *__wfmt, + ...) __attribute__ ((__format__ (__printf__, 2, 4))); extern __const char *__const _sys_errlist_internal[] attribute_hidden; extern int _sys_nerr_internal attribute_hidden; diff --git a/misc/Makefile b/misc/Makefile index 862eb1b800..cd5b64e7ab 100644 --- a/misc/Makefile +++ b/misc/Makefile @@ -1,4 +1,4 @@ -# Copyright (C) 1991-2002, 2003, 2004 Free Software Foundation, Inc. +# Copyright (C) 1991-2002, 2003, 2004, 2005 Free Software Foundation, Inc. # This file is part of the GNU C Library. # The GNU C Library is free software; you can redistribute it and/or @@ -65,6 +65,8 @@ routines := brk sbrk sstk ioctl \ distribute := device-nrs.h +generated := tst-error1.mtrace tst-error1-mem + include ../Makeconfig aux := init-misc @@ -73,7 +75,11 @@ install-lib := libbsd-compat.a libg.a endif gpl2lgpl := error.c error.h -tests := tst-dirname tst-tsearch tst-fdset tst-efgcvt tst-mntent tst-hsearch +tests := tst-dirname tst-tsearch tst-fdset tst-efgcvt tst-mntent tst-hsearch \ + tst-error1 +ifeq (no,$(cross-compiling)) +tests: $(objpfx)tst-error1-mem +endif CFLAGS-tsearch.c = $(uses-callbacks) CFLAGS-lsearch.c = $(uses-callbacks) @@ -106,3 +112,8 @@ endif ifeq ($(build-bounded),yes) $(objpfx)tst-tsearch-bp: $(common-objpfx)math/libm_b.a endif + +tst-error1-ENV = MALLOC_TRACE=$(objpfx)tst-error1.mtrace +tst-error1-ARGS = $(objpfx)tst-error1.out +$(objpfx)tst-error1-mem: $(objpfx)tst-error1.out + $(common-objpfx)malloc/mtrace $(objpfx)tst-error1.mtrace > $@ diff --git a/misc/error.c b/misc/error.c index 2501583366..5f00ae97de 100644 --- a/misc/error.c +++ b/misc/error.c @@ -1,7 +1,6 @@ /* Error handler for noninteractive utilities - Copyright (C) 1990-1998, 2000-2003, 2004 Free Software Foundation, Inc. - This file is part of the GNU C Library. Its master source is NOT part of - the C library, however. The master source lives in /gd/gnu/lib. + Copyright (C) 1990-1998, 2000-2004, 2005 Free Software Foundation, Inc. + This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -74,6 +73,7 @@ unsigned int error_message_count; # define program_name program_invocation_name # include +# include # include /* In GNU libc we want do not want to use the common name `error' directly. @@ -158,14 +158,10 @@ print_errno_message (int errnum) #endif #if _LIBC - if (_IO_fwide (stderr, 0) > 0) - { - __fwprintf (stderr, L": %s", s); - return; - } -#endif - + __fxprintf (NULL, ": %s", L": %s", s); +#else fprintf (stderr, ": %s", s); +#endif } #ifdef VA_START @@ -182,14 +178,15 @@ error_tail (int status, int errnum, const char *message, va_list args) mbstate_t st; size_t res; const char *tmp; + bool use_malloc = false; - do + while (1) { - if (len < ALLOCA_LIMIT) + if (__libc_use_alloca (len * sizeof (wchar_t))) wmessage = (wchar_t *) alloca (len * sizeof (wchar_t)); else { - if (wmessage != NULL && len / 2 < ALLOCA_LIMIT) + if (!use_malloc) wmessage = NULL; wchar_t *p = (wchar_t *) realloc (wmessage, @@ -201,18 +198,38 @@ error_tail (int status, int errnum, const char *message, va_list args) return; } wmessage = p; + use_malloc = true; } memset (&st, '\0', sizeof (st)); tmp = message; + + res = mbsrtowcs (wmessage, &tmp, len, &st); + if (res != len) + break; + + if (__builtin_expect (len >= SIZE_MAX / 2, 0)) + { + /* This reallyy should not happen if everything is fine. */ + res = (size_t) -1; + break; + } + + len *= 2; } - while ((res = mbsrtowcs (wmessage, &tmp, len, &st)) == len); if (res == (size_t) -1) - /* The string cannot be converted. */ - wmessage = (wchar_t *) L"???"; + { + /* The string cannot be converted. */ + if (use_malloc) + free (wmessage); + wmessage = (wchar_t *) L"???"; + } __vfwprintf (stderr, wmessage, args); + + if (use_malloc) + free (wmessage); } else # endif @@ -226,11 +243,10 @@ error_tail (int status, int errnum, const char *message, va_list args) if (errnum) print_errno_message (errnum); # if _LIBC - if (_IO_fwide (stderr, 0) > 0) - putwc (L'\n', stderr); - else + __fxprintf (NULL, "\n", L"\n"); +# else + putc ('\n', stderr); # endif - putc ('\n', stderr); fflush (stderr); if (status) exit (status); @@ -275,11 +291,10 @@ error (status, errnum, message, va_alist) else { #if _LIBC - if (_IO_fwide (stderr, 0) > 0) - __fwprintf (stderr, L"%s: ", program_name); - else + __fxprintf (NULL, "%s: ", L"%s: ", program_name); +#else + fprintf (stderr, "%s: ", program_name); #endif - fprintf (stderr, "%s: ", program_name); } #ifdef VA_START @@ -359,21 +374,19 @@ error_at_line (status, errnum, file_name, line_number, message, va_alist) else { #if _LIBC - if (_IO_fwide (stderr, 0) > 0) - __fwprintf (stderr, L"%s: ", program_name); - else + __fxprintf (NULL, "%s:", L"%s: ", program_name); +#else + fprintf (stderr, "%s:", program_name); #endif - fprintf (stderr, "%s:", program_name); } if (file_name != NULL) { #if _LIBC - if (_IO_fwide (stderr, 0) > 0) - __fwprintf (stderr, L"%s:%d: ", file_name, line_number); - else + __fxprintf (NULL, "%s:%d: ", L"%s:%d: ", file_name, line_number); +#else + fprintf (stderr, "%s:%d: ", file_name, line_number); #endif - fprintf (stderr, "%s:%d: ", file_name, line_number); } #ifdef VA_START diff --git a/misc/tst-error1.c b/misc/tst-error1.c new file mode 100644 index 0000000000..e84843ed2f --- /dev/null +++ b/misc/tst-error1.c @@ -0,0 +1,26 @@ +#include +#include +#include +#include +#include + +static int +do_test (int argc, char *argv[]) +{ + mtrace (); + (void) freopen (argc == 1 ? "/dev/stdout" : argv[1], "a", stderr); + /* Orient the stream. */ + fwprintf (stderr, L"hello world\n"); + char buf[20000]; + static const char str[] = "hello world! "; + for (int i = 0; i < 1000; ++i) + memcpy (&buf[i * (sizeof (str) - 1)], str, sizeof (str)); + error (0, 0, str); + error (0, 0, buf); + error (0, 0, buf); + error (0, 0, str); + return 0; +} + +#define TEST_FUNCTION do_test (argc, argv) +#include "../test-skeleton.c" diff --git a/stdio-common/Makefile b/stdio-common/Makefile index 2e797e4dfe..d860d75dee 100644 --- a/stdio-common/Makefile +++ b/stdio-common/Makefile @@ -40,7 +40,7 @@ install-others = $(inst_includedir)/bits/stdio_lim.h include ../Makeconfig -aux := errlist siglist printf-parsemb printf-parsewc +aux := errlist siglist printf-parsemb printf-parsewc fxprintf distribute := _itoa.h _itowa.h _i18n_number.h \ printf-parse.h stdio_lim.h.in tst-unbputc.sh tst-printf.sh diff --git a/stdio-common/fxprintf.c b/stdio-common/fxprintf.c new file mode 100644 index 0000000000..82a2ac8bd7 --- /dev/null +++ b/stdio-common/fxprintf.c @@ -0,0 +1,42 @@ +/* Copyright (C) 2005 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper . + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include +#include + + +int +__fxprintf (FILE *fp, const char *fmt, const wchar_t *wfmt, ...) +{ + if (fp == NULL) + fp = stderr; + + va_list ap; + va_start (ap, wfmt); + + int res; + if (_IO_fwide (fp, 0) > 0) + res = __vfwprintf (fp, wfmt, ap); + else + res = _IO_vfprintf (fp, fmt, ap); + + va_end (ap); + + return res; +}