Author: tfaber Date: Sun Jun 11 08:33:36 2017 New Revision: 74993
URL: http://svn.reactos.org/svn/reactos?rev=74993&view=rev Log: [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
Modified: trunk/reactos/win32ss/user/ntuser/clipboard.c
Modified: trunk/reactos/win32ss/user/ntuser/clipboard.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/clipboa... ============================================================================== --- trunk/reactos/win32ss/user/ntuser/clipboard.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/ntuser/clipboard.c [iso-8859-1] Sun Jun 11 08:33:36 2017 @@ -36,9 +36,9 @@ 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;
@@ -49,6 +49,12 @@ }
return NULL; +} + +static BOOL FASTCALL +IntIsFormatAvailable(PWINSTATION_OBJECT pWinStaObj, UINT fmt) +{ + return IntGetFormatElement(pWinStaObj, fmt) != NULL; }
static VOID FASTCALL @@ -76,7 +82,7 @@
/* 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 @@
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 @@ static VOID NTAPI IntAddSynthesizedFormats(PWINSTATION_OBJECT pWinStaObj) { - PCLIP pTextEl, pUniTextEl, pOemTextEl, pLocaleEl, pBmEl, pDibEl; - - 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); + BOOL bHaveText, bHaveUniText, bHaveOemText, bHaveLocale, bHaveBm, bHaveDib; + + 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 @@ }
/* 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ { 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 @@ { PCLIP pPaletteEl;
- pPaletteEl = IntIsFormatAvailable(pWinStaObj, CF_PALETTE); + pPaletteEl = IntGetFormatElement(pWinStaObj, CF_PALETTE); if (pPaletteEl && !IS_DATA_DELAYED(pPaletteEl)) pgcd->hPalette = pPaletteEl->hData; }