From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 1576 invoked by alias); 7 Sep 2007 22:34:31 -0000 Received: (qmail 1550 invoked by uid 22791); 7 Sep 2007 22:34:29 -0000 X-Spam-Check-By: sourceware.org Received: from sunsite.ms.mff.cuni.cz (HELO sunsite.mff.cuni.cz) (195.113.15.26) by sourceware.org (qpsmtpd/0.31) with ESMTP; Fri, 07 Sep 2007 22:34:23 +0000 Received: from sunsite.mff.cuni.cz (localhost.localdomain [127.0.0.1]) by sunsite.mff.cuni.cz (8.13.8/8.13.8) with ESMTP id l87MgEPG016899; Sat, 8 Sep 2007 00:42:14 +0200 Received: (from jakub@localhost) by sunsite.mff.cuni.cz (8.13.8/8.13.8/Submit) id l87MgEqi016898; Sat, 8 Sep 2007 00:42:14 +0200 Date: Fri, 07 Sep 2007 22:34:00 -0000 From: Jakub Jelinek To: Ulrich Drepper Cc: Glibc hackers Subject: [PATCH] Further -D_FORTIFY_SOURCE={,=2} C++ support Message-ID: <20070907224213.GK2279@sunsite.mff.cuni.cz> Reply-To: Jakub Jelinek Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.4.2.2i Mailing-List: contact libc-hacker-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-hacker-owner@sourceware.org X-SW-Source: 2007-09/txt/msg00001.txt.bz2 Hi! __builtin_va_arg_pack () has been committed to GCC SVN, so we can support fortification even for {,v}{,s,sn,sw,w,f,fw}printf and syslog. This patch is on top of the one I posted on Monday. Distro note: the support is backported in latest Fedora gcc as well, so with little tweaks of misc/sys/cdefs.h it is possible to test this even with older gccs. 2007-09-07 Jakub Jelinek * misc/sys/cdefs.h (__va_arg_pack): Define for GCC 4.3+. * misc/bits/syslog.h (syslog): When __va_arg_pack is defined, implement as __extern_always_inline function. (vsyslog): Define as __extern_always_inline function unconditionally. * libio/bits/stdio2.h (sprintf, snprintf, printf, fprintf): When __va_arg_pack is defined, implement as __extern_always_inline functions. (vsprintf, vsnprintf, vprintf, vfprintf): Define as __extern_always_inline functions unconditionally. * libio/bits/stdio.h (vprintf): Ifdef out the inline when bits/stdio2.h will be included. * wcsmbs/bits/wchar2.h (__swprintf_alias): New redirect. (swprintf, wprintf, fwprintf): When __va_arg_pack is defined, implement as __extern_always_inline functions. (vswprintf, vwprintf, vfwprintf): Define as __extern_always_inline functions unconditionally. * debug/tst-chk1.c (do_test): Enable remaining tests for C++. --- libc/misc/sys/cdefs.h.jj 2007-09-07 08:14:01.000000000 +0200 +++ libc/misc/sys/cdefs.h 2007-09-07 08:13:20.000000000 +0200 @@ -294,6 +294,12 @@ # endif #endif +/* GCC 4.3 and above allow passing all anonymous arguments of an + __extern_always_inline function to some other vararg function. */ +#if __GNUC_PREREQ (4,3) +# define __va_arg_pack() __builtin_va_arg_pack () +#endif + /* It is possible to compile containing GCC extensions even if GCC is run in pedantic mode if the uses are carefully marked using the `__extension__' keyword. But this is not generally available before --- libc/misc/bits/syslog.h.jj 2007-09-02 19:18:12.000000000 +0200 +++ libc/misc/bits/syslog.h 2007-09-07 08:26:51.000000000 +0200 @@ -25,8 +25,13 @@ extern void __syslog_chk (int __pri, int __flag, __const char *__fmt, ...) __attribute__ ((__format__ (__printf__, 3, 4))); -#ifndef __cplusplus -/* FIXME for C++. */ +#ifdef __va_arg_pack +__extern_always_inline void +syslog (int __pri, int __flag, __const char *__fmt, ...) +{ + return __syslog_chk (__pri, __flag, __fmt, __va_arg_pack ()); +} +#elif !defined __cplusplus # define syslog(pri, ...) \ __syslog_chk (pri, __USE_FORTIFY_LEVEL - 1, __VA_ARGS__) #endif @@ -37,14 +42,9 @@ extern void __vsyslog_chk (int __pri, in __gnuc_va_list __ap) __attribute__ ((__format__ (__printf__, 3, 0))); -# ifdef __cplusplus __extern_always_inline void vsyslog (int __pri, __const char *__fmt, __gnuc_va_list __ap) { return __vsyslog_chk (__pri, __USE_FORTIFY_LEVEL - 1, __fmt, __ap); } -# else -# define vsyslog(pri, fmt, ap) \ - __vsyslog_chk (pri, __USE_FORTIFY_LEVEL - 1, fmt, ap) -# endif #endif --- libc/libio/bits/stdio2.h.jj 2007-09-02 19:18:12.000000000 +0200 +++ libc/libio/bits/stdio2.h 2007-09-07 08:45:37.000000000 +0200 @@ -27,14 +27,19 @@ extern int __vsprintf_chk (char *__restr __const char *__restrict __format, _G_va_list __ap) __THROW; -#ifndef __cplusplus -/* FIXME for C++ */ +#ifdef __va_arg_pack +__extern_always_inline int +__NTH (sprintf (char *__restrict __s, __const char *__restrict __fmt, ...)) +{ + return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, + __bos (__s), __fmt, __va_arg_pack ()); +} +#elif !defined __cplusplus # define sprintf(str, ...) \ __builtin___sprintf_chk (str, __USE_FORTIFY_LEVEL - 1, __bos (str), \ __VA_ARGS__) #endif -#ifdef __cplusplus __extern_always_inline int __NTH (vsprintf (char *__restrict __s, __const char *__restrict __fmt, _G_va_list __ap)) @@ -42,10 +47,6 @@ __NTH (vsprintf (char *__restrict __s, _ return __builtin___vsprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, __bos (__s), __fmt, __ap); } -#else -# define vsprintf(str, fmt, ap) \ - __builtin___vsprintf_chk (str, __USE_FORTIFY_LEVEL - 1, __bos (str), fmt, ap) -#endif #if defined __USE_BSD || defined __USE_ISOC99 || defined __USE_UNIX98 @@ -56,14 +57,20 @@ extern int __vsnprintf_chk (char *__rest size_t __slen, __const char *__restrict __format, _G_va_list __ap) __THROW; -# ifndef __cplusplus -/* FIXME for C++ */ +# ifdef __va_arg_pack +__extern_always_inline int +__NTH (snprintf (char *__restrict __s, size_t __n, + __const char *__restrict __fmt, ...)) +{ + return __builtin___snprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1, + __bos (__s), __fmt, __va_arg_pack ()); +} +# elif !defined __cplusplus # define snprintf(str, len, ...) \ __builtin___snprintf_chk (str, len, __USE_FORTIFY_LEVEL - 1, __bos (str), \ __VA_ARGS__) # endif -# ifdef __cplusplus __extern_always_inline int __NTH (vsnprintf (char *__restrict __s, size_t __n, __const char *__restrict __fmt, _G_va_list __ap)) @@ -71,11 +78,6 @@ __NTH (vsnprintf (char *__restrict __s, return __builtin___vsnprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1, __bos (__s), __fmt, __ap); } -# else -# define vsnprintf(str, len, fmt, ap) \ - __builtin___vsnprintf_chk (str, len, __USE_FORTIFY_LEVEL - 1, __bos (str), \ - fmt, ap) -# endif #endif @@ -89,19 +91,34 @@ extern int __vfprintf_chk (FILE *__restr extern int __vprintf_chk (int __flag, __const char *__restrict __format, _G_va_list __ap); -# ifndef __cplusplus -/* FIXME for C++ */ +# ifdef __va_arg_pack +__extern_always_inline int +fprintf (FILE *__restrict __stream, __const char *__restrict __fmt, ...) +{ + return __fprintf_chk (__stream, __USE_FORTIFY_LEVEL - 1, __fmt, + __va_arg_pack ()); +} + +__extern_always_inline int +printf (__const char *__restrict __fmt, ...) +{ + return __printf_chk (__USE_FORTIFY_LEVEL - 1, __fmt, __va_arg_pack ()); +} +# elif !defined __cplusplus # define printf(...) \ __printf_chk (__USE_FORTIFY_LEVEL - 1, __VA_ARGS__) # define fprintf(stream, ...) \ __fprintf_chk (stream, __USE_FORTIFY_LEVEL - 1, __VA_ARGS__) # endif -# ifdef __cplusplus __extern_always_inline int vprintf (__const char *__restrict __fmt, _G_va_list __ap) { +#ifdef __USE_EXTERN_INLINES + return __vfprintf_chk (stdout, __USE_FORTIFY_LEVEL - 1, __fmt, __ap); +#else return __vprintf_chk (__USE_FORTIFY_LEVEL - 1, __fmt, __ap); +#endif } __extern_always_inline int @@ -110,12 +127,6 @@ vfprintf (FILE *__restrict __stream, { return __vfprintf_chk (__stream, __USE_FORTIFY_LEVEL - 1, __fmt, __ap); } -# else -# define vprintf(format, ap) \ - __vprintf_chk (__USE_FORTIFY_LEVEL - 1, format, ap) -# define vfprintf(stream, format, ap) \ - __vfprintf_chk (stream, __USE_FORTIFY_LEVEL - 1, format, ap) -# endif #endif --- libc/wcsmbs/bits/wchar2.h.jj 2007-09-02 19:18:12.000000000 +0200 +++ libc/wcsmbs/bits/wchar2.h 2007-09-07 08:35:03.000000000 +0200 @@ -198,8 +198,23 @@ extern int __swprintf_chk (wchar_t *__re __const wchar_t *__restrict __format, ...) __THROW /* __attribute__ ((__format__ (__wprintf__, 5, 6))) */; -#ifndef __cplusplus -/* XXX We might want to have support in gcc for swprintf. FIXME for C++. */ +extern int __REDIRECT_NTH (__swprintf_alias, + (wchar_t *__restrict __s, size_t __n, + __const wchar_t *__restrict __fmt, ...), + swprintf); + +#ifdef __va_arg_pack +__extern_always_inline int +__NTH (swprintf (wchar_t *__restrict __s, size_t __n, + __const wchar_t *__restrict __fmt, ...)) +{ + if (__bos (__s) != (size_t) -1 || __USE_FORTIFY_LEVEL > 1) + return __swprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1, __bos (__s), + __fmt, __va_arg_pack ()); + return __swprintf_alias (__s, __n, __fmt, __va_arg_pack ()); +} +#elif !defined __cplusplus +/* XXX We might want to have support in gcc for swprintf. */ # define swprintf(s, n, ...) \ (__bos (s) != (size_t) -1 || __USE_FORTIFY_LEVEL > 1 \ ? __swprintf_chk (s, n, __USE_FORTIFY_LEVEL - 1, __bos (s), __VA_ARGS__) \ @@ -212,7 +227,6 @@ extern int __vswprintf_chk (wchar_t *__r __gnuc_va_list __arg) __THROW /* __attribute__ ((__format__ (__wprintf__, 5, 0))) */; -#ifdef __cplusplus extern int __REDIRECT_NTH (__vswprintf_alias, (wchar_t *__restrict __s, size_t __n, __const wchar_t *__restrict __fmt, @@ -227,12 +241,6 @@ __NTH (vswprintf (wchar_t *__restrict __ __fmt, __ap); return __vswprintf_alias (__s, __n, __fmt, __ap); } -#else -# define vswprintf(s, n, fmt, ap) \ - (__bos (s) != (size_t) -1 || __USE_FORTIFY_LEVEL > 1 \ - ? __vswprintf_chk (s, n, __USE_FORTIFY_LEVEL - 1, __bos (s), fmt, ap) \ - : vswprintf (s, n, fmt, ap)) -#endif #if __USE_FORTIFY_LEVEL > 1 @@ -247,14 +255,26 @@ extern int __vfwprintf_chk (__FILE *__re extern int __vwprintf_chk (int __flag, __const wchar_t *__restrict __format, __gnuc_va_list __ap); -# ifndef __cplusplus -/* FIXME for C++. */ +# ifdef __va_arg_pack +__extern_always_inline int +wprintf (__const wchar_t *__restrict __fmt, ...) +{ + return __wprintf_chk (__USE_FORTIFY_LEVEL - 1, __fmt, __va_arg_pack ()); +} + +__extern_always_inline int +fwprintf (__FILE *__restrict __stream, __const wchar_t *__restrict __fmt, ...) +{ + return __fwprintf_chk (__stream, __USE_FORTIFY_LEVEL - 1, __fmt, + __va_arg_pack ()); +} +# elif !defined __cplusplus # define wprintf(...) \ __wprintf_chk (__USE_FORTIFY_LEVEL - 1, __VA_ARGS__) # define fwprintf(stream, ...) \ __fwprintf_chk (stream, __USE_FORTIFY_LEVEL - 1, __VA_ARGS__) # endif -# ifdef __cplusplus + __extern_always_inline int vwprintf (__const wchar_t *__restrict __fmt, __gnuc_va_list __ap) { @@ -267,12 +287,6 @@ vfwprintf (__FILE *__restrict __stream, { return __vfwprintf_chk (__stream, __USE_FORTIFY_LEVEL - 1, __fmt, __ap); } -# else -# define vwprintf(format, ap) \ - __vwprintf_chk (__USE_FORTIFY_LEVEL - 1, format, ap) -# define vfwprintf(stream, format, ap) \ - __vfwprintf_chk (stream, __USE_FORTIFY_LEVEL - 1, format, ap) -# endif #endif --- libc/debug/tst-chk1.c.jj 2007-09-03 13:14:30.000000000 +0200 +++ libc/debug/tst-chk1.c 2007-09-07 08:37:16.000000000 +0200 @@ -102,7 +102,7 @@ int num2 = 987654; chk_fail_ok = 0; \ FAIL (); \ } -#if __USE_FORTIFY_LEVEL >= 2 && !defined __cplusplus +#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 @@ -309,7 +309,7 @@ do_test (void) stpncpy (buf + 6, "cd", l0 + 5); CHK_FAIL_END -# ifndef __cplusplus +# if !defined __cplusplus || defined __va_arg_pack CHK_FAIL_START sprintf (buf + 8, "%d", num1); CHK_FAIL_END @@ -363,7 +363,7 @@ do_test (void) strncpy (a.buf1 + (O + 6), "X", l0 + 4); CHK_FAIL_END -# ifndef __cplusplus +# if !defined __cplusplus || defined __va_arg_pack CHK_FAIL_START sprintf (a.buf1 + (O + 7), "%d", num1); CHK_FAIL_END --- libio/bits/stdio.h.jj 2007-09-08 00:19:16.000000000 +0200 +++ libio/bits/stdio.h 2007-09-07 08:44:25.000000000 +0200 @@ -29,7 +29,9 @@ #ifdef __USE_EXTERN_INLINES -# ifndef __cplusplus +/* For -D_FORTIFY_SOURCE{,=2} bits/stdio2.h will define a different + inline. */ +# if !(__USE_FORTIFY_LEVEL > 0 && defined __extern_always_inline) /* Write formatted output to stdout from argument list ARG. */ __STDIO_INLINE int vprintf (__const char *__restrict __fmt, _G_va_list __arg) Jakub