Author: jimtabor Date: Tue Jul 29 13:11:18 2008 New Revision: 34934
URL: http://svn.reactos.org/svn/reactos?rev=34934&view=rev Log: - Patch by Jeffrey Morlan: Fix bounds checking and change NtGdiDoPalette to use a temporary kmode buffer. See Bug 3383.
Modified: trunk/reactos/subsystems/win32/win32k/objects/color.c
Modified: trunk/reactos/subsystems/win32/win32k/objects/color.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/obj... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/objects/color.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/objects/color.c [iso-8859-1] Tue Jul 29 13:11:18 2008 @@ -436,18 +436,16 @@ { if (pe != NULL) { - UINT CopyEntries; - - if (StartIndex + Entries < palGDI->NumColors) - CopyEntries = StartIndex + Entries; - else - CopyEntries = palGDI->NumColors - StartIndex; + if (StartIndex >= palGDI->NumColors) + Entries = 0; + else if (Entries > palGDI->NumColors - StartIndex) + Entries = palGDI->NumColors - StartIndex;
memcpy(pe, palGDI->IndexedColors + StartIndex, - CopyEntries * sizeof(pe[0])); - - Ret = CopyEntries; + Entries * sizeof(pe[0])); + + Ret = Entries; } else { @@ -837,6 +835,7 @@ IN BOOL bInbound) { LONG ret; + LPVOID pEntries = NULL;
/* FIXME: Handle bInbound correctly */
@@ -846,58 +845,76 @@ return 0; }
- _SEH_TRY + if (pUnsafeEntries) { - switch(iFunc) + pEntries = ExAllocatePool(PagedPool, cEntries * sizeof(PALETTEENTRY)); + if (!pEntries) + return 0; + if (bInbound) { - case GdiPalAnimate: + _SEH_TRY + { ProbeForRead(pUnsafeEntries, cEntries * sizeof(PALETTEENTRY), 1); - ret = IntAnimatePalette((HPALETTE)hObj, iStart, cEntries, pUnsafeEntries); - break; - - case GdiPalSetEntries: - ProbeForRead(pUnsafeEntries, cEntries * sizeof(PALETTEENTRY), 1); - ret = IntSetPaletteEntries((HPALETTE)hObj, iStart, cEntries, pUnsafeEntries); - break; - - case GdiPalGetEntries: - if (pUnsafeEntries) - { - ProbeForWrite(pUnsafeEntries, cEntries * sizeof(PALETTEENTRY), 1); - } - ret = IntGetPaletteEntries((HPALETTE)hObj, iStart, cEntries, pUnsafeEntries); - break; - - case GdiPalGetSystemEntries: - if (pUnsafeEntries) - { - ProbeForWrite(pUnsafeEntries, cEntries * sizeof(PALETTEENTRY), 1); - } - ret = IntGetSystemPaletteEntries((HDC)hObj, iStart, cEntries, pUnsafeEntries); - break; - - case GdiPalSetColorTable: - ProbeForRead(pUnsafeEntries, cEntries * sizeof(PALETTEENTRY), 1); - ret = IntSetDIBColorTable((HDC)hObj, iStart, cEntries, (RGBQUAD*)pUnsafeEntries); - break; - - case GdiPalGetColorTable: - if (pUnsafeEntries) - { - ProbeForWrite(pUnsafeEntries, cEntries * sizeof(PALETTEENTRY), 1); - } - ret = IntGetDIBColorTable((HDC)hObj, iStart, cEntries, (RGBQUAD*)pUnsafeEntries); - break; - - default: - ret = 0; + memcpy(pEntries, pUnsafeEntries, cEntries * sizeof(PALETTEENTRY)); + } + _SEH_HANDLE + { + ExFreePool(pEntries); + _SEH_YIELD(return 0); + } + _SEH_END } } - _SEH_HANDLE + + ret = 0; + switch(iFunc) { - ret = 0; + case GdiPalAnimate: + if (pEntries) + ret = IntAnimatePalette((HPALETTE)hObj, iStart, cEntries, pEntries); + break; + + case GdiPalSetEntries: + if (pEntries) + ret = IntSetPaletteEntries((HPALETTE)hObj, iStart, cEntries, pEntries); + break; + + case GdiPalGetEntries: + ret = IntGetPaletteEntries((HPALETTE)hObj, iStart, cEntries, pEntries); + break; + + case GdiPalGetSystemEntries: + ret = IntGetSystemPaletteEntries((HDC)hObj, iStart, cEntries, pEntries); + break; + + case GdiPalSetColorTable: + if (pEntries) + ret = IntSetDIBColorTable((HDC)hObj, iStart, cEntries, (RGBQUAD*)pEntries); + break; + + case GdiPalGetColorTable: + if (pEntries) + ret = IntGetDIBColorTable((HDC)hObj, iStart, cEntries, (RGBQUAD*)pEntries); + break; } - _SEH_END + + if (pEntries) + { + if (!bInbound) + { + _SEH_TRY + { + ProbeForWrite(pUnsafeEntries, cEntries * sizeof(PALETTEENTRY), 1); + memcpy(pUnsafeEntries, pEntries, cEntries * sizeof(PALETTEENTRY)); + } + _SEH_HANDLE + { + ret = 0; + } + _SEH_END + } + ExFreePool(pEntries); + }
return ret; }