Calling open("foo", O_WRONLY|O_CREAT) without 3rd argument may (pseudo-)randomly set FILE_ATTRIBUTE_READONLY on the new file. With the attached patch, the attribute is always set in this case to show that something is wrong. A compile time warning is printed if possible.

I'm not yet sure how to handle the _O_CREAT constant from fcntl.h: directly use 0x0100 or define _O_CREAT in io.h. The patch uses the latter.

--
Christian

From b28b3f65eb8cb5d0412737493bd7e1f26a4c24ad Mon Sep 17 00:00:00 2001
From: Christian Franke <[email protected]>
Date: Sun, 29 Sep 2019 15:45:50 +0200
Subject: [PATCH] headers: _FORTIFY_SOURCE: Add _[w][s]open() and [s]open().

Always pass 0 as permission bits if this optional argument is missing.
Warn if argument is missing and _O_CREAT could be detected at compile time.
Warn if more than one optional argument is passed.

Signed-off-by: Christian Franke <[email protected]>
---
 mingw-w64-headers/crt/io.h | 91 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 91 insertions(+)

diff --git a/mingw-w64-headers/crt/io.h b/mingw-w64-headers/crt/io.h
index 30b5a7b8..fa486499 100644
--- a/mingw-w64-headers/crt/io.h
+++ b/mingw-w64-headers/crt/io.h
@@ -389,6 +389,97 @@ int read(int __fh, void * __dst, unsigned int __n)
 }
 #endif
 
+#if __MINGW_FORTIFY_VA_ARG
+
+#define _O_CREAT 0x0100
+
+_CRTIMP int __cdecl __mingw_call__open(const char *, int, ...) 
__MINGW_ASM_CRT_CALL(_open);
+_CRTIMP int __cdecl __mingw_call__open_warn_toomany(const char *, int, ...) 
__MINGW_ASM_CRT_CALL(_open)
+  __attribute__((__warning__("_open(): too many arguments")));
+_CRTIMP int __cdecl __mingw_call__open_warn_missing(const char *, int, ...) 
__MINGW_ASM_CRT_CALL(_open)
+  __attribute__((__warning__("_open(..._O_CREAT...): missing argument")));
+
+__mingw_bos_extern_ovr
+int _open(const char * __filename, int __flags, ...)
+{
+  if (__builtin_va_arg_pack_len() > 1)
+    return __mingw_call__open_warn_toomany(__filename, __flags, 
__builtin_va_arg_pack());
+  if (__builtin_va_arg_pack_len() < 1 && __builtin_constant_p(__flags) && 
(__flags & _O_CREAT))
+    return __mingw_call__open_warn_missing(__filename, __flags, 0);
+  if (__builtin_va_arg_pack_len() < 1)
+    return __mingw_call__open(__filename, __flags, 0);
+  return __mingw_call__open(__filename, __flags, __builtin_va_arg_pack());
+}
+
+_CRTIMP int __cdecl __mingw_call__sopen(const char *, int, int, ...) 
__MINGW_ASM_CRT_CALL(_sopen);
+_CRTIMP int __cdecl __mingw_call__sopen_warn_toomany(const char *, int, int, 
...) __MINGW_ASM_CRT_CALL(_sopen)
+  __attribute__((__warning__("_sopen(): too many arguments")));
+_CRTIMP int __cdecl __mingw_call__sopen_warn_missing(const char *, int, int, 
...) __MINGW_ASM_CRT_CALL(_sopen)
+  __attribute__((__warning__("_sopen(..._O_CREAT...): missing argument")));
+
+__mingw_bos_extern_ovr
+int _sopen(const char * __filename, int __flags, int __share, ...)
+{
+  if (__builtin_va_arg_pack_len() > 1)
+    return __mingw_call__sopen_warn_toomany(__filename, __flags, __share, 
__builtin_va_arg_pack());
+  if (__builtin_va_arg_pack_len() < 1 && __builtin_constant_p(__flags) && 
(__flags & _O_CREAT))
+    return __mingw_call__sopen_warn_missing(__filename, __flags, __share, 0);
+  if (__builtin_va_arg_pack_len() < 1)
+    return __mingw_call__sopen(__filename, __flags, __share, 0);
+  return __mingw_call__sopen(__filename, __flags, __share, 
__builtin_va_arg_pack());
+}
+
+_CRTIMP int __cdecl __mingw_call__wopen(const wchar_t *, int, ...) 
__MINGW_ASM_CRT_CALL(_wopen);
+_CRTIMP int __cdecl __mingw_call__wopen_warn_toomany(const wchar_t *, int, 
...) __MINGW_ASM_CRT_CALL(_wopen)
+  __attribute__((__warning__("_wopen(): too many arguments")));
+_CRTIMP int __cdecl __mingw_call__wopen_warn_missing(const wchar_t *, int, 
...) __MINGW_ASM_CRT_CALL(_wopen)
+  __attribute__((__warning__("_wopen(..._O_CREAT...): missing argument")));
+
+__mingw_bos_extern_ovr
+int _wopen(const wchar_t * __filename, int __flags, ...)
+{
+  if (__builtin_va_arg_pack_len() > 1)
+    return __mingw_call__wopen_warn_toomany(__filename, __flags, 
__builtin_va_arg_pack());
+  if (__builtin_va_arg_pack_len() < 1 && __builtin_constant_p(__flags) && 
(__flags & _O_CREAT))
+    return __mingw_call__wopen_warn_missing(__filename, __flags, 0);
+  if (__builtin_va_arg_pack_len() < 1)
+    return __mingw_call__wopen(__filename, __flags, 0);
+  return __mingw_call__wopen(__filename, __flags, __builtin_va_arg_pack());
+}
+
+_CRTIMP int __cdecl __mingw_call__wsopen(const wchar_t *, int, int, ...) 
__MINGW_ASM_CRT_CALL(_wsopen);
+_CRTIMP int __cdecl __mingw_call__wsopen_warn_toomany(const wchar_t *, int, 
int, ...) __MINGW_ASM_CRT_CALL(_wsopen)
+  __attribute__((__warning__("_wsopen(): too many arguments")));
+_CRTIMP int __cdecl __mingw_call__wsopen_warn_missing(const wchar_t *, int, 
int, ...) __MINGW_ASM_CRT_CALL(_wsopen)
+  __attribute__((__warning__("_wsopen(..._O_CREAT...): missing argument")));
+
+__mingw_bos_extern_ovr
+int _wsopen(const wchar_t * __filename, int __flags, int __share, ...)
+{
+  if (__builtin_va_arg_pack_len() > 1)
+    return __mingw_call__wsopen_warn_toomany(__filename, __flags, __share, 
__builtin_va_arg_pack());
+  if (__builtin_va_arg_pack_len() < 1 && __builtin_constant_p(__flags) && 
(__flags & _O_CREAT))
+    return __mingw_call__wsopen_warn_missing(__filename, __flags, __share, 0);
+  if (__builtin_va_arg_pack_len() < 1)
+    return __mingw_call__wsopen(__filename, __flags, __share, 0);
+  return __mingw_call__wsopen(__filename, __flags, __share, 
__builtin_va_arg_pack());
+}
+
+#ifndef NO_OLDNAMES
+__mingw_bos_extern_ovr
+int open(const char * __filename, int __flags, ...)
+{
+  return _open(__filename, __flags, __builtin_va_arg_pack());
+}
+
+__mingw_bos_extern_ovr
+int sopen(const char * __filename, int __flags, int __share, ...)
+{
+  return _sopen(__filename, __flags, __share, __builtin_va_arg_pack());
+}
+#endif
+
+#endif /* __MINGW_FORTIFY_VA_ARG */
 #endif /* __MINGW_FORTIFY_LEVEL > 0 */
 
 #ifdef __cplusplus
-- 
2.21.0

_______________________________________________
Mingw-w64-public mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public

Reply via email to