Liu Hao wrote:
在 2019/8/28 2:38, Christian Franke 写道:
These warnings are not printed for calls of the v*printf() functions,
only for the non-v variants. Delegating to non-v variants always
requires __builtin_va_arg_pack() which is not used in the existing code.

Adding the pragmas back only when GCC starts to warn about something
doesn't seem a good idea. Actually, it is the inconsistency that
concerns me so I'd remove them if I were you.

Done. Warnings will only occur if included with -I instead of -isystem.


..
This part looks good to me except the `mempcpy` thing.

New patch attached. New mempcpy() code now guarded by _GNU_SOURCE, old prototype unchanged.

Adds checks for functions without corresponding __builtin_*_chk(). This includes warnings if buffer overflow could be detected during compile time.

Functions added: memcpy_s(), wcscpy(), wcscat(), gets(), fgets(), fread(), tmpnam().
!__USE_MINGW_ANSI_STDIO: sprintf(), vsprintf()

Missing but easy to add: read(), memset_s(), strcpy_s(), strcat_s(), ...

--
Regards,
Christian

diff --git a/include/_mingw_mac.h b/include/_mingw_mac.h
index c5d1a0d..adca7bd 100644
--- a/include/_mingw_mac.h
+++ b/include/_mingw_mac.h
@@ -127,6 +127,9 @@
 #  define __MINGW_LSYMBOL(sym) sym
 #endif /* if __MINGW_USE_UNDERSCORE_PREFIX == 0 */
 
+#define __MINGW_ASM_CALL(func) 
__asm__(__MINGW64_STRINGIFY(__MINGW_USYMBOL(func)))
+#define __MINGW_ASM_CRT_CALL(func) __asm__(__STRINGIFY(func))
+
 #ifndef __PTRDIFF_TYPE__
 #  ifdef _WIN64
 #    define __PTRDIFF_TYPE__ long long int
@@ -291,6 +294,57 @@
 #  define __mingw_static_ovr __mingw_ovr
 #endif /* __cplusplus */
 
+#if __MINGW_GNUC_PREREQ(4, 3) && !defined(__clang__)
+#  define __mingw_attribute_artificial \
+     __attribute__((__artificial__))
+#  define __mingw_va_arg_pack_ovr __mingw_ovr \
+     __attribute__((__always_inline__,  __gnu_inline__)) \
+     __mingw_attribute_artificial
+#else
+#  define __mingw_attribute_artificial
+#  undef __mingw_va_arg_pack_ovr
+#endif
+
+#if _FORTIFY_SOURCE > 0 && __OPTIMIZE__ > 0 && __MINGW_GNUC_PREREQ(4, 1)
+#  if _FORTIFY_SOURCE > 1
+#    define __MINGW_FORTIFY_LEVEL 2
+#  else
+#    define __MINGW_FORTIFY_LEVEL 1
+#  endif
+#else
+#  define __MINGW_FORTIFY_LEVEL 0
+#endif
+
+#if __MINGW_FORTIFY_LEVEL > 0
+   /* Calling an function with __attribute__((__warning__("...")))
+      from a system include __inline__ function does not print
+      a warning unless caller has __attribute__((__artificial__)). */
+#  define __mingw_bos_declare \
+     void __cdecl __chk_fail(void) __attribute__((__noreturn__)); \
+     void __cdecl __mingw_chk_fail_warn(void) __MINGW_ASM_CALL(__chk_fail) \
+     __attribute__((__noreturn__)) \
+     __attribute__((__warning__("Buffer overflow detected")))
+#  define __mingw_bos(p) \
+     __builtin_object_size((p), (__MINGW_FORTIFY_LEVEL > 1))
+#  define __mingw_bos_known(p) \
+     (__mingw_bos(p) != (size_t)-1)
+#  define __mingw_bos_cond_chk(c) \
+     (__builtin_expect((c), 1) ? (void)0 : __chk_fail())
+#  define __mingw_bos_ptr_chk(p, n) \
+     __mingw_bos_cond_chk(!__mingw_bos_known(p) || __mingw_bos(p) >= 
(size_t)(n))
+#  define __mingw_bos_ptr_chk_warn(p, n) \
+     (__mingw_bos_known(p) && __builtin_constant_p((n)) && __mingw_bos(p) < 
(size_t)(n) \
+     ? __mingw_chk_fail_warn() : __mingw_bos_ptr_chk(p, n))
+#  define __mingw_bos_ovr __mingw_ovr \
+     __attribute__((__always_inline__, __gnu_inline__)) \
+     __mingw_attribute_artificial
+#  define __mingw_bos_extern_ovr extern __inline__ __cdecl \
+     __attribute__((__always_inline__, __gnu_inline__)) \
+     __mingw_attribute_artificial
+#else
+#  define __mingw_bos_ovr __mingw_ovr
+#endif /* __MINGW_FORTIFY_LEVEL > 0 */
+
 /* Enable workaround for ABI incompatibility on affected platforms */
 #ifndef WIDL_EXPLICIT_AGGREGATE_RETURNS
 #if defined(__GNUC__) && defined(__cplusplus) && (defined(__x86_64__) || 
defined(__i386__))
diff --git a/include/stdio.h b/include/stdio.h
index e183236..059bea1 100644
--- a/include/stdio.h
+++ b/include/stdio.h
@@ -156,6 +156,10 @@ extern FILE (* __MINGW_IMP_SYMBOL(_iob))[];        /* A 
pointer to an array of FILE */
 #endif
 #endif
 
+#if __MINGW_FORTIFY_LEVEL > 0
+__mingw_bos_declare;
+#endif
+
 #ifndef _STDIO_DEFINED
 extern
   __attribute__((__format__ (gnu_scanf, 2, 3))) __MINGW_ATTRIB_NONNULL(2)
@@ -349,6 +353,25 @@ int printf (const char *__format, ...)
   return __retval;
 }
 
+#ifdef __mingw_va_arg_pack_ovr
+
+__mingw_va_arg_pack_ovr
+__attribute__((__format__ (gnu_printf, 2, 3))) __MINGW_ATTRIB_NONNULL(2)
+int sprintf (char *__stream, const char *__format, ...)
+{
+#if __MINGW_FORTIFY_LEVEL > 0
+  if (__mingw_bos_known(__stream)) {
+    int __retval = __mingw_snprintf( __stream, __mingw_bos(__stream), 
__format, __builtin_va_arg_pack() );
+    if (__retval >= 0)
+      __mingw_bos_ptr_chk(__stream, (size_t)__retval + 1);
+    return __retval;
+  }
+#endif
+  return __mingw_sprintf( __stream, __format, __builtin_va_arg_pack() );
+}
+
+#else /* !__mingw_va_arg_pack_ovr */
+
 __mingw_ovr
 __attribute__((__format__ (gnu_printf, 2, 3))) __MINGW_ATTRIB_NONNULL(2)
 int sprintf (char *__stream, const char *__format, ...)
@@ -360,6 +383,8 @@ int sprintf (char *__stream, const char *__format, ...)
   return __retval;
 }
 
+#endif /* __mingw_va_arg_pack_ovr */
+
 __mingw_ovr
 __attribute__((__format__ (gnu_printf, 2, 0))) __MINGW_ATTRIB_NONNULL(2)
 int vfprintf (FILE *__stream, const char *__format, __builtin_va_list 
__local_argv)
@@ -374,13 +399,36 @@ int vprintf (const char *__format, __builtin_va_list 
__local_argv)
   return __mingw_vfprintf( stdout, __format, __local_argv );
 }
 
-__mingw_ovr
+__mingw_bos_ovr
 __attribute__((__format__ (gnu_printf, 2, 0))) __MINGW_ATTRIB_NONNULL(2)
 int vsprintf (char *__stream, const char *__format, __builtin_va_list 
__local_argv)
 {
+#if __MINGW_FORTIFY_LEVEL > 0
+  if (__mingw_bos_known(__stream)) {
+    int __retval = __mingw_vsnprintf( __stream, __mingw_bos(__stream), 
__format, __local_argv );
+    if (__retval >= 0)
+      __mingw_bos_ptr_chk(__stream, (size_t)__retval + 1);
+    return __retval;
+  }
+#endif
   return __mingw_vsprintf( __stream, __format, __local_argv );
 }
 /* #ifndef __NO_ISOCEXT */  /* externs in libmingwex.a */
+
+#ifdef __mingw_va_arg_pack_ovr
+
+__mingw_va_arg_pack_ovr
+__attribute__((__format__ (gnu_printf, 3, 4))) __MINGW_ATTRIB_NONNULL(3)
+int snprintf (char *__stream, size_t __n, const char *__format, ...)
+{
+#if __MINGW_FORTIFY_LEVEL > 0
+  __mingw_bos_ptr_chk_warn(__stream, __n);
+#endif
+  return __mingw_snprintf( __stream, __n, __format, __builtin_va_arg_pack() );
+}
+
+#else /* !__mingw_va_arg_pack_ovr */
+
 __mingw_ovr
 __attribute__((__format__ (gnu_printf, 3, 4))) __MINGW_ATTRIB_NONNULL(3)
 int snprintf (char *__stream, size_t __n, const char *__format, ...)
@@ -392,10 +440,15 @@ int snprintf (char *__stream, size_t __n, const char 
*__format, ...)
   return __retval;
 }
 
-__mingw_ovr
+#endif /* __mingw_va_arg_pack_ovr */
+
+__mingw_bos_ovr
 __attribute__((__format__ (gnu_printf, 3, 0))) __MINGW_ATTRIB_NONNULL(3)
 int vsnprintf (char *__stream, size_t __n, const char *__format, 
__builtin_va_list __local_argv)
 {
+#if __MINGW_FORTIFY_LEVEL > 0
+  __mingw_bos_ptr_chk_warn(__stream, __n);
+#endif
   return __mingw_vsnprintf( __stream, __n, __format, __local_argv );
 }
 
@@ -732,6 +785,45 @@ int vsnprintf (char *__stream, size_t __n, const char 
*__format, __builtin_va_li
   _CRTIMP int __cdecl _vsnprintf(char * __restrict__ _Dest,size_t _Count,const 
char * __restrict__ _Format,va_list _Args) __MINGW_ATTRIB_DEPRECATED_SEC_WARN;
 #endif
 
+#if __MINGW_FORTIFY_LEVEL > 0
+
+char * __cdecl __gets_chk(char *, size_t);
+char * __cdecl __mingw_call_gets(char *) __MINGW_ASM_CALL(gets);
+char * __cdecl __mingw_call_fgets(char * __restrict__, int, FILE * 
__restrict__) __MINGW_ASM_CALL(fgets);
+size_t __cdecl __mingw_call_fread(void * __restrict__, size_t, size_t, FILE * 
__restrict__) __MINGW_ASM_CALL(fread);
+char * __cdecl __mingw_call_tmpnam(char *) __MINGW_ASM_CALL(tmpnam);
+
+__mingw_bos_extern_ovr
+char * gets(char * __dst)
+{
+  if (__mingw_bos_known(__dst))
+    return __gets_chk(__dst, __mingw_bos(__dst));
+  return __mingw_call_gets(__dst);
+}
+
+__mingw_bos_extern_ovr
+char * fgets(char * __restrict__ __dst, int __n, FILE * __restrict__ __f)
+{
+  __mingw_bos_ptr_chk_warn(__dst, __n);
+  return __mingw_call_fgets(__dst, __n, __f);
+}
+
+__mingw_bos_extern_ovr
+size_t fread(void * __restrict__ __dst, size_t __sz, size_t __n, FILE * 
__restrict__ __f)
+{
+  __mingw_bos_ptr_chk_warn(__dst, __sz * __n);
+  return __mingw_call_fread(__dst, __sz, __n, __f);
+}
+
+__mingw_bos_extern_ovr
+char * tmpnam(char * __dst)
+{
+  __mingw_bos_ptr_chk_warn(__dst, L_tmpnam);
+  return __mingw_call_tmpnam(__dst);
+}
+
+#endif /* __MINGW_FORTIFY_LEVEL > 0 */
+
 #if __USE_MINGW_ANSI_STDIO == 0
 
 #ifdef _UCRT
@@ -765,10 +857,13 @@ int vsnprintf (char *__stream, size_t __n, const char 
*__format, __builtin_va_li
   int __cdecl __ms_vsnprintf(char * __restrict__ d,size_t n,const char * 
__restrict__ format,va_list arg)
     __MINGW_ATTRIB_DEPRECATED_MSVC2005 __MINGW_ATTRIB_DEPRECATED_SEC_WARN;
 
-  __mingw_ovr
+  __mingw_bos_ovr
   __attribute__((__format__ (ms_printf, 3, 0))) __MINGW_ATTRIB_NONNULL(3)
   int vsnprintf (char * __restrict__ __stream, size_t __n, const char * 
__restrict__ __format, va_list __local_argv)
   {
+#if __MINGW_FORTIFY_LEVEL > 0
+    __mingw_bos_ptr_chk_warn(__stream, __n);
+#endif
     return __ms_vsnprintf (__stream, __n, __format, __local_argv);
   }
 
@@ -776,6 +871,20 @@ int vsnprintf (char *__stream, size_t __n, const char 
*__format, __builtin_va_li
   int __cdecl __ms_snprintf(char * __restrict__ s, size_t n, const char * 
__restrict__  format, ...);
 
 #ifndef __NO_ISOCEXT
+#ifdef __mingw_va_arg_pack_ovr
+
+__mingw_va_arg_pack_ovr
+__attribute__((__format__ (ms_printf, 3, 4))) __MINGW_ATTRIB_NONNULL(3)
+int snprintf (char * __restrict__ __stream, size_t __n, const char * 
__restrict__ __format, ...)
+{
+#if __MINGW_FORTIFY_LEVEL > 0
+  __mingw_bos_ptr_chk_warn(__stream, __n);
+#endif
+  return __ms_snprintf(__stream, __n, __format, __builtin_va_arg_pack());
+}
+
+#else /* !__mingw_va_arg_pack_ovr */
+
 __mingw_ovr
 __attribute__((__format__ (ms_printf, 3, 4))) __MINGW_ATTRIB_NONNULL(3)
 int snprintf (char * __restrict__ __stream, size_t __n, const char * 
__restrict__ __format, ...)
@@ -786,8 +895,43 @@ int snprintf (char * __restrict__ __stream, size_t __n, 
const char * __restrict_
   __builtin_va_end( __local_argv );
   return __retval;
 }
+
+#endif /* !__mingw_va_arg_pack_ovr */
 #endif /* !__NO_ISOCEXT */
 
+#if __MINGW_FORTIFY_LEVEL > 0
+
+int __cdecl __mingw_call_ms_sprintf(char * __restrict__, const char * 
__restrict__, ...) __MINGW_ASM_CALL(sprintf);
+int __cdecl __mingw_call_ms_vsprintf(char * __restrict__, const char * 
__restrict__, va_list) __MINGW_ASM_CALL(vsprintf);
+
+__mingw_bos_extern_ovr
+__attribute__((__format__ (ms_printf, 2, 3))) __MINGW_ATTRIB_NONNULL(2)
+int sprintf (char * __restrict__ __stream, const char * __restrict__ __format, 
...)
+{
+  if (__mingw_bos_known(__stream)) {
+    int __retval = __ms_snprintf( __stream, __mingw_bos(__stream), __format, 
__builtin_va_arg_pack() );
+    if (__retval >= 0)
+      __mingw_bos_ptr_chk(__stream, (size_t)__retval + 1);
+    return __retval;
+  }
+  return __mingw_call_ms_sprintf( __stream, __format, __builtin_va_arg_pack() 
);
+}
+
+__mingw_bos_extern_ovr
+__attribute__((__format__ (ms_printf, 2, 0))) __MINGW_ATTRIB_NONNULL(2)
+int vsprintf (char * __restrict__ __stream, const char * __restrict__ 
__format, va_list __local_argv)
+{
+  if (__mingw_bos_known(__stream)) {
+    int __retval = __ms_vsnprintf( __stream, __mingw_bos(__stream), __format, 
__local_argv );
+    if (__retval >= 0)
+      __mingw_bos_ptr_chk(__stream, (size_t)__retval + 1);
+    return __retval;
+  }
+  return __mingw_call_ms_vsprintf( __stream, __format, __local_argv );
+}
+
+#endif /* __MINGW_FORTIFY_LEVEL > 0 */
+
 #pragma pop_macro ("vsnprintf")
 #pragma pop_macro ("snprintf")
 #ifdef __GNUC__
@@ -949,6 +1093,21 @@ int vwprintf (const wchar_t *__format, __builtin_va_list 
__local_argv)
 }
 
 #ifndef __NO_ISOCEXT  /* externs in libmingwex.a */
+
+#ifdef __mingw_va_arg_pack_ovr
+
+__mingw_va_arg_pack_ovr
+/* __attribute__((__format__ (gnu_wprintf, 3, 4))) */ __MINGW_ATTRIB_NONNULL(3)
+int snwprintf (wchar_t *__stream, size_t __n, const wchar_t *__format, ...)
+{
+#if __MINGW_FORTIFY_LEVEL > 0
+  __mingw_bos_ptr_chk_warn(__stream, __n * sizeof(wchar_t));
+#endif
+  return __mingw_snwprintf( __stream, __n, __format, __builtin_va_arg_pack() );
+}
+
+#else /* !__mingw_va_arg_pack_ovr */
+
 __mingw_ovr
 /* __attribute__((__format__ (gnu_wprintf, 3, 4))) */ __MINGW_ATTRIB_NONNULL(3)
 int snwprintf (wchar_t *__stream, size_t __n, const wchar_t *__format, ...)
@@ -960,10 +1119,15 @@ int snwprintf (wchar_t *__stream, size_t __n, const 
wchar_t *__format, ...)
   return __retval;
 }
 
-__mingw_ovr
+#endif /* __mingw_va_arg_pack_ovr */
+
+__mingw_bos_ovr
 /* __attribute__((__format__ (gnu_wprintf, 3, 0))) */ __MINGW_ATTRIB_NONNULL(3)
 int vsnwprintf (wchar_t *__stream, size_t __n, const wchar_t *__format, 
__builtin_va_list __local_argv)
 {
+#if __MINGW_FORTIFY_LEVEL > 0
+  __mingw_bos_ptr_chk_warn(__stream, __n * sizeof(wchar_t));
+#endif
   return __mingw_vsnwprintf( __stream, __n, __format, __local_argv );
 }
 #endif /* __NO_ISOCEXT */
diff --git a/include/string.h b/include/string.h
index c8c8018..3fe4866 100644
--- a/include/string.h
+++ b/include/string.h
@@ -188,4 +188,98 @@ extern "C" {
 #endif
 
 #include <sec_api/string_s.h>
+
+#if __MINGW_FORTIFY_LEVEL > 0
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+__mingw_bos_declare;
+
+__mingw_bos_extern_ovr
+void * memcpy(void * __restrict__ __dst, const void * __restrict__ __src, 
size_t __n)
+{
+  return __builtin___memcpy_chk(__dst, __src, __n, __mingw_bos(__dst));
+}
+
+__mingw_bos_extern_ovr
+void * memset(void * __dst, int __val, size_t __n)
+{
+  return __builtin___memset_chk(__dst, __val, __n, __mingw_bos(__dst));
+}
+
+__mingw_bos_extern_ovr
+void * memmove(void * __dst, const void * __src, size_t __n)
+{
+  return __builtin___memmove_chk(__dst, __src, __n, __mingw_bos(__dst));
+}
+
+#ifdef _GNU_SOURCE
+__mingw_bos_extern_ovr
+void * mempcpy(void * __dst, const void * __src, size_t __n)
+{
+  return __builtin___mempcpy_chk(__dst, __src, __n, __mingw_bos(__dst));
+}
+#endif /* _GNU_SOURCE */
+
+__mingw_bos_extern_ovr
+char * strcpy(char * __restrict__ __dst, const char * __restrict__ __src)
+{
+  return __builtin___strcpy_chk(__dst, __src, __mingw_bos(__dst));
+}
+
+__mingw_bos_extern_ovr
+char * strcat(char * __restrict__ __dst, const char * __restrict__ __src)
+{
+  return __builtin___strcat_chk(__dst, __src, __mingw_bos(__dst));
+}
+
+__mingw_bos_extern_ovr
+char * strncpy(char * __restrict__ __dst, const char * __restrict__ __src, 
size_t __n)
+{
+  return __builtin___strncpy_chk(__dst, __src, __n, __mingw_bos(__dst));
+}
+
+__mingw_bos_extern_ovr
+char * strncat(char * __restrict__ __dst, const char * __restrict__ __src, 
size_t __n)
+{
+  return __builtin___strncat_chk(__dst, __src, __n, __mingw_bos(__dst));
+}
+
+_SECIMP errno_t __cdecl __mingw_call_memcpy_s(void *, size_t, const void *, 
size_t) __MINGW_ASM_CRT_CALL(memcpy_s);
+wchar_t * __cdecl __mingw_call_wcscpy(wchar_t * __restrict__, const wchar_t * 
__restrict__) __MINGW_ASM_CALL(wcscpy);
+wchar_t * __cdecl __mingw_call_wcscat(wchar_t * __restrict__, const wchar_t * 
__restrict__) __MINGW_ASM_CALL(wcscat);
+
+__mingw_bos_extern_ovr
+errno_t memcpy_s(void * __dst, size_t __os, const void * __src, size_t __n)
+{
+  __mingw_bos_ptr_chk_warn(__dst, __os);
+  return __mingw_call_memcpy_s(__dst, __os, __src, __n);
+}
+
+__mingw_bos_extern_ovr
+wchar_t * wcscpy(wchar_t * __restrict__ __dst, const wchar_t * __restrict__ 
__src)
+{
+  if (__mingw_bos_known(__dst)) {
+    __mingw_bos_cond_chk(!wcscpy_s(__dst, __mingw_bos(__dst) / 
sizeof(wchar_t), __src));
+    return __dst;
+  }
+  return __mingw_call_wcscpy(__dst, __src);
+}
+
+__mingw_bos_extern_ovr
+wchar_t * wcscat(wchar_t * __restrict__ __dst, const wchar_t * __restrict__ 
__src)
+{
+  if (__mingw_bos_known(__dst)) {
+    __mingw_bos_cond_chk(!wcscat_s(__dst, __mingw_bos(__dst) / 
sizeof(wchar_t), __src));
+    return __dst;
+  }
+  return __mingw_call_wcscat(__dst, __src);
+}
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __MINGW_FORTIFY_LEVEL > 0 */
+
 #endif
_______________________________________________
Mingw-w64-public mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public

Reply via email to