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
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
---
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,