public inbox for libc-hacker@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] Further -D_FORTIFY_SOURCE={,=2} C++ support
@ 2007-09-07 22:34 Jakub Jelinek
  0 siblings, 0 replies; only message in thread
From: Jakub Jelinek @ 2007-09-07 22:34 UTC (permalink / raw)
  To: Ulrich Drepper; +Cc: Glibc hackers

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  <jakub@redhat.com>

	* 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

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2007-09-07 22:34 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-09-07 22:34 [PATCH] Further -D_FORTIFY_SOURCE={,=2} C++ support Jakub Jelinek

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).