From 896b53ffa72d91d7d604967028291525562b60dd Mon Sep 17 00:00:00 2001 From: Jon TURNEY Date: Sun, 16 Jun 2013 13:55:51 +0100 Subject: [PATCH] hw/xwin: Improve NET_WM_ICON validation Check that we don't overrun the end of the property data while converting icons See http://cygwin.com/ml/cygwin-xfree/2013-06/msg00040.html for testcase. Also, some warning fixes in winXIconToHICON() Signed-off-by: Jon TURNEY Reviewed-by: Colin Harrison --- hw/xwin/winmultiwindowicons.c | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/hw/xwin/winmultiwindowicons.c b/hw/xwin/winmultiwindowicons.c index 0531ad6c7..93d389d46 100644 --- a/hw/xwin/winmultiwindowicons.c +++ b/hw/xwin/winmultiwindowicons.c @@ -372,13 +372,12 @@ winXIconToHICON(Display * pDisplay, Window id, int iconSize) unsigned char *mask, *image = NULL, *imageMask; unsigned char *dst, *src; int planes, bpp, i; - int biggest_size = 0; + unsigned int biggest_size = 0; HDC hDC; ICONINFO ii; XWMHints *hints; HICON hIcon = NULL; uint32_t *biggest_icon = NULL; - static Atom _XA_NET_WM_ICON; static int generation; uint32_t *icon, *icon_data = NULL; @@ -405,10 +404,25 @@ winXIconToHICON(Display * pDisplay, Window id, int iconSize) (icon_data != NULL)) { for (icon = icon_data; icon < &icon_data[size] && *icon; icon = &icon[icon[0] * icon[1] + 2]) { - /* Find an exact match to the size we require... */ + winDebug("winXIconToHICON: %u x %u NetIcon\n", icon[0], icon[1]); + + /* Icon data size will overflow an int and thus is bigger than the + property can possibly be */ + if ((INT_MAX/icon[0]) < icon[1]) { + winDebug("winXIconToHICON: _NET_WM_ICON icon data size overflow\n"); + break; + } + + /* Icon data size is bigger than amount of data remaining */ + if (&icon[icon[0] * icon[1] + 2] > &icon_data[size]) { + winDebug("winXIconToHICON: _NET_WM_ICON data is malformed\n"); + break; + } + + /* Found an exact match to the size we require... */ if (icon[0] == iconSize && icon[1] == iconSize) { - winDebug("winXIconToHICON: found %lu x %lu NetIcon\n", icon[0], - icon[1]); + winDebug("winXIconToHICON: selected %d x %d NetIcon\n", + iconSize, iconSize); hIcon = NetWMToWinIcon(bpp, icon); break; } @@ -421,7 +435,7 @@ winXIconToHICON(Display * pDisplay, Window id, int iconSize) if (!hIcon && biggest_icon) { winDebug - ("winXIconToHICON: selected %lu x %lu NetIcon for scaling to %u x %u\n", + ("winXIconToHICON: selected %u x %u NetIcon for scaling to %d x %d\n", biggest_icon[0], biggest_icon[1], iconSize, iconSize); hIcon = NetWMToWinIcon(bpp, biggest_icon);