[PATCH] annotate allocator functions with gcc allocation size attribute

Marcus Meissner marcus at jet.franken.de
Sat Aug 30 04:57:51 CDT 2008


Hi,

GCC 4.3 allows annotating malloc(size) style functions with
an attribute that marks the size of the returned buffer.

alloca(), malloc(), calloc() are marked with up by default,
others need to be marked up with __attribute__(alloc_size()).

This allows buffer overrun checking for known-sized buffers
when calling memcpy(), strcpy() and similar.

I also have patches to add buffer overflow checking for MBtoWC and WCtoMB,
and lstr*W functions.

Ciao, Marcus
---
 dlls/comctl32/comctl32.h         |    4 ++--
 dlls/comdlg32/cdlg.h             |    2 +-
 dlls/hhctrl.ocx/hhctrl.h         |    8 ++++----
 dlls/localspl/localspl_private.h |    2 +-
 dlls/mshtml/mshtml_private.h     |    8 ++++----
 dlls/msi/msipriv.h               |    6 +++++-
 dlls/oleaut32/typelib.c          |    2 ++
 dlls/riched20/editor.h           |    4 ++--
 include/objbase.h                |    2 +-
 include/rpcndr.h                 |    2 +-
 include/shlobj.h                 |    2 +-
 include/winbase.h                |   12 ++++++------
 include/wincrypt.h               |    4 ++--
 include/windef.h                 |    6 ++++++
 include/winternl.h               |    2 +-
 15 files changed, 39 insertions(+), 27 deletions(-)

diff --git a/dlls/comctl32/comctl32.h b/dlls/comctl32/comctl32.h
index 2c8e538..597e3b1 100644
--- a/dlls/comctl32/comctl32.h
+++ b/dlls/comctl32/comctl32.h
@@ -175,8 +175,8 @@ typedef struct
 
 /* undocumented functions */
 
-LPVOID WINAPI Alloc (DWORD);
-LPVOID WINAPI ReAlloc (LPVOID, DWORD);
+LPVOID WINAPI Alloc (DWORD) ALLOC_SIZE(1);
+LPVOID WINAPI ReAlloc (LPVOID, DWORD) ALLOC_SIZE(2);
 BOOL   WINAPI Free (LPVOID);
 DWORD  WINAPI GetSize (LPVOID);
 
diff --git a/dlls/comdlg32/cdlg.h b/dlls/comdlg32/cdlg.h
index d0c0591..c28a6c4 100644
--- a/dlls/comdlg32/cdlg.h
+++ b/dlls/comdlg32/cdlg.h
@@ -30,7 +30,7 @@
 extern HINSTANCE	COMDLG32_hInstance;
 
 void	COMDLG32_SetCommDlgExtendedError(DWORD err);
-LPVOID	COMDLG32_AllocMem(int size);
+LPVOID	COMDLG32_AllocMem(int size) ALLOC_SIZE(1);
 
 /* handle<-handle16 conversion */
 #define HINSTANCE_32(h16)           ((HINSTANCE)(ULONG_PTR)(h16))
diff --git a/dlls/hhctrl.ocx/hhctrl.h b/dlls/hhctrl.ocx/hhctrl.h
index 6f7c96b..872a422 100644
--- a/dlls/hhctrl.ocx/hhctrl.h
+++ b/dlls/hhctrl.ocx/hhctrl.h
@@ -141,22 +141,22 @@ BOOL NavigateToChm(HHInfo*,LPCWSTR,LPCWSTR);
 
 /* memory allocation functions */
 
-static inline void *heap_alloc(size_t len)
+static inline void ALLOC_SIZE(1) *heap_alloc(size_t len)
 {
     return HeapAlloc(GetProcessHeap(), 0, len);
 }
 
-static inline void *heap_alloc_zero(size_t len)
+static inline void ALLOC_SIZE(1) *heap_alloc_zero(size_t len)
 {
     return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
 }
 
-static inline void *heap_realloc(void *mem, size_t len)
+static inline void ALLOC_SIZE(2) *heap_realloc(void *mem, size_t len)
 {
     return HeapReAlloc(GetProcessHeap(), 0, mem, len);
 }
 
-static inline void *heap_realloc_zero(void *mem, size_t len)
+static inline void ALLOC_SIZE(2) *heap_realloc_zero(void *mem, size_t len)
 {
     return HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, mem, len);
 }
diff --git a/dlls/localspl/localspl_private.h b/dlls/localspl/localspl_private.h
index 7d76429..b420ae3 100644
--- a/dlls/localspl/localspl_private.h
+++ b/dlls/localspl/localspl_private.h
@@ -51,7 +51,7 @@ extern HINSTANCE LOCALSPL_hInstance;
 
 /* ## Memory allocation functions ## */
 
-static inline void *heap_alloc( size_t len )
+static inline void ALLOC_SIZE(1) *heap_alloc( size_t len )
 {
     return HeapAlloc( GetProcessHeap(), 0, len );
 }
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h
index 85329c5..fc23d24 100644
--- a/dlls/mshtml/mshtml_private.h
+++ b/dlls/mshtml/mshtml_private.h
@@ -490,7 +490,7 @@ void hlink_frame_navigate(HTMLDocument*,IHlinkFrame*,LPCWSTR,nsIInputStream*,DWO
 void call_property_onchanged(ConnectionPoint*,DISPID);
 HRESULT call_set_active_object(IOleInPlaceUIWindow*,IOleInPlaceActiveObject*);
 
-void *nsalloc(size_t);
+void *nsalloc(size_t) ALLOC_SIZE(1);
 void nsfree(void*);
 
 void nsACString_Init(nsACString*,const char*);
@@ -654,17 +654,17 @@ extern LONG module_ref;
 
 /* memory allocation functions */
 
-static inline void *heap_alloc(size_t len)
+static inline void ALLOC_SIZE(1) *heap_alloc(size_t len)
 {
     return HeapAlloc(GetProcessHeap(), 0, len);
 }
 
-static inline void *heap_alloc_zero(size_t len)
+static inline void ALLOC_SIZE(1) *heap_alloc_zero(size_t len)
 {
     return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
 }
 
-static inline void *heap_realloc(void *mem, size_t len)
+static inline void ALLOC_SIZE(2) *heap_realloc(void *mem, size_t len)
 {
     return HeapReAlloc(GetProcessHeap(), 0, mem, len);
 }
diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h
index 2f54cca..ced9119 100644
--- a/dlls/msi/msipriv.h
+++ b/dlls/msi/msipriv.h
@@ -1040,21 +1040,25 @@ extern const WCHAR cszRootDrive[];
 extern const WCHAR cszbs[];
 
 /* memory allocation macro functions */
-static inline void *msi_alloc( size_t len )
+static void *msi_alloc( size_t len ) ALLOC_SIZE(1);
+static inline void *msi_alloc( size_t len ) 
 {
     return HeapAlloc( GetProcessHeap(), 0, len );
 }
 
+static void *msi_alloc_zero( size_t len ) ALLOC_SIZE(1);
 static inline void *msi_alloc_zero( size_t len )
 {
     return HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, len );
 }
 
+static void *msi_realloc( void *mem, size_t len ) ALLOC_SIZE(2);
 static inline void *msi_realloc( void *mem, size_t len )
 {
     return HeapReAlloc( GetProcessHeap(), 0, mem, len );
 }
 
+static void *msi_realloc_zero( void *mem, size_t len ) ALLOC_SIZE(2);
 static inline void *msi_realloc_zero( void *mem, size_t len )
 {
     return HeapReAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, mem, len );
diff --git a/dlls/oleaut32/typelib.c b/dlls/oleaut32/typelib.c
index d7139d2..227be7f 100644
--- a/dlls/oleaut32/typelib.c
+++ b/dlls/oleaut32/typelib.c
@@ -1357,6 +1357,8 @@ static void TLB_abort(void)
 {
     DebugBreak();
 }
+
+static void * TLB_Alloc(unsigned size) ALLOC_SIZE(1);
 static void * TLB_Alloc(unsigned size)
 {
     void * ret;
diff --git a/dlls/riched20/editor.h b/dlls/riched20/editor.h
index 5e73c97..1da6e16 100644
--- a/dlls/riched20/editor.h
+++ b/dlls/riched20/editor.h
@@ -23,7 +23,7 @@
 
 extern HANDLE me_heap;
 
-static inline void *heap_alloc( size_t len )
+static inline void ALLOC_SIZE(1) *heap_alloc( size_t len )
 {
     return HeapAlloc( me_heap, 0, len );
 }
@@ -33,7 +33,7 @@ static inline BOOL heap_free( void *ptr )
     return HeapFree( me_heap, 0, ptr );
 }
 
-static inline void *heap_realloc( void *ptr, size_t len )
+static inline void ALLOC_SIZE(2) *heap_realloc( void *ptr, size_t len )
 {
     return HeapReAlloc( me_heap, 0, ptr, len );
 }
diff --git a/include/objbase.h b/include/objbase.h
index 6a07a25..f3b5ba2 100644
--- a/include/objbase.h
+++ b/include/objbase.h
@@ -343,7 +343,7 @@ HRESULT WINAPI CoGetInstanceFromFile(COSERVERINFO* pServerInfo, CLSID* pClsid, I
 HRESULT WINAPI CoGetInstanceFromIStorage(COSERVERINFO* pServerInfo, CLSID* pClsid, IUnknown* punkOuter, DWORD dwClsCtx, IStorage* pstg, DWORD dwCount, MULTI_QI* pResults);
 
 HRESULT WINAPI CoGetMalloc(DWORD dwMemContext, LPMALLOC* lpMalloc);
-LPVOID WINAPI CoTaskMemAlloc(ULONG size);
+LPVOID WINAPI CoTaskMemAlloc(ULONG size) ALLOC_SIZE(1);
 void WINAPI CoTaskMemFree(LPVOID ptr);
 LPVOID WINAPI CoTaskMemRealloc(LPVOID ptr, ULONG size);
 
diff --git a/include/rpcndr.h b/include/rpcndr.h
index 9bf2840..4fd1ab9 100644
--- a/include/rpcndr.h
+++ b/include/rpcndr.h
@@ -652,7 +652,7 @@ RPCRTAPI LONG RPC_ENTRY
   NdrDcomAsyncStubCall( struct IRpcStubBuffer* pThis, struct IRpcChannelBuffer* pChannel, PRPC_MESSAGE pRpcMsg, DWORD * pdwStubPhase );
 
 RPCRTAPI void* RPC_ENTRY
-  NdrAllocate( PMIDL_STUB_MESSAGE pStubMsg, size_t Len );
+  NdrAllocate( PMIDL_STUB_MESSAGE pStubMsg, size_t Len ) ALLOC_SIZE(2);
 
 RPCRTAPI void RPC_ENTRY
   NdrClearOutParameters( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, void *ArgAddr );
diff --git a/include/shlobj.h b/include/shlobj.h
index 3e6e7a5..f1dde00 100644
--- a/include/shlobj.h
+++ b/include/shlobj.h
@@ -40,7 +40,7 @@ DECLARE_HANDLE(HPSXA);
 #endif
 
 UINT         WINAPI SHAddFromPropSheetExtArray(HPSXA,LPFNADDPROPSHEETPAGE,LPARAM);
-LPVOID       WINAPI SHAlloc(ULONG);
+LPVOID       WINAPI SHAlloc(ULONG) ALLOC_SIZE(1);
 HRESULT      WINAPI SHCoCreateInstance(LPCWSTR,const CLSID*,IUnknown*,REFIID,LPVOID*);
 HPSXA        WINAPI SHCreatePropSheetExtArray(HKEY,LPCWSTR,UINT);
 HPSXA        WINAPI SHCreatePropSheetExtArrayEx(HKEY,LPCWSTR,UINT,IDataObject*);
diff --git a/include/winbase.h b/include/winbase.h
index f7ccb8c..5969558 100644
--- a/include/winbase.h
+++ b/include/winbase.h
@@ -1744,7 +1744,7 @@ WINBASEAPI UINT        WINAPI GetWindowsDirectoryW(LPWSTR,UINT);
 WINBASEAPI ATOM        WINAPI GlobalAddAtomA(LPCSTR);
 WINBASEAPI ATOM        WINAPI GlobalAddAtomW(LPCWSTR);
 #define                       GlobalAddAtom WINELIB_NAME_AW(GlobalAddAtom)
-WINBASEAPI HGLOBAL     WINAPI GlobalAlloc(UINT,SIZE_T);
+WINBASEAPI HGLOBAL     WINAPI GlobalAlloc(UINT,SIZE_T) ALLOC_SIZE(2);
 WINBASEAPI SIZE_T      WINAPI GlobalCompact(DWORD);
 WINBASEAPI ATOM        WINAPI GlobalDeleteAtom(ATOM);
 WINBASEAPI ATOM        WINAPI GlobalFindAtomA(LPCSTR);
@@ -1760,20 +1760,20 @@ WINBASEAPI HGLOBAL     WINAPI GlobalHandle(LPCVOID);
 WINBASEAPI LPVOID      WINAPI GlobalLock(HGLOBAL);
 WINBASEAPI VOID        WINAPI GlobalMemoryStatus(LPMEMORYSTATUS);
 WINBASEAPI BOOL        WINAPI GlobalMemoryStatusEx(LPMEMORYSTATUSEX);
-WINBASEAPI HGLOBAL     WINAPI GlobalReAlloc(HGLOBAL,SIZE_T,UINT);
+WINBASEAPI HGLOBAL     WINAPI GlobalReAlloc(HGLOBAL,SIZE_T,UINT) ALLOC_SIZE(3);
 WINBASEAPI SIZE_T      WINAPI GlobalSize(HGLOBAL);
 WINBASEAPI VOID        WINAPI GlobalUnfix(HGLOBAL);
 WINBASEAPI BOOL        WINAPI GlobalUnlock(HGLOBAL);
 WINBASEAPI BOOL        WINAPI GlobalUnWire(HGLOBAL);
 WINBASEAPI LPVOID      WINAPI GlobalWire(HGLOBAL);
 #define                       HasOverlappedCompleted(lpOverlapped) ((lpOverlapped)->Internal != STATUS_PENDING)
-WINBASEAPI LPVOID      WINAPI HeapAlloc(HANDLE,DWORD,SIZE_T);
+WINBASEAPI LPVOID      WINAPI HeapAlloc(HANDLE,DWORD,SIZE_T) ALLOC_SIZE(3);
 WINBASEAPI SIZE_T      WINAPI HeapCompact(HANDLE,DWORD);
 WINBASEAPI HANDLE      WINAPI HeapCreate(DWORD,SIZE_T,SIZE_T);
 WINBASEAPI BOOL        WINAPI HeapDestroy(HANDLE);
 WINBASEAPI BOOL        WINAPI HeapFree(HANDLE,DWORD,LPVOID);
 WINBASEAPI BOOL        WINAPI HeapLock(HANDLE);
-WINBASEAPI LPVOID      WINAPI HeapReAlloc(HANDLE,DWORD,LPVOID,SIZE_T);
+WINBASEAPI LPVOID      WINAPI HeapReAlloc(HANDLE,DWORD,LPVOID,SIZE_T) ALLOC_SIZE(4);
 WINBASEAPI BOOL        WINAPI HeapQueryInformation(HANDLE,HEAP_INFORMATION_CLASS,PVOID,SIZE_T,PSIZE_T);
 WINBASEAPI BOOL        WINAPI HeapSetInformation(HANDLE,HEAP_INFORMATION_CLASS,PVOID,SIZE_T);
 WINBASEAPI SIZE_T      WINAPI HeapSize(HANDLE,DWORD,LPCVOID);
@@ -1821,13 +1821,13 @@ WINBASEAPI HMODULE     WINAPI LoadLibraryExW(LPCWSTR,HANDLE,DWORD);
 #define                       LoadLibraryEx WINELIB_NAME_AW(LoadLibraryEx)
 WINBASEAPI HINSTANCE   WINAPI LoadModule(LPCSTR,LPVOID);
 WINBASEAPI HGLOBAL     WINAPI LoadResource(HMODULE,HRSRC);
-WINBASEAPI HLOCAL      WINAPI LocalAlloc(UINT,SIZE_T);
+WINBASEAPI HLOCAL      WINAPI LocalAlloc(UINT,SIZE_T) ALLOC_SIZE(2);
 WINBASEAPI SIZE_T      WINAPI LocalCompact(UINT);
 WINBASEAPI UINT        WINAPI LocalFlags(HLOCAL);
 WINBASEAPI HLOCAL      WINAPI LocalFree(HLOCAL);
 WINBASEAPI HLOCAL      WINAPI LocalHandle(LPCVOID);
 WINBASEAPI LPVOID      WINAPI LocalLock(HLOCAL);
-WINBASEAPI HLOCAL      WINAPI LocalReAlloc(HLOCAL,SIZE_T,UINT);
+WINBASEAPI HLOCAL      WINAPI LocalReAlloc(HLOCAL,SIZE_T,UINT) ALLOC_SIZE(3);
 WINBASEAPI SIZE_T      WINAPI LocalShrink(HGLOBAL,UINT);
 WINBASEAPI SIZE_T      WINAPI LocalSize(HLOCAL);
 WINBASEAPI BOOL        WINAPI LocalUnlock(HLOCAL);
diff --git a/include/wincrypt.h b/include/wincrypt.h
index ba16cd5..5017aa6 100644
--- a/include/wincrypt.h
+++ b/include/wincrypt.h
@@ -3806,8 +3806,8 @@ WINADVAPI BOOL WINAPI CryptVerifySignatureW (HCRYPTHASH, CONST BYTE *, DWORD, HC
 #define               CryptVerifySignature WINELIB_NAME_AW(CryptVerifySignature)
 
 /* crypt32.dll functions */
-LPVOID WINAPI CryptMemAlloc(ULONG cbSize);
-LPVOID WINAPI CryptMemRealloc(LPVOID pv, ULONG cbSize);
+LPVOID WINAPI CryptMemAlloc(ULONG cbSize) ALLOC_SIZE(1);
+LPVOID WINAPI CryptMemRealloc(LPVOID pv, ULONG cbSize) ALLOC_SIZE(2);
 VOID   WINAPI CryptMemFree(LPVOID pv);
 
 BOOL WINAPI CryptBinaryToStringA(const BYTE *pbBinary,
diff --git a/include/windef.h b/include/windef.h
index fd3d423..0554ce5 100644
--- a/include/windef.h
+++ b/include/windef.h
@@ -49,6 +49,12 @@ extern "C" {
 #define _WIN64
 #endif
 
+#if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ >= 4)
+#define ALLOC_SIZE(x) __attribute__((__alloc_size__(x)))
+#else
+#define ALLOC_SIZE(x)
+#endif
+
 #ifndef __stdcall
 # ifdef __i386__
 #  ifdef __GNUC__
diff --git a/include/winternl.h b/include/winternl.h
index 2dc1fc2..07c93ad 100644
--- a/include/winternl.h
+++ b/include/winternl.h
@@ -2080,7 +2080,7 @@ NTSYSAPI PVOID     WINAPI RtlAddVectoredExceptionHandler(ULONG,PVECTORED_EXCEPTI
 NTSYSAPI NTSTATUS  WINAPI RtlAdjustPrivilege(ULONG,BOOLEAN,BOOLEAN,PBOOLEAN);
 NTSYSAPI NTSTATUS  WINAPI RtlAllocateAndInitializeSid(PSID_IDENTIFIER_AUTHORITY,BYTE,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,PSID *);
 NTSYSAPI RTL_HANDLE * WINAPI RtlAllocateHandle(RTL_HANDLE_TABLE *,ULONG *);
-NTSYSAPI PVOID     WINAPI RtlAllocateHeap(HANDLE,ULONG,SIZE_T);
+NTSYSAPI PVOID     WINAPI RtlAllocateHeap(HANDLE,ULONG,SIZE_T) ALLOC_SIZE(3);
 NTSYSAPI WCHAR     WINAPI RtlAnsiCharToUnicodeChar(LPSTR *);
 NTSYSAPI DWORD     WINAPI RtlAnsiStringToUnicodeSize(const STRING *);
 NTSYSAPI NTSTATUS  WINAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING,PCANSI_STRING,BOOLEAN);
-- 
1.5.2.4



More information about the wine-patches mailing list