From: Thomas Faber Date: Sun, 11 Jun 2017 08:33:36 +0000 (+0000) Subject: [WIN32K:NTUSER] X-Git-Tag: ReactOS-0.4.6~351 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=16370e7605a366ffd94ccf61069922f4ab3c4843 [WIN32K:NTUSER] Fix pool use after free during user32:clipboard: - Rename IntIsFormatAvailable to IntGetFormatElement to better reflect what it does - Introduce a new IntIsFormatAvailable that actually returns BOOL as implied by the name - In IntAddSynthesizedFormats, call IntGetFormatElement right before its data is actually used, since IntAddFormatedData will invalidate the element pointer. Thanks to Kamil for the initial investigation on this. CORE-13408 #resolve svn path=/trunk/; revision=74993 --- diff --git a/reactos/win32ss/user/ntuser/clipboard.c b/reactos/win32ss/user/ntuser/clipboard.c index 4de67661d9e..e2a93e13b38 100644 --- a/reactos/win32ss/user/ntuser/clipboard.c +++ b/reactos/win32ss/user/ntuser/clipboard.c @@ -36,9 +36,9 @@ IntGetWinStaForCbAccess(VOID) return pWinStaObj; } -/* If format exists, returns a non zero value (pointing to formated object) */ +/* If format exists, returns a non-null value (pointing to formated object) */ static PCLIP FASTCALL -IntIsFormatAvailable(PWINSTATION_OBJECT pWinStaObj, UINT fmt) +IntGetFormatElement(PWINSTATION_OBJECT pWinStaObj, UINT fmt) { DWORD i; @@ -51,6 +51,12 @@ IntIsFormatAvailable(PWINSTATION_OBJECT pWinStaObj, UINT fmt) return NULL; } +static BOOL FASTCALL +IntIsFormatAvailable(PWINSTATION_OBJECT pWinStaObj, UINT fmt) +{ + return IntGetFormatElement(pWinStaObj, fmt) != NULL; +} + static VOID FASTCALL IntFreeElementData(PCLIP pElement) { @@ -76,7 +82,7 @@ IntAddFormatedData(PWINSTATION_OBJECT pWinStaObj, UINT fmt, HANDLE hData, BOOLEA /* Use existing entry with specified format */ if (!bEnd) - pElement = IntIsFormatAvailable(pWinStaObj, fmt); + pElement = IntGetFormatElement(pWinStaObj, fmt); /* Put new entry at the end if nothing was found */ if (!pElement) @@ -226,7 +232,7 @@ IntSynthesizeBitmap(PWINSTATION_OBJECT pWinStaObj, PCLIP pBmEl) TRACE("IntSynthesizeBitmap(%p, %p)\n", pWinStaObj, pBmEl); - pDibEl = IntIsFormatAvailable(pWinStaObj, CF_DIB); + pDibEl = IntGetFormatElement(pWinStaObj, CF_DIB); ASSERT(pDibEl && !IS_DATA_SYNTHESIZED(pDibEl)); if (!pDibEl->fGlobalHandle) return; @@ -278,17 +284,17 @@ cleanup: static VOID NTAPI IntAddSynthesizedFormats(PWINSTATION_OBJECT pWinStaObj) { - PCLIP pTextEl, pUniTextEl, pOemTextEl, pLocaleEl, pBmEl, pDibEl; + BOOL bHaveText, bHaveUniText, bHaveOemText, bHaveLocale, bHaveBm, bHaveDib; - pTextEl = IntIsFormatAvailable(pWinStaObj, CF_TEXT); - pOemTextEl = IntIsFormatAvailable(pWinStaObj, CF_OEMTEXT); - pUniTextEl = IntIsFormatAvailable(pWinStaObj, CF_UNICODETEXT); - pLocaleEl = IntIsFormatAvailable(pWinStaObj, CF_LOCALE); - pBmEl = IntIsFormatAvailable(pWinStaObj, CF_BITMAP); - pDibEl = IntIsFormatAvailable(pWinStaObj, CF_DIB); + bHaveText = IntIsFormatAvailable(pWinStaObj, CF_TEXT); + bHaveOemText = IntIsFormatAvailable(pWinStaObj, CF_OEMTEXT); + bHaveUniText = IntIsFormatAvailable(pWinStaObj, CF_UNICODETEXT); + bHaveLocale = IntIsFormatAvailable(pWinStaObj, CF_LOCALE); + bHaveBm = IntIsFormatAvailable(pWinStaObj, CF_BITMAP); + bHaveDib = IntIsFormatAvailable(pWinStaObj, CF_DIB); /* Add CF_LOCALE format if we have CF_TEXT */ - if (!pLocaleEl && pTextEl) + if (!bHaveLocale && bHaveText) { PCLIPBOARDDATA pMemObj; HANDLE hMem; @@ -307,25 +313,25 @@ IntAddSynthesizedFormats(PWINSTATION_OBJECT pWinStaObj) } /* Add CF_TEXT. Note: it is synthesized in user32.dll */ - if (!pTextEl && (pUniTextEl || pOemTextEl)) + if (!bHaveText && (bHaveUniText || bHaveOemText)) IntAddFormatedData(pWinStaObj, CF_TEXT, DATA_SYNTH_USER, FALSE, TRUE); /* Add CF_OEMTEXT. Note: it is synthesized in user32.dll */ - if (!pOemTextEl && (pUniTextEl || pTextEl)) + if (!bHaveOemText && (bHaveUniText || bHaveText)) IntAddFormatedData(pWinStaObj, CF_OEMTEXT, DATA_SYNTH_USER, FALSE, TRUE); /* Add CF_UNICODETEXT. Note: it is synthesized in user32.dll */ - if (!pUniTextEl && (pTextEl || pOemTextEl)) + if (!bHaveUniText && (bHaveText || bHaveOemText)) IntAddFormatedData(pWinStaObj, CF_UNICODETEXT, DATA_SYNTH_USER, FALSE, TRUE); /* Add CF_BITMAP. Note: it is synthesized on demand */ - if (!pBmEl && pDibEl) + if (!bHaveBm && bHaveDib) IntAddFormatedData(pWinStaObj, CF_BITMAP, DATA_SYNTH_KRNL, FALSE, TRUE); /* Note: We need to render the DIB or DIBV5 format as soon as possible because pallette information may change */ - if (!pDibEl && pBmEl) - IntSynthesizeDib(pWinStaObj, pBmEl->hData); + if (!bHaveDib && bHaveBm) + IntSynthesizeDib(pWinStaObj, IntGetFormatElement(pWinStaObj, CF_BITMAP)->hData); } VOID NTAPI @@ -441,7 +447,7 @@ UserEnumClipboardFormats(UINT fmt) else { /* Return next format */ - pElement = IntIsFormatAvailable(pWinStaObj, fmt); + pElement = IntGetFormatElement(pWinStaObj, fmt); ++pElement; if (pElement < &pWinStaObj->pClipBase[pWinStaObj->cNumClipFormats]) Ret = pElement->fmt; @@ -885,7 +891,7 @@ NtUserGetClipboardData(UINT fmt, PGETCLIPBDATA pgcd) goto cleanup; } - pElement = IntIsFormatAvailable(pWinStaObj, fmt); + pElement = IntGetFormatElement(pWinStaObj, fmt); if (pElement && IS_DATA_DELAYED(pElement) && pWinStaObj->spwndClipOwner) { /* Send WM_RENDERFORMAT message */ @@ -894,7 +900,7 @@ NtUserGetClipboardData(UINT fmt, PGETCLIPBDATA pgcd) pWinStaObj->fInDelayedRendering = FALSE; /* Data should be in clipboard now */ - pElement = IntIsFormatAvailable(pWinStaObj, fmt); + pElement = IntGetFormatElement(pWinStaObj, fmt); } if (!pElement || IS_DATA_DELAYED(pElement)) @@ -909,11 +915,11 @@ NtUserGetClipboardData(UINT fmt, PGETCLIPBDATA pgcd) case CF_UNICODETEXT: case CF_TEXT: case CF_OEMTEXT: - pElement = IntIsFormatAvailable(pWinStaObj, CF_UNICODETEXT); + pElement = IntGetFormatElement(pWinStaObj, CF_UNICODETEXT); if (IS_DATA_SYNTHESIZED(pElement)) - pElement = IntIsFormatAvailable(pWinStaObj, CF_TEXT); + pElement = IntGetFormatElement(pWinStaObj, CF_TEXT); if (IS_DATA_SYNTHESIZED(pElement)) - pElement = IntIsFormatAvailable(pWinStaObj, CF_OEMTEXT); + pElement = IntGetFormatElement(pWinStaObj, CF_OEMTEXT); break; case CF_BITMAP: IntSynthesizeBitmap(pWinStaObj, pElement); @@ -934,7 +940,7 @@ NtUserGetClipboardData(UINT fmt, PGETCLIPBDATA pgcd) { PCLIP pLocaleEl; - pLocaleEl = IntIsFormatAvailable(pWinStaObj, CF_LOCALE); + pLocaleEl = IntGetFormatElement(pWinStaObj, CF_LOCALE); if (pLocaleEl && !IS_DATA_DELAYED(pLocaleEl)) pgcd->hLocale = pLocaleEl->hData; } @@ -942,7 +948,7 @@ NtUserGetClipboardData(UINT fmt, PGETCLIPBDATA pgcd) { PCLIP pPaletteEl; - pPaletteEl = IntIsFormatAvailable(pWinStaObj, CF_PALETTE); + pPaletteEl = IntGetFormatElement(pWinStaObj, CF_PALETTE); if (pPaletteEl && !IS_DATA_DELAYED(pPaletteEl)) pgcd->hPalette = pPaletteEl->hData; }