user32: avoid local heap oveflow by allocating menu structures on the global heap.
Rein Klazes
wijn at online.nl
Fri May 1 01:40:35 CDT 2009
Fixes bug#18297
---
dlls/user32/menu.c | 39 ++++++++++++++++++++++++++-------------
1 files changed, 26 insertions(+), 13 deletions(-)
diff --git a/dlls/user32/menu.c b/dlls/user32/menu.c
index 335fcfa..49799b3 100644
--- a/dlls/user32/menu.c
+++ b/dlls/user32/menu.c
@@ -93,7 +93,6 @@ typedef struct {
/* Popup menu structure */
typedef struct {
WORD wFlags; /* Menu flags (MF_POPUP, MF_SYSMENU) */
- WORD wMagic; /* Magic number */
WORD Width; /* Width of the whole menu */
WORD Height; /* Height of the whole menu */
UINT nItems; /* Number of items in the menu */
@@ -115,6 +114,11 @@ typedef struct {
SIZE maxBmpSize; /* Maximum size of the bitmap items */
} POPUPMENU, *LPPOPUPMENU;
+typedef struct {
+ WORD wMagic; /* Magic number */
+ LPPOPUPMENU lppop;
+} MENUHEAD;
+
/* internal flags for menu tracking */
#define TF_ENDMENU 0x10000
@@ -292,13 +296,13 @@ static void do_debug_print_menuitem(const char *prefix, const MENUITEM *mp,
*/
static POPUPMENU *MENU_GetMenu(HMENU hMenu)
{
- POPUPMENU *menu = USER_HEAP_LIN_ADDR(hMenu);
- if (!menu || menu->wMagic != MENU_MAGIC)
+ MENUHEAD *pmenuhead = USER_HEAP_LIN_ADDR(hMenu);
+ if (!pmenuhead || pmenuhead->wMagic != MENU_MAGIC)
{
- WARN("invalid menu handle=%p, ptr=%p, magic=%x\n", hMenu, menu, menu? menu->wMagic:0);
- menu = NULL;
+ WARN("invalid menu handle=%p, ptr=%p, magic=%x\n", hMenu, pmenuhead, pmenuhead? pmenuhead->wMagic:0);
+ return NULL;
}
- return menu;
+ return pmenuhead->lppop;
}
/***********************************************************************
@@ -4066,11 +4070,12 @@ HMENU WINAPI CreateMenu(void)
{
HMENU hMenu;
LPPOPUPMENU menu;
- if (!(hMenu = USER_HEAP_ALLOC( sizeof(POPUPMENU) ))) return 0;
- menu = USER_HEAP_LIN_ADDR(hMenu);
-
+ MENUHEAD *menuhead;
+ if (!(hMenu = USER_HEAP_ALLOC( sizeof(MENUHEAD) ))) return 0;
+ menuhead = USER_HEAP_LIN_ADDR(hMenu);
+ menu = menuhead->lppop = HeapAlloc( GetProcessHeap(), 0, sizeof(POPUPMENU));
ZeroMemory(menu, sizeof(POPUPMENU));
- menu->wMagic = MENU_MAGIC;
+ menuhead->wMagic = MENU_MAGIC;
menu->FocusedItem = NO_SELECTED_ITEM;
menu->bTimeToHide = FALSE;
@@ -4085,14 +4090,21 @@ HMENU WINAPI CreateMenu(void)
*/
BOOL WINAPI DestroyMenu( HMENU hMenu )
{
- LPPOPUPMENU lppop = MENU_GetMenu(hMenu);
+ LPPOPUPMENU lppop;
+ MENUHEAD *pmenuhead = USER_HEAP_LIN_ADDR(hMenu);
- TRACE("(%p)\n", hMenu);
+ if (!pmenuhead || pmenuhead->wMagic != MENU_MAGIC)
+ {
+ WARN("invalid menu handle=%p, ptr=%p, magic=%x\n", hMenu, pmenuhead, pmenuhead? pmenuhead->wMagic:0);
+ return FALSE;
+ }
+ TRACE("(%p)\n", hMenu);
+ lppop = pmenuhead->lppop;
if (!lppop) return FALSE;
- lppop->wMagic = 0; /* Mark it as destroyed */
+ pmenuhead->wMagic = 0; /* Mark it as destroyed */
/* DestroyMenu should not destroy system menu popup owner */
if ((lppop->wFlags & (MF_POPUP | MF_SYSMENU)) == MF_POPUP && lppop->hWnd)
@@ -4112,6 +4124,7 @@ BOOL WINAPI DestroyMenu( HMENU hMenu )
}
HeapFree( GetProcessHeap(), 0, lppop->items );
}
+ HeapFree( GetProcessHeap(), 0, lppop );
USER_HEAP_FREE( hMenu );
return TRUE;
}
--
1.6.2.1
More information about the wine-patches
mailing list