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