[PATCH] static buffer overflow checking

Marcus Meissner meissner at suse.de
Wed Sep 10 15:12:43 CDT 2008


Hi,

This checks for a case, where buffers passed to MultiByteToWideChar
and WideChartoMultiByte do not match the size passed.

Usually a WCHAR buf[xx] is passed and sizeof(buf) as size.

This approach will not work with -O0, which might be a problem.

Ciao, Marcus
---
 include/winnls.h |   52 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 52 insertions(+), 0 deletions(-)

diff --git a/include/winnls.h b/include/winnls.h
index 50d6389..6fba285 100644
--- a/include/winnls.h
+++ b/include/winnls.h
@@ -788,6 +788,58 @@ WINBASEAPI BOOL        WINAPI SetThreadLocale(LCID);
 WINBASEAPI BOOL        WINAPI SetUserGeoID(GEOID);
 WINBASEAPI INT         WINAPI WideCharToMultiByte(UINT,DWORD,LPCWSTR,INT,LPSTR,INT,LPCSTR,LPBOOL);
 
+#if !defined(__GNUC__) || (__GNUC__ < 4)
+# undef __builtin_object_size
+# define __builtin_object_size(x,y) -1
+# undef __builtin_constant_p
+# define __builtin_constant_p(x) 0
+#endif
+
+/* __builtin_object_size does not evaluate the argument, so using it
+ * a second time in this macro is safe.
+ */
+extern void MBtoWC_incorrect_source_buffer_size(void);
+extern void MBtoWC_incorrect_destination_buffer_size__divide_by_sizeof_WCHAR(void);
+static inline INT
+WINAPI MultiByteToWideChar_ichk(
+	UINT cp,DWORD flags,
+	LPCSTR src,INT srclen,INT srcbuflen,
+	LPWSTR dst,INT dstlen,INT dstbuflen
+) {
+	if (__builtin_constant_p(srclen) && (srclen != -1) && (srcbuflen != -1) && (srcbuflen < srclen))
+		MBtoWC_incorrect_source_buffer_size();
+	if (__builtin_constant_p(dstlen) && (dstlen != -1)  && (dstbuflen != -1) && (dstbuflen/2 < dstlen))
+		MBtoWC_incorrect_destination_buffer_size__divide_by_sizeof_WCHAR();
+	return MultiByteToWideChar(cp,flags,src,srclen,dst,dstlen);
+}
+#define MultiByteToWideChar(cp,flags,src,srclen,dst,dstlen)	\
+	MultiByteToWideChar_ichk((cp),(flags),			\
+		(src),(srclen),(__builtin_object_size(src,0)),	\
+		(dst),(dstlen),(__builtin_object_size(dst,0))	\
+	)
+
+extern void WCtoMB_incorrect_source_buffer_size__divide_by_sizeof_WCHAR(void);
+extern void WCtoMB_incorrect_dest_buffer_size(void);
+static inline INT
+WINAPI WideCharToMultiByte_ichk(
+	UINT cp,DWORD flags,
+	LPCWSTR src,INT srclen,INT srcbuflen,
+	LPSTR dst,INT dstlen,INT dstbuflen,
+	LPCSTR xstr,LPBOOL b
+) {
+	if (__builtin_constant_p(srclen) && (srclen != -1) && (srcbuflen != -1) && (srcbuflen/2 < srclen))
+		WCtoMB_incorrect_source_buffer_size__divide_by_sizeof_WCHAR();
+	if (__builtin_constant_p(dstlen) && (dstlen != -1) && (dstbuflen != -1) && (dstbuflen < dstlen))
+		WCtoMB_incorrect_dest_buffer_size();
+	return WideCharToMultiByte(cp,flags,src,srclen,dst,dstlen,xstr,b);
+}
+#define WideCharToMultiByte(cp,flags,src,srclen,dst,dstlen,defchar,b)	\
+	WideCharToMultiByte_ichk((cp),(flags),				\
+		(src),(srclen),__builtin_object_size((src),0),		\
+		(dst),(dstlen),__builtin_object_size((dst),0),		\
+		(defchar),(b)							\
+	)
+
 #ifdef __cplusplus
 }
 #endif
-- 
1.5.6



More information about the wine-patches mailing list